summaryrefslogtreecommitdiffstats
path: root/clang/unittests/Tooling
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2013-11-06 20:12:45 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2013-11-06 20:12:45 +0000
commitc689ee76d467fade531cbb731f0f35996a121883 (patch)
treee74ad5837f3e01af7b7fbeb758a36780798b22ff /clang/unittests/Tooling
parent2a0e663fbda17d2858467f9687f568217ed73897 (diff)
downloadbcm5719-llvm-c689ee76d467fade531cbb731f0f35996a121883.tar.gz
bcm5719-llvm-c689ee76d467fade531cbb731f0f35996a121883.zip
Introduce ClangTool::buildASTs, and buildASTFromCode.
These allow clients to retrieve persistent AST objects (ASTUnits) which can be used in an ad-hoc manner after parsing. To accommodate this change, the code for processing a CompilerInvocation using a FrontendAction has been factored out to FrontendActionFactory, and a new base class, ToolAction, has been introduced, allowing the tool to do arbitrary things with each CompilerInvocation. This change was necessary because ASTUnit does not use the FrontendAction interface directly. This change also causes the FileManager in ClangTool to use shared ownership. This will become necessary because ASTUnit takes shared ownership of FileManager (ClangTool's FileManager is currently unused by ASTUnit; this is a FIXME). As shown in the tests, any client of ToolInvocation will need to be modified to use shared ownership for FileManager. Differential Revision: http://llvm-reviews.chandlerc.com/D2097 llvm-svn: 194164
Diffstat (limited to 'clang/unittests/Tooling')
-rw-r--r--clang/unittests/Tooling/ToolingTest.cpp54
1 files changed, 50 insertions, 4 deletions
diff --git a/clang/unittests/Tooling/ToolingTest.cpp b/clang/unittests/Tooling/ToolingTest.cpp
index 412af7adda9..096f6884554 100644
--- a/clang/unittests/Tooling/ToolingTest.cpp
+++ b/clang/unittests/Tooling/ToolingTest.cpp
@@ -10,12 +10,14 @@
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/DeclCXX.h"
#include "clang/AST/DeclGroup.h"
+#include "clang/Frontend/ASTUnit.h"
#include "clang/Frontend/CompilerInstance.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"
+#include "llvm/ADT/STLExtras.h"
#include <string>
namespace clang {
@@ -83,6 +85,18 @@ class FindClassDeclXConsumer : public clang::ASTConsumer {
private:
bool *FoundClassDeclX;
};
+bool FindClassDeclX(ASTUnit *AST) {
+ for (std::vector<Decl *>::iterator i = AST->top_level_begin(),
+ e = AST->top_level_end();
+ i != e; ++i) {
+ if (CXXRecordDecl* Record = dyn_cast<clang::CXXRecordDecl>(*i)) {
+ if (Record->getName() == "X") {
+ return true;
+ }
+ }
+ }
+ return false;
+}
} // end namespace
TEST(runToolOnCode, FindsClassDecl) {
@@ -97,6 +111,16 @@ TEST(runToolOnCode, FindsClassDecl) {
EXPECT_FALSE(FoundClassDeclX);
}
+TEST(buildASTFromCode, FindsClassDecl) {
+ OwningPtr<ASTUnit> AST(buildASTFromCode("class X;"));
+ ASSERT_TRUE(AST.get());
+ EXPECT_TRUE(FindClassDeclX(AST.get()));
+
+ AST.reset(buildASTFromCode("class Y;"));
+ ASSERT_TRUE(AST.get());
+ EXPECT_FALSE(FindClassDeclX(AST.get()));
+}
+
TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromType) {
OwningPtr<FrontendActionFactory> Factory(
newFrontendActionFactory<SyntaxOnlyAction>());
@@ -119,13 +143,15 @@ TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromFactoryType) {
}
TEST(ToolInvocation, TestMapVirtualFile) {
- clang::FileManager Files((clang::FileSystemOptions()));
+ IntrusiveRefCntPtr<clang::FileManager> Files(
+ new clang::FileManager(clang::FileSystemOptions()));
std::vector<std::string> Args;
Args.push_back("tool-executable");
Args.push_back("-Idef");
Args.push_back("-fsyntax-only");
Args.push_back("test.cpp");
- clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction, &Files);
+ clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,
+ Files.getPtr());
Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");
Invocation.mapVirtualFile("def/abc", "\n");
EXPECT_TRUE(Invocation.run());
@@ -136,13 +162,15 @@ TEST(ToolInvocation, TestVirtualModulesCompilation) {
// mapped module.map is found on the include path. In the future, expand this
// test to run a full modules enabled compilation, so we make sure we can
// rerun modules compilations with a virtual file system.
- clang::FileManager Files((clang::FileSystemOptions()));
+ IntrusiveRefCntPtr<clang::FileManager> Files(
+ new clang::FileManager(clang::FileSystemOptions()));
std::vector<std::string> Args;
Args.push_back("tool-executable");
Args.push_back("-Idef");
Args.push_back("-fsyntax-only");
Args.push_back("test.cpp");
- clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction, &Files);
+ clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction,
+ Files.getPtr());
Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");
Invocation.mapVirtualFile("def/abc", "\n");
// Add a module.map file in the include directory of our header, so we trigger
@@ -254,5 +282,23 @@ TEST(ClangToolTest, ArgumentAdjusters) {
EXPECT_FALSE(Found);
}
+TEST(ClangToolTest, BuildASTs) {
+ FixedCompilationDatabase Compilations("/", std::vector<std::string>());
+
+ std::vector<std::string> Sources;
+ Sources.push_back("/a.cc");
+ Sources.push_back("/b.cc");
+ ClangTool Tool(Compilations, Sources);
+
+ Tool.mapVirtualFile("/a.cc", "void a() {}");
+ Tool.mapVirtualFile("/b.cc", "void b() {}");
+
+ std::vector<ASTUnit *> ASTs;
+ EXPECT_EQ(0, Tool.buildASTs(ASTs));
+ EXPECT_EQ(2u, ASTs.size());
+
+ llvm::DeleteContainerPointers(ASTs);
+}
+
} // end namespace tooling
} // end namespace clang
OpenPOWER on IntegriCloud