diff options
Diffstat (limited to 'unittests/Tooling')
-rw-r--r-- | unittests/Tooling/CMakeLists.txt | 1 | ||||
-rw-r--r-- | unittests/Tooling/CastExprTest.cpp | 38 | ||||
-rw-r--r-- | unittests/Tooling/CompilationDatabaseTest.cpp | 21 | ||||
-rw-r--r-- | unittests/Tooling/RecursiveASTVisitorTest.cpp | 86 | ||||
-rw-r--r-- | unittests/Tooling/RefactoringTest.cpp | 12 | ||||
-rw-r--r-- | unittests/Tooling/TestVisitor.h | 5 |
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; |