Adds a tooling library.

Provides an API to run clang tools (FrontendActions) as standalone tools,
or repeatedly in-memory in a process. This is useful for unit-testing,
map-reduce style applications, source transformation daemons or command line
tools.

The ability to run over multiple translation units with different command
line arguments enables building up refactoring tools that need to apply
transformations across translation unit boundaries.

See tools/clang-check/ClangCheck.cpp for an example.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@154008 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/unittests/Tooling/ToolingTest.cpp b/unittests/Tooling/ToolingTest.cpp
new file mode 100644
index 0000000..c7b2210
--- /dev/null
+++ b/unittests/Tooling/ToolingTest.cpp
@@ -0,0 +1,113 @@
+//===- unittest/Tooling/ToolingTest.cpp - Tooling unit tests --------------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTConsumer.h"
+#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclGroup.h"
+#include "clang/Frontend/FrontendAction.h"
+#include "clang/Frontend/FrontendActions.h"
+#include "clang/Tooling/CompilationDatabase.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace tooling {
+
+namespace {
+/// Takes an ast consumer and returns it from CreateASTConsumer. This only
+/// works with single translation unit compilations.
+class TestAction : public clang::ASTFrontendAction {
+ public:
+  /// Takes ownership of TestConsumer.
+  explicit TestAction(clang::ASTConsumer *TestConsumer)
+      : TestConsumer(TestConsumer) {}
+
+ protected:
+  virtual clang::ASTConsumer* CreateASTConsumer(
+      clang::CompilerInstance& compiler, StringRef dummy) {
+    /// TestConsumer will be deleted by the framework calling us.
+    return TestConsumer;
+  }
+
+ private:
+  clang::ASTConsumer * const TestConsumer;
+};
+
+class FindTopLevelDeclConsumer : public clang::ASTConsumer {
+ public:
+  explicit FindTopLevelDeclConsumer(bool *FoundTopLevelDecl)
+      : FoundTopLevelDecl(FoundTopLevelDecl) {}
+  virtual bool HandleTopLevelDecl(clang::DeclGroupRef DeclGroup) {
+    *FoundTopLevelDecl = true;
+    return true;
+  }
+ private:
+  bool * const FoundTopLevelDecl;
+};
+} // end namespace
+
+TEST(runToolOnCode, FindsTopLevelDeclOnEmptyCode) {
+  bool FoundTopLevelDecl = false;
+  EXPECT_TRUE(runToolOnCode(
+      new TestAction(new FindTopLevelDeclConsumer(&FoundTopLevelDecl)), ""));
+  EXPECT_TRUE(FoundTopLevelDecl);
+}
+
+namespace {
+class FindClassDeclXConsumer : public clang::ASTConsumer {
+ public:
+  FindClassDeclXConsumer(bool *FoundClassDeclX)
+      : FoundClassDeclX(FoundClassDeclX) {}
+  virtual bool HandleTopLevelDecl(clang::DeclGroupRef GroupRef) {
+    if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>(
+            *GroupRef.begin())) {
+      if (Record->getName() == "X") {
+        *FoundClassDeclX = true;
+      }
+    }
+    return true;
+  }
+ private:
+  bool *FoundClassDeclX;
+};
+} // end namespace
+
+TEST(runToolOnCode, FindsClassDecl) {
+  bool FoundClassDeclX = false;
+  EXPECT_TRUE(runToolOnCode(new TestAction(
+      new FindClassDeclXConsumer(&FoundClassDeclX)), "class X;"));
+  EXPECT_TRUE(FoundClassDeclX);
+
+  FoundClassDeclX = false;
+  EXPECT_TRUE(runToolOnCode(new TestAction(
+      new FindClassDeclXConsumer(&FoundClassDeclX)), "class Y;"));
+  EXPECT_FALSE(FoundClassDeclX);
+}
+
+TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromType) {
+  llvm::OwningPtr<FrontendActionFactory> Factory(
+    newFrontendActionFactory<SyntaxOnlyAction>());
+  llvm::OwningPtr<FrontendAction> Action(Factory->create());
+  EXPECT_TRUE(Action.get() != NULL);
+}
+
+struct IndependentFrontendActionCreator {
+  FrontendAction *newFrontendAction() { return new SyntaxOnlyAction; }
+};
+
+TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromFactoryType) {
+  IndependentFrontendActionCreator Creator;
+  llvm::OwningPtr<FrontendActionFactory> Factory(
+    newFrontendActionFactory(&Creator));
+  llvm::OwningPtr<FrontendAction> Action(Factory->create());
+  EXPECT_TRUE(Action.get() != NULL);
+}
+
+} // end namespace tooling
+} // end namespace clang