aboutsummaryrefslogtreecommitdiff
path: root/unittests/Tooling
diff options
context:
space:
mode:
Diffstat (limited to 'unittests/Tooling')
-rw-r--r--unittests/Tooling/CMakeLists.txt1
-rw-r--r--unittests/Tooling/CastExprTest.cpp38
-rw-r--r--unittests/Tooling/CompilationDatabaseTest.cpp21
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTest.cpp86
-rw-r--r--unittests/Tooling/RefactoringTest.cpp12
-rw-r--r--unittests/Tooling/TestVisitor.h5
6 files changed, 158 insertions, 5 deletions
diff --git a/unittests/Tooling/CMakeLists.txt b/unittests/Tooling/CMakeLists.txt
index b5af99bdfd6d..8ed35480cb88 100644
--- a/unittests/Tooling/CMakeLists.txt
+++ b/unittests/Tooling/CMakeLists.txt
@@ -11,6 +11,7 @@ if (MSVC)
endif()
add_clang_unittest(ToolingTests
+ CastExprTest.cpp
CommentHandlerTest.cpp
CompilationDatabaseTest.cpp
FixItTest.cpp
diff --git a/unittests/Tooling/CastExprTest.cpp b/unittests/Tooling/CastExprTest.cpp
new file mode 100644
index 000000000000..5310c2125472
--- /dev/null
+++ b/unittests/Tooling/CastExprTest.cpp
@@ -0,0 +1,38 @@
+//===- unittest/Tooling/CastExprTest.cpp ----------------------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "TestVisitor.h"
+
+using namespace clang;
+
+namespace {
+
+struct CastExprVisitor : TestVisitor<CastExprVisitor> {
+ std::function<void(ExplicitCastExpr *)> OnExplicitCast;
+
+ bool VisitExplicitCastExpr(ExplicitCastExpr *Expr) {
+ if (OnExplicitCast)
+ OnExplicitCast(Expr);
+ return true;
+ }
+};
+
+TEST(CastExprTest, GetSubExprAsWrittenThroughMaterializedTemporary) {
+ CastExprVisitor Visitor;
+ Visitor.OnExplicitCast = [](ExplicitCastExpr *Expr) {
+ auto Sub = Expr->getSubExprAsWritten();
+ EXPECT_TRUE(isa<DeclRefExpr>(Sub))
+ << "Expected DeclRefExpr, but saw " << Sub->getStmtClassName();
+ };
+ Visitor.runOver("struct S1 {};\n"
+ "struct S2 { operator S1(); };\n"
+ "S1 f(S2 s) { return static_cast<S1>(s); }\n");
+}
+
+}
diff --git a/unittests/Tooling/CompilationDatabaseTest.cpp b/unittests/Tooling/CompilationDatabaseTest.cpp
index 5a6693eb4dbb..fd8afe6b7976 100644
--- a/unittests/Tooling/CompilationDatabaseTest.cpp
+++ b/unittests/Tooling/CompilationDatabaseTest.cpp
@@ -586,6 +586,27 @@ TEST(ParseFixedCompilationDatabase, HandlesPositionalArgs) {
EXPECT_EQ(2, Argc);
}
+TEST(ParseFixedCompilationDatabase, HandlesPositionalArgsSyntaxOnly) {
+ // Adjust the given command line arguments to ensure that any positional
+ // arguments in them are stripped.
+ const char *Argv[] = {"--", "somefile.cpp", "-fsyntax-only", "-DDEF3"};
+ int Argc = llvm::array_lengthof(Argv);
+ std::string ErrorMessage;
+ std::unique_ptr<CompilationDatabase> Database =
+ FixedCompilationDatabase::loadFromCommandLine(Argc, Argv, ErrorMessage);
+ ASSERT_TRUE((bool)Database);
+ ASSERT_TRUE(ErrorMessage.empty());
+ std::vector<CompileCommand> Result = Database->getCompileCommands("source");
+ ASSERT_EQ(1ul, Result.size());
+ ASSERT_EQ(".", Result[0].Directory);
+ std::vector<std::string> Expected;
+ Expected.push_back("clang-tool");
+ Expected.push_back("-fsyntax-only");
+ Expected.push_back("-DDEF3");
+ Expected.push_back("source");
+ ASSERT_EQ(Expected, Result[0].CommandLine);
+}
+
TEST(ParseFixedCompilationDatabase, HandlesArgv0) {
const char *Argv[] = {"1", "2", "--", "mytool", "somefile.cpp"};
int Argc = sizeof(Argv) / sizeof(char*);
diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp
index 269bdbb34ab1..74c9c3db34d8 100644
--- a/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -158,4 +158,90 @@ TEST(RecursiveASTVisitor, DefaultArgumentsAreVisited) {
"static int k = f();\n"));
}
+// Check to ensure that InitListExpr is visited twice, once each for the
+// syntactic and semantic form.
+class InitListExprPreOrderVisitor
+ : public ExpectedLocationVisitor<InitListExprPreOrderVisitor> {
+public:
+ bool VisitInitListExpr(InitListExpr *ILE) {
+ Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart());
+ return true;
+ }
+};
+
+class InitListExprPostOrderVisitor
+ : public ExpectedLocationVisitor<InitListExprPostOrderVisitor> {
+public:
+ bool shouldTraversePostOrder() const { return true; }
+
+ bool VisitInitListExpr(InitListExpr *ILE) {
+ Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart());
+ return true;
+ }
+};
+
+class InitListExprPreOrderNoQueueVisitor
+ : public ExpectedLocationVisitor<InitListExprPreOrderNoQueueVisitor> {
+public:
+ bool TraverseInitListExpr(InitListExpr *ILE) {
+ return ExpectedLocationVisitor::TraverseInitListExpr(ILE);
+ }
+
+ bool VisitInitListExpr(InitListExpr *ILE) {
+ Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart());
+ return true;
+ }
+};
+
+class InitListExprPostOrderNoQueueVisitor
+ : public ExpectedLocationVisitor<InitListExprPostOrderNoQueueVisitor> {
+public:
+ bool shouldTraversePostOrder() const { return true; }
+
+ bool TraverseInitListExpr(InitListExpr *ILE) {
+ return ExpectedLocationVisitor::TraverseInitListExpr(ILE);
+ }
+
+ bool VisitInitListExpr(InitListExpr *ILE) {
+ Match(ILE->isSemanticForm() ? "semantic" : "syntactic", ILE->getLocStart());
+ return true;
+ }
+};
+
+TEST(RecursiveASTVisitor, InitListExprIsPreOrderVisitedTwice) {
+ InitListExprPreOrderVisitor Visitor;
+ Visitor.ExpectMatch("syntactic", 2, 21);
+ Visitor.ExpectMatch("semantic", 2, 21);
+ EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n"
+ "static struct S s = {.x = 0};\n",
+ InitListExprPreOrderVisitor::Lang_C));
+}
+
+TEST(RecursiveASTVisitor, InitListExprIsPostOrderVisitedTwice) {
+ InitListExprPostOrderVisitor Visitor;
+ Visitor.ExpectMatch("syntactic", 2, 21);
+ Visitor.ExpectMatch("semantic", 2, 21);
+ EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n"
+ "static struct S s = {.x = 0};\n",
+ InitListExprPostOrderVisitor::Lang_C));
+}
+
+TEST(RecursiveASTVisitor, InitListExprIsPreOrderNoQueueVisitedTwice) {
+ InitListExprPreOrderNoQueueVisitor Visitor;
+ Visitor.ExpectMatch("syntactic", 2, 21);
+ Visitor.ExpectMatch("semantic", 2, 21);
+ EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n"
+ "static struct S s = {.x = 0};\n",
+ InitListExprPreOrderNoQueueVisitor::Lang_C));
+}
+
+TEST(RecursiveASTVisitor, InitListExprIsPostOrderNoQueueVisitedTwice) {
+ InitListExprPostOrderNoQueueVisitor Visitor;
+ Visitor.ExpectMatch("syntactic", 2, 21);
+ Visitor.ExpectMatch("semantic", 2, 21);
+ EXPECT_TRUE(Visitor.runOver("struct S { int x; };\n"
+ "static struct S s = {.x = 0};\n",
+ InitListExprPostOrderNoQueueVisitor::Lang_C));
+}
+
} // end anonymous namespace
diff --git a/unittests/Tooling/RefactoringTest.cpp b/unittests/Tooling/RefactoringTest.cpp
index 495ac755b39d..15900940c887 100644
--- a/unittests/Tooling/RefactoringTest.cpp
+++ b/unittests/Tooling/RefactoringTest.cpp
@@ -1123,8 +1123,10 @@ TEST_F(AtomicChangeTest, AtomicChangeToYAML) {
"Key: 'input.cpp:20'\n"
"FilePath: input.cpp\n"
"Error: ''\n"
- "InsertedHeaders: [ a.h ]\n"
- "RemovedHeaders: [ b.h ]\n"
+ "InsertedHeaders: \n" // Extra whitespace here!
+ " - a.h\n"
+ "RemovedHeaders: \n" // Extra whitespace here!
+ " - b.h\n"
"Replacements: \n" // Extra whitespace here!
" - FilePath: input.cpp\n"
" Offset: 20\n"
@@ -1143,8 +1145,10 @@ TEST_F(AtomicChangeTest, YAMLToAtomicChange) {
"Key: 'input.cpp:20'\n"
"FilePath: input.cpp\n"
"Error: 'ok'\n"
- "InsertedHeaders: [ a.h ]\n"
- "RemovedHeaders: [ b.h ]\n"
+ "InsertedHeaders: \n" // Extra whitespace here!
+ " - a.h\n"
+ "RemovedHeaders: \n" // Extra whitespace here!
+ " - b.h\n"
"Replacements: \n" // Extra whitespace here!
" - FilePath: input.cpp\n"
" Offset: 20\n"
diff --git a/unittests/Tooling/TestVisitor.h b/unittests/Tooling/TestVisitor.h
index a762ec8b1453..adfd3ef60f50 100644
--- a/unittests/Tooling/TestVisitor.h
+++ b/unittests/Tooling/TestVisitor.h
@@ -53,7 +53,10 @@ public:
bool runOver(StringRef Code, Language L = Lang_CXX) {
std::vector<std::string> Args;
switch (L) {
- case Lang_C: Args.push_back("-std=c99"); break;
+ case Lang_C:
+ Args.push_back("-x");
+ Args.push_back("c");
+ break;
case Lang_CXX98: Args.push_back("-std=c++98"); break;
case Lang_CXX11: Args.push_back("-std=c++11"); break;
case Lang_CXX14: Args.push_back("-std=c++14"); break;