diff --git a/test/Tooling/clang-diff-args.test b/test/Tooling/clang-diff-args.test
new file mode 100644
index 0000000000000000000000000000000000000000..a051c3ba79b8bbfef21b96dc34b6fa5cbaf01d2f
--- /dev/null
+++ b/test/Tooling/clang-diff-args.test
@@ -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
diff --git a/test/Tooling/clang-diff-basic.cpp b/test/Tooling/clang-diff-basic.cpp
index e23abbd4cee23775885ed024f3f2dad0fe76d22a..ac676991e99506c3a506da0b03e6d002b55232a8 100644
--- a/test/Tooling/clang-diff-basic.cpp
+++ b/test/Tooling/clang-diff-basic.cpp
@@ -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 {
diff --git a/tools/clang-diff/ClangDiff.cpp b/tools/clang-diff/ClangDiff.cpp
index 86284cda43707a39d4f91b70754ea1235d623e55..ea7218368852e993cc3dcc2bfa6645321e2fca8e 100644
--- a/tools/clang-diff/ClangDiff.cpp
+++ b/tools/clang-diff/ClangDiff.cpp
@@ -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);