1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
//===- 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"
#include <string>
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, FindsNoTopLevelDeclOnEmptyCode) {
bool FoundTopLevelDecl = false;
EXPECT_TRUE(runToolOnCode(
new TestAction(new FindTopLevelDeclConsumer(&FoundTopLevelDecl)), ""));
#if !defined(_MSC_VER)
EXPECT_FALSE(FoundTopLevelDecl);
#else
// FIXME: LangOpts.MicrosoftExt appends "class type_info;"
EXPECT_TRUE(FoundTopLevelDecl);
#endif
}
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 {
ASTConsumer *newASTConsumer() {
return new FindTopLevelDeclConsumer(NULL);
}
};
TEST(newFrontendActionFactory, CreatesFrontendActionFactoryFromFactoryType) {
IndependentFrontendActionCreator Creator;
llvm::OwningPtr<FrontendActionFactory> Factory(
newFrontendActionFactory(&Creator));
llvm::OwningPtr<FrontendAction> Action(Factory->create());
EXPECT_TRUE(Action.get() != NULL);
}
TEST(ToolInvocation, TestMapVirtualFile) {
clang::FileManager Files((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);
Invocation.mapVirtualFile("test.cpp", "#include <abc>\n");
Invocation.mapVirtualFile("def/abc", "\n");
EXPECT_TRUE(Invocation.run());
}
} // end namespace tooling
} // end namespace clang
|