summaryrefslogtreecommitdiffstats
path: root/clang/unittests
diff options
context:
space:
mode:
authorStephen Kelly <steveire@gmail.com>2019-05-04 16:51:58 +0100
committerStephen Kelly <steveire@gmail.com>2019-12-18 22:33:23 +0000
commit98e8f774eb6ca8946b3104b4e82beefd41ca2c35 (patch)
treea8452417e927406cee681323fa71bae48cd5ef76 /clang/unittests
parent84fd2bedf4096e78b892165138051b8563169fe3 (diff)
downloadbcm5719-llvm-98e8f774eb6ca8946b3104b4e82beefd41ca2c35.tar.gz
bcm5719-llvm-98e8f774eb6ca8946b3104b4e82beefd41ca2c35.zip
Add method to ignore invisible AST nodes
Reviewers: aaron.ballman Subscribers: mgorny, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D70613
Diffstat (limited to 'clang/unittests')
-rw-r--r--clang/unittests/AST/ASTTraverserTest.cpp235
-rw-r--r--clang/unittests/AST/CMakeLists.txt1
-rw-r--r--clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp143
3 files changed, 379 insertions, 0 deletions
diff --git a/clang/unittests/AST/ASTTraverserTest.cpp b/clang/unittests/AST/ASTTraverserTest.cpp
index 6debdf10eda..c995f55d3c8 100644
--- a/clang/unittests/AST/ASTTraverserTest.cpp
+++ b/clang/unittests/AST/ASTTraverserTest.cpp
@@ -95,6 +95,21 @@ template <typename... NodeType> std::string dumpASTString(NodeType &&... N) {
return OS.str();
}
+template <typename... NodeType>
+std::string dumpASTString(ast_type_traits::TraversalKind TK, NodeType &&... N) {
+ std::string Buffer;
+ llvm::raw_string_ostream OS(Buffer);
+
+ TestASTDumper Dumper(OS);
+ Dumper.SetTraversalKind(TK);
+
+ OS << "\n";
+
+ Dumper.Visit(std::forward<NodeType &&>(N)...);
+
+ return OS.str();
+}
+
const FunctionDecl *getFunctionNode(clang::ASTUnit *AST,
const std::string &Name) {
auto Result = ast_matchers::match(functionDecl(hasName(Name)).bind("fn"),
@@ -244,4 +259,224 @@ TemplateArgument
EXPECT_EQ(toTargetAddressSpace(static_cast<LangAS>(AS->getAddressSpace())),
19u);
}
+
+TEST(Traverse, IgnoreUnlessSpelledInSource) {
+
+ auto AST = buildASTFromCode(R"cpp(
+
+struct A
+{
+};
+
+struct B
+{
+ B(int);
+ B(A const& a);
+ B();
+};
+
+struct C
+{
+ operator B();
+};
+
+B func1() {
+ return 42;
+}
+
+B func2() {
+ return B{42};
+}
+
+B func3() {
+ return B(42);
+}
+
+B func4() {
+ return B();
+}
+
+B func5() {
+ return B{};
+}
+
+B func6() {
+ return C();
+}
+
+B func7() {
+ return A();
+}
+
+B func8() {
+ return C{};
+}
+
+B func9() {
+ return A{};
+}
+
+B func10() {
+ A a;
+ return a;
+}
+
+B func11() {
+ B b;
+ return b;
+}
+
+B func12() {
+ C c;
+ return c;
+}
+
+)cpp");
+
+ auto getFunctionNode = [&AST](const std::string &name) {
+ auto BN = ast_matchers::match(functionDecl(hasName(name)).bind("fn"),
+ AST->getASTContext());
+ EXPECT_EQ(BN.size(), 1u);
+ return BN[0].getNodeAs<Decl>("fn");
+ };
+
+ {
+ auto FN = getFunctionNode("func1");
+
+ EXPECT_EQ(dumpASTString(ast_type_traits::TK_AsIs, FN),
+ R"cpp(
+FunctionDecl 'func1'
+`-CompoundStmt
+ `-ReturnStmt
+ `-ExprWithCleanups
+ `-CXXConstructExpr
+ `-MaterializeTemporaryExpr
+ `-ImplicitCastExpr
+ `-CXXConstructExpr
+ `-IntegerLiteral
+)cpp");
+
+ EXPECT_EQ(
+ dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource, FN),
+ R"cpp(
+FunctionDecl 'func1'
+`-CompoundStmt
+ `-ReturnStmt
+ `-IntegerLiteral
+)cpp");
+ }
+
+ EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ getFunctionNode("func2")),
+ R"cpp(
+FunctionDecl 'func2'
+`-CompoundStmt
+ `-ReturnStmt
+ `-CXXTemporaryObjectExpr
+ `-IntegerLiteral
+)cpp");
+
+ EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ getFunctionNode("func3")),
+ R"cpp(
+FunctionDecl 'func3'
+`-CompoundStmt
+ `-ReturnStmt
+ `-CXXFunctionalCastExpr
+ `-IntegerLiteral
+)cpp");
+
+ EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ getFunctionNode("func4")),
+ R"cpp(
+FunctionDecl 'func4'
+`-CompoundStmt
+ `-ReturnStmt
+ `-CXXTemporaryObjectExpr
+)cpp");
+
+ EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ getFunctionNode("func5")),
+ R"cpp(
+FunctionDecl 'func5'
+`-CompoundStmt
+ `-ReturnStmt
+ `-CXXTemporaryObjectExpr
+)cpp");
+
+ EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ getFunctionNode("func6")),
+ R"cpp(
+FunctionDecl 'func6'
+`-CompoundStmt
+ `-ReturnStmt
+ `-CXXTemporaryObjectExpr
+)cpp");
+
+ EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ getFunctionNode("func7")),
+ R"cpp(
+FunctionDecl 'func7'
+`-CompoundStmt
+ `-ReturnStmt
+ `-CXXTemporaryObjectExpr
+)cpp");
+
+ EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ getFunctionNode("func8")),
+ R"cpp(
+FunctionDecl 'func8'
+`-CompoundStmt
+ `-ReturnStmt
+ `-CXXFunctionalCastExpr
+ `-InitListExpr
+)cpp");
+
+ EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ getFunctionNode("func9")),
+ R"cpp(
+FunctionDecl 'func9'
+`-CompoundStmt
+ `-ReturnStmt
+ `-CXXFunctionalCastExpr
+ `-InitListExpr
+)cpp");
+
+ EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ getFunctionNode("func10")),
+ R"cpp(
+FunctionDecl 'func10'
+`-CompoundStmt
+ |-DeclStmt
+ | `-VarDecl 'a'
+ | `-CXXConstructExpr
+ `-ReturnStmt
+ `-DeclRefExpr 'a'
+)cpp");
+
+ EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ getFunctionNode("func11")),
+ R"cpp(
+FunctionDecl 'func11'
+`-CompoundStmt
+ |-DeclStmt
+ | `-VarDecl 'b'
+ | `-CXXConstructExpr
+ `-ReturnStmt
+ `-DeclRefExpr 'b'
+)cpp");
+
+ EXPECT_EQ(dumpASTString(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ getFunctionNode("func12")),
+ R"cpp(
+FunctionDecl 'func12'
+`-CompoundStmt
+ |-DeclStmt
+ | `-VarDecl 'c'
+ | `-CXXConstructExpr
+ `-ReturnStmt
+ `-DeclRefExpr 'c'
+)cpp");
+}
+
} // namespace clang
diff --git a/clang/unittests/AST/CMakeLists.txt b/clang/unittests/AST/CMakeLists.txt
index 4d463d1cc30..be585efc7a2 100644
--- a/clang/unittests/AST/CMakeLists.txt
+++ b/clang/unittests/AST/CMakeLists.txt
@@ -15,6 +15,7 @@ add_clang_unittest(ASTTests
ASTImporterVisibilityTest.cpp
ASTTraverserTest.cpp
ASTTypeTraitsTest.cpp
+ ASTTraverserTest.cpp
ASTVectorTest.cpp
CommentLexer.cpp
CommentParser.cpp
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index f67e4d965b5..a21ed04b32d 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -1680,6 +1680,149 @@ void foo()
functionDecl(hasDescendant(Matcher)))))));
}
+TEST(Traversal, traverseUnlessSpelledInSource) {
+
+ StringRef Code = R"cpp(
+
+struct A
+{
+};
+
+struct B
+{
+ B(int);
+ B(A const& a);
+ B();
+};
+
+struct C
+{
+ operator B();
+};
+
+B func1() {
+ return 42;
+}
+
+B func2() {
+ return B{42};
+}
+
+B func3() {
+ return B(42);
+}
+
+B func4() {
+ return B();
+}
+
+B func5() {
+ return B{};
+}
+
+B func6() {
+ return C();
+}
+
+B func7() {
+ return A();
+}
+
+B func8() {
+ return C{};
+}
+
+B func9() {
+ return A{};
+}
+
+B func10() {
+ A a;
+ return a;
+}
+
+B func11() {
+ B b;
+ return b;
+}
+
+B func12() {
+ C c;
+ return c;
+}
+
+)cpp";
+
+ EXPECT_TRUE(matches(
+ Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ returnStmt(forFunction(functionDecl(hasName("func1"))),
+ hasReturnValue(integerLiteral(equals(42)))))));
+
+ EXPECT_TRUE(matches(
+ Code,
+ traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ returnStmt(forFunction(functionDecl(hasName("func2"))),
+ hasReturnValue(cxxTemporaryObjectExpr(
+ hasArgument(0, integerLiteral(equals(42)))))))));
+
+ EXPECT_TRUE(matches(
+ Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ returnStmt(forFunction(functionDecl(hasName("func3"))),
+ hasReturnValue(
+ cxxFunctionalCastExpr(hasSourceExpression(
+ integerLiteral(equals(42)))))))));
+
+ EXPECT_TRUE(matches(
+ Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ returnStmt(forFunction(functionDecl(hasName("func4"))),
+ hasReturnValue(cxxTemporaryObjectExpr())))));
+
+ EXPECT_TRUE(matches(
+ Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ returnStmt(forFunction(functionDecl(hasName("func5"))),
+ hasReturnValue(cxxTemporaryObjectExpr())))));
+
+ EXPECT_TRUE(matches(
+ Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ returnStmt(forFunction(functionDecl(hasName("func6"))),
+ hasReturnValue(cxxTemporaryObjectExpr())))));
+
+ EXPECT_TRUE(matches(
+ Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ returnStmt(forFunction(functionDecl(hasName("func7"))),
+ hasReturnValue(cxxTemporaryObjectExpr())))));
+
+ EXPECT_TRUE(matches(
+ Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ returnStmt(forFunction(functionDecl(hasName("func8"))),
+ hasReturnValue(cxxFunctionalCastExpr(
+ hasSourceExpression(initListExpr())))))));
+
+ EXPECT_TRUE(matches(
+ Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ returnStmt(forFunction(functionDecl(hasName("func9"))),
+ hasReturnValue(cxxFunctionalCastExpr(
+ hasSourceExpression(initListExpr())))))));
+
+ EXPECT_TRUE(matches(
+ Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ returnStmt(forFunction(functionDecl(hasName("func10"))),
+ hasReturnValue(
+ declRefExpr(to(varDecl(hasName("a")))))))));
+
+ EXPECT_TRUE(matches(
+ Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ returnStmt(forFunction(functionDecl(hasName("func11"))),
+ hasReturnValue(
+ declRefExpr(to(varDecl(hasName("b")))))))));
+
+ EXPECT_TRUE(matches(
+ Code, traverse(ast_type_traits::TK_IgnoreUnlessSpelledInSource,
+ returnStmt(forFunction(functionDecl(hasName("func12"))),
+ hasReturnValue(
+ declRefExpr(to(varDecl(hasName("c")))))))));
+}
+
TEST(IgnoringImpCasts, MatchesImpCasts) {
// This test checks that ignoringImpCasts matches when implicit casts are
// present and its inner matcher alone does not match.
OpenPOWER on IntegriCloud