aboutsummaryrefslogtreecommitdiff
path: root/unittests/Tooling/ToolingTest.cpp
diff options
context:
space:
mode:
authorManuel Klimek <klimek@google.com>2011-04-21 18:37:41 +0000
committerManuel Klimek <klimek@google.com>2011-04-21 18:37:41 +0000
commitcf3ce5d89628b3955c638fb102c8dc4c24e1986d (patch)
tree23b117ad61ea2246d4550d24f954d12dc2e90d49 /unittests/Tooling/ToolingTest.cpp
parent0e02f6ef48a098cc27a250e644415038c2fa52a5 (diff)
Adds a function to run FrontendActions over in-memory code. This is
the first step towards a standalone Clang tool infrastructure. The plan is to make it easy to build command line tools that run over the AST of source files in a project outside of the build system. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129924 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'unittests/Tooling/ToolingTest.cpp')
-rw-r--r--unittests/Tooling/ToolingTest.cpp91
1 files changed, 91 insertions, 0 deletions
diff --git a/unittests/Tooling/ToolingTest.cpp b/unittests/Tooling/ToolingTest.cpp
new file mode 100644
index 0000000000..da89c0ba10
--- /dev/null
+++ b/unittests/Tooling/ToolingTest.cpp
@@ -0,0 +1,91 @@
+//===- 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/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, llvm::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 void HandleTopLevelDecl(clang::DeclGroupRef DeclGroup) {
+ *FoundTopLevelDecl = true;
+ }
+ private:
+ bool * const FoundTopLevelDecl;
+};
+} // end namespace
+
+TEST(RunSyntaxOnlyToolOnCode, FindsTopLevelDeclOnEmptyCode) {
+ bool FoundTopLevelDecl = false;
+ EXPECT_TRUE(RunSyntaxOnlyToolOnCode(
+ new TestAction(new FindTopLevelDeclConsumer(&FoundTopLevelDecl)), ""));
+ EXPECT_TRUE(FoundTopLevelDecl);
+}
+
+namespace {
+class FindClassDeclXConsumer : public clang::ASTConsumer {
+ public:
+ FindClassDeclXConsumer(bool *FoundClassDeclX)
+ : FoundClassDeclX(FoundClassDeclX) {}
+ virtual void HandleTopLevelDecl(clang::DeclGroupRef GroupRef) {
+ if (CXXRecordDecl* Record = llvm::dyn_cast<clang::CXXRecordDecl>(
+ *GroupRef.begin())) {
+ if (Record->getName() == "X") {
+ *FoundClassDeclX = true;
+ }
+ }
+ }
+ private:
+ bool *FoundClassDeclX;
+};
+} // end namespace
+
+TEST(RunSyntaxOnlyToolOnCode, FindsClassDecl) {
+ bool FoundClassDeclX = false;
+ EXPECT_TRUE(RunSyntaxOnlyToolOnCode(new TestAction(
+ new FindClassDeclXConsumer(&FoundClassDeclX)), "class X;"));
+ EXPECT_TRUE(FoundClassDeclX);
+
+ FoundClassDeclX = false;
+ EXPECT_TRUE(RunSyntaxOnlyToolOnCode(new TestAction(
+ new FindClassDeclXConsumer(&FoundClassDeclX)), "class Y;"));
+ EXPECT_FALSE(FoundClassDeclX);
+}
+
+} // end namespace tooling
+} // end namespace clang
+