summaryrefslogtreecommitdiffstats
path: root/unittests/AST
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
committerdim <dim@FreeBSD.org>2013-12-22 00:07:40 +0000
commit952eddef9aff85b1e92626e89baaf7a360e2ac85 (patch)
treedf8df0b0067b381eab470a3b8f28d14a552a6340 /unittests/AST
parentea266cad53e3d49771fa38103913d3ec7a166694 (diff)
downloadFreeBSD-src-952eddef9aff85b1e92626e89baaf7a360e2ac85.zip
FreeBSD-src-952eddef9aff85b1e92626e89baaf7a360e2ac85.tar.gz
Vendor import of clang release_34 branch r197841 (effectively, 3.4 RC3):
https://llvm.org/svn/llvm-project/cfe/branches/release_34@197841
Diffstat (limited to 'unittests/AST')
-rw-r--r--unittests/AST/ASTTypeTraitsTest.cpp114
-rw-r--r--unittests/AST/ASTVectorTest.cpp24
-rw-r--r--unittests/AST/CMakeLists.txt3
-rw-r--r--unittests/AST/CommentParser.cpp35
-rw-r--r--unittests/AST/DeclTest.cpp59
-rw-r--r--unittests/AST/Makefile2
-rw-r--r--unittests/AST/MatchVerifier.h93
-rw-r--r--unittests/AST/SourceLocationTest.cpp111
8 files changed, 430 insertions, 11 deletions
diff --git a/unittests/AST/ASTTypeTraitsTest.cpp b/unittests/AST/ASTTypeTraitsTest.cpp
new file mode 100644
index 0000000..dd73b52
--- /dev/null
+++ b/unittests/AST/ASTTypeTraitsTest.cpp
@@ -0,0 +1,114 @@
+//===- unittest/AST/ASTTypeTraits.cpp - AST type traits 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/ASTTypeTraits.h"
+#include "gtest/gtest.h"
+#include "MatchVerifier.h"
+
+using namespace clang::ast_matchers;
+
+namespace clang {
+namespace ast_type_traits {
+
+TEST(ASTNodeKind, NoKind) {
+ EXPECT_FALSE(ASTNodeKind().isBaseOf(ASTNodeKind()));
+ EXPECT_FALSE(ASTNodeKind().isSame(ASTNodeKind()));
+}
+
+template <typename T> static ASTNodeKind DNT() {
+ return ASTNodeKind::getFromNodeKind<T>();
+}
+
+TEST(ASTNodeKind, Bases) {
+ EXPECT_TRUE(DNT<Decl>().isBaseOf(DNT<VarDecl>()));
+ EXPECT_FALSE(DNT<Decl>().isSame(DNT<VarDecl>()));
+ EXPECT_FALSE(DNT<VarDecl>().isBaseOf(DNT<Decl>()));
+
+ EXPECT_TRUE(DNT<Decl>().isSame(DNT<Decl>()));
+}
+
+TEST(ASTNodeKind, SameBase) {
+ EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<CallExpr>()));
+ EXPECT_TRUE(DNT<Expr>().isBaseOf(DNT<BinaryOperator>()));
+ EXPECT_FALSE(DNT<CallExpr>().isBaseOf(DNT<BinaryOperator>()));
+ EXPECT_FALSE(DNT<BinaryOperator>().isBaseOf(DNT<CallExpr>()));
+}
+
+TEST(ASTNodeKind, DiffBase) {
+ EXPECT_FALSE(DNT<Expr>().isBaseOf(DNT<ArrayType>()));
+ EXPECT_FALSE(DNT<QualType>().isBaseOf(DNT<FunctionDecl>()));
+ EXPECT_FALSE(DNT<Type>().isSame(DNT<QualType>()));
+}
+
+struct Foo {};
+
+TEST(ASTNodeKind, UnknownKind) {
+ // We can construct one, but it is nowhere in the hierarchy.
+ EXPECT_FALSE(DNT<Foo>().isSame(DNT<Foo>()));
+}
+
+TEST(ASTNodeKind, Name) {
+ EXPECT_EQ("Decl", DNT<Decl>().asStringRef());
+ EXPECT_EQ("CallExpr", DNT<CallExpr>().asStringRef());
+ EXPECT_EQ("ConstantArrayType", DNT<ConstantArrayType>().asStringRef());
+ EXPECT_EQ("<None>", ASTNodeKind().asStringRef());
+}
+
+TEST(DynTypedNode, DeclSourceRange) {
+ RangeVerifier<DynTypedNode> Verifier;
+ Verifier.expectRange(1, 1, 1, 11);
+ EXPECT_TRUE(Verifier.match("void f() {}", decl()));
+}
+
+TEST(DynTypedNode, StmtSourceRange) {
+ RangeVerifier<DynTypedNode> Verifier;
+ Verifier.expectRange(1, 10, 1, 11);
+ EXPECT_TRUE(Verifier.match("void f() {}", stmt()));
+}
+
+TEST(DynTypedNode, TypeLocSourceRange) {
+ RangeVerifier<DynTypedNode> Verifier;
+ Verifier.expectRange(1, 1, 1, 8);
+ EXPECT_TRUE(Verifier.match("void f() {}", typeLoc(loc(functionType()))));
+}
+
+TEST(DynTypedNode, NNSLocSourceRange) {
+ RangeVerifier<DynTypedNode> Verifier;
+ Verifier.expectRange(1, 33, 1, 34);
+ EXPECT_TRUE(Verifier.match("namespace N { typedef void T; } N::T f() {}",
+ nestedNameSpecifierLoc()));
+}
+
+TEST(DynTypedNode, DeclDump) {
+ DumpVerifier Verifier;
+ Verifier.expectSubstring("FunctionDecl");
+ EXPECT_TRUE(Verifier.match("void f() {}", functionDecl()));
+}
+
+TEST(DynTypedNode, StmtDump) {
+ DumpVerifier Verifier;
+ Verifier.expectSubstring("CompoundStmt");
+ EXPECT_TRUE(Verifier.match("void f() {}", stmt()));
+}
+
+TEST(DynTypedNode, DeclPrint) {
+ PrintVerifier Verifier;
+ Verifier.expectString("void f() {\n}\n\n");
+ EXPECT_TRUE(Verifier.match("void f() {}", functionDecl()));
+}
+
+TEST(DynTypedNode, StmtPrint) {
+ PrintVerifier Verifier;
+ Verifier.expectString("{\n}\n");
+ EXPECT_TRUE(Verifier.match("void f() {}", stmt()));
+}
+
+} // namespace ast_type_traits
+} // namespace clang
diff --git a/unittests/AST/ASTVectorTest.cpp b/unittests/AST/ASTVectorTest.cpp
new file mode 100644
index 0000000..a92e86b
--- /dev/null
+++ b/unittests/AST/ASTVectorTest.cpp
@@ -0,0 +1,24 @@
+//===- unittests/AST/DeclTest.cpp --- Declaration tests -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Unit tests for the ASTVector container.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Support/Compiler.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTVector.h"
+
+using namespace clang;
+
+LLVM_ATTRIBUTE_UNUSED void CompileTest() {
+ ASTContext *C = 0;
+ ASTVector<int> V;
+ V.insert(*C, V.begin(), 0);
+}
diff --git a/unittests/AST/CMakeLists.txt b/unittests/AST/CMakeLists.txt
index ad29428..70f86d3 100644
--- a/unittests/AST/CMakeLists.txt
+++ b/unittests/AST/CMakeLists.txt
@@ -1,8 +1,11 @@
add_clang_unittest(ASTTests
ASTContextParentMapTest.cpp
+ ASTTypeTraitsTest.cpp
+ ASTVectorTest.cpp
CommentLexer.cpp
CommentParser.cpp
DeclPrinterTest.cpp
+ DeclTest.cpp
SourceLocationTest.cpp
StmtPrinterTest.cpp
)
diff --git a/unittests/AST/CommentParser.cpp b/unittests/AST/CommentParser.cpp
index d05fb58..f75c636 100644
--- a/unittests/AST/CommentParser.cpp
+++ b/unittests/AST/CommentParser.cpp
@@ -628,18 +628,43 @@ TEST_F(CommentParserTest, Basic3) {
}
}
-TEST_F(CommentParserTest, Paragraph1) {
+TEST_F(CommentParserTest, ParagraphSplitting1) {
const char *Sources[] = {
"// Aaa\n"
"//\n"
"// Bbb",
"// Aaa\n"
+ "// \n"
+ "// Bbb",
+
+ "// Aaa\n"
+ "//\t\n"
+ "// Bbb",
+
+ "// Aaa\n"
"//\n"
"//\n"
"// Bbb",
- };
+ "/**\n"
+ " Aaa\n"
+ "\n"
+ " Bbb\n"
+ "*/",
+
+ "/**\n"
+ " Aaa\n"
+ " \n"
+ " Bbb\n"
+ "*/",
+
+ "/**\n"
+ " Aaa\n"
+ "\t \n"
+ " Bbb\n"
+ "*/",
+ };
for (size_t i = 0, e = array_lengthof(Sources); i != e; i++) {
FullComment *FC = parseString(Sources[i]);
@@ -650,7 +675,7 @@ TEST_F(CommentParserTest, Paragraph1) {
}
}
-TEST_F(CommentParserTest, Paragraph2) {
+TEST_F(CommentParserTest, Paragraph1) {
const char *Source =
"// \\brief Aaa\n"
"//\n"
@@ -670,7 +695,7 @@ TEST_F(CommentParserTest, Paragraph2) {
ASSERT_TRUE(HasParagraphCommentAt(FC, 2, " Bbb"));
}
-TEST_F(CommentParserTest, Paragraph3) {
+TEST_F(CommentParserTest, Paragraph2) {
const char *Source = "// \\brief \\author";
FullComment *FC = parseString(Source);
@@ -694,7 +719,7 @@ TEST_F(CommentParserTest, Paragraph3) {
}
}
-TEST_F(CommentParserTest, Paragraph4) {
+TEST_F(CommentParserTest, Paragraph3) {
const char *Source =
"// \\brief Aaa\n"
"// Bbb \\author\n"
diff --git a/unittests/AST/DeclTest.cpp b/unittests/AST/DeclTest.cpp
new file mode 100644
index 0000000..c845da2
--- /dev/null
+++ b/unittests/AST/DeclTest.cpp
@@ -0,0 +1,59 @@
+//===- unittests/AST/DeclTest.cpp --- Declaration tests -------------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Unit tests for Decl nodes in the AST.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Tooling/Tooling.h"
+#include "gtest/gtest.h"
+
+using namespace clang::ast_matchers;
+using namespace clang::tooling;
+
+TEST(Decl, CleansUpAPValues) {
+ MatchFinder Finder;
+ llvm::OwningPtr<FrontendActionFactory> Factory(
+ newFrontendActionFactory(&Finder));
+
+ // This is a regression test for a memory leak in APValues for structs that
+ // allocate memory. This test only fails if run under valgrind with full leak
+ // checking enabled.
+ std::vector<std::string> Args(1, "-std=c++11");
+ Args.push_back("-fno-ms-extensions");
+ ASSERT_TRUE(runToolOnCodeWithArgs(
+ Factory->create(),
+ "struct X { int a; }; constexpr X x = { 42 };"
+ "union Y { constexpr Y(int a) : a(a) {} int a; }; constexpr Y y = { 42 };"
+ "constexpr int z[2] = { 42, 43 };"
+ "constexpr int __attribute__((vector_size(16))) v1 = {};"
+ "\n#ifdef __SIZEOF_INT128__\n"
+ "constexpr __uint128_t large_int = 0xffffffffffffffff;"
+ "constexpr __uint128_t small_int = 1;"
+ "\n#endif\n"
+ "constexpr double d1 = 42.42;"
+ "constexpr long double d2 = 42.42;"
+ "constexpr _Complex long double c1 = 42.0i;"
+ "constexpr _Complex long double c2 = 42.0;"
+ "template<int N> struct A : A<N-1> {};"
+ "template<> struct A<0> { int n; }; A<50> a;"
+ "constexpr int &r = a.n;"
+ "constexpr int A<50>::*p = &A<50>::n;"
+ "void f() { foo: bar: constexpr int k = __builtin_constant_p(0) ?"
+ " (char*)&&foo - (char*)&&bar : 0; }",
+ Args));
+
+ // FIXME: Once this test starts breaking we can test APValue::needsCleanup
+ // for ComplexInt.
+ ASSERT_FALSE(runToolOnCodeWithArgs(
+ Factory->create(),
+ "constexpr _Complex __uint128_t c = 0xffffffffffffffff;",
+ Args));
+}
diff --git a/unittests/AST/Makefile b/unittests/AST/Makefile
index 4fb2f5b..0282d21 100644
--- a/unittests/AST/Makefile
+++ b/unittests/AST/Makefile
@@ -10,7 +10,7 @@
CLANG_LEVEL = ../..
TESTNAME = AST
include $(CLANG_LEVEL)/../../Makefile.config
-LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc
+LINK_COMPONENTS := $(TARGETS_TO_BUILD) asmparser bitreader support mc option
USEDLIBS = clangTooling.a clangFrontend.a clangSerialization.a clangDriver.a \
clangRewriteCore.a clangRewriteFrontend.a \
clangParse.a clangSema.a clangAnalysis.a \
diff --git a/unittests/AST/MatchVerifier.h b/unittests/AST/MatchVerifier.h
index 7aa7886..5a29cde 100644
--- a/unittests/AST/MatchVerifier.h
+++ b/unittests/AST/MatchVerifier.h
@@ -25,7 +25,7 @@
namespace clang {
namespace ast_matchers {
-enum Language { Lang_C, Lang_C89, Lang_CXX, Lang_OpenCL };
+enum Language { Lang_C, Lang_C89, Lang_CXX, Lang_CXX11, Lang_OpenCL };
/// \brief Base class for verifying some property of nodes found by a matcher.
template <typename NodeType>
@@ -34,12 +34,23 @@ public:
template <typename MatcherType>
testing::AssertionResult match(const std::string &Code,
const MatcherType &AMatcher) {
- return match(Code, AMatcher, Lang_CXX);
+ std::vector<std::string> Args;
+ return match(Code, AMatcher, Args, Lang_CXX);
}
template <typename MatcherType>
testing::AssertionResult match(const std::string &Code,
- const MatcherType &AMatcher, Language L);
+ const MatcherType &AMatcher,
+ Language L) {
+ std::vector<std::string> Args;
+ return match(Code, AMatcher, Args, L);
+ }
+
+ template <typename MatcherType>
+ testing::AssertionResult match(const std::string &Code,
+ const MatcherType &AMatcher,
+ std::vector<std::string>& Args,
+ Language L);
protected:
virtual void run(const MatchFinder::MatchResult &Result);
@@ -64,13 +75,13 @@ private:
/// verifier for the matched node.
template <typename NodeType> template <typename MatcherType>
testing::AssertionResult MatchVerifier<NodeType>::match(
- const std::string &Code, const MatcherType &AMatcher, Language L) {
+ const std::string &Code, const MatcherType &AMatcher,
+ std::vector<std::string>& Args, Language L) {
MatchFinder Finder;
Finder.addMatcher(AMatcher.bind(""), this);
OwningPtr<tooling::FrontendActionFactory> Factory(
tooling::newFrontendActionFactory(&Finder));
- std::vector<std::string> Args;
StringRef FileName;
switch (L) {
case Lang_C:
@@ -85,6 +96,10 @@ testing::AssertionResult MatchVerifier<NodeType>::match(
Args.push_back("-std=c++98");
FileName = "input.cc";
break;
+ case Lang_CXX11:
+ Args.push_back("-std=c++11");
+ FileName = "input.cc";
+ break;
case Lang_OpenCL:
FileName = "input.cl";
}
@@ -110,6 +125,20 @@ void MatchVerifier<NodeType>::run(const MatchFinder::MatchResult &Result) {
}
}
+template <>
+inline void MatchVerifier<ast_type_traits::DynTypedNode>::run(
+ const MatchFinder::MatchResult &Result) {
+ BoundNodes::IDToNodeMap M = Result.Nodes.getMap();
+ BoundNodes::IDToNodeMap::const_iterator I = M.find("");
+ if (I == M.end()) {
+ setFailure("Node was not bound");
+ } else {
+ // Callback has been called, default to success.
+ setSuccess();
+ verify(Result, I->second);
+ }
+}
+
/// \brief Verify whether a node has the correct source location.
///
/// By default, Node.getSourceLocation() is checked. This can be changed
@@ -192,5 +221,59 @@ private:
unsigned ExpectBeginLine, ExpectBeginColumn, ExpectEndLine, ExpectEndColumn;
};
+/// \brief Verify whether a node's dump contains a given substring.
+class DumpVerifier : public MatchVerifier<ast_type_traits::DynTypedNode> {
+public:
+ void expectSubstring(const std::string &Str) {
+ ExpectSubstring = Str;
+ }
+
+protected:
+ void verify(const MatchFinder::MatchResult &Result,
+ const ast_type_traits::DynTypedNode &Node) {
+ std::string DumpStr;
+ llvm::raw_string_ostream Dump(DumpStr);
+ Node.dump(Dump, *Result.SourceManager);
+
+ if (Dump.str().find(ExpectSubstring) == std::string::npos) {
+ std::string MsgStr;
+ llvm::raw_string_ostream Msg(MsgStr);
+ Msg << "Expected dump substring <" << ExpectSubstring << ">, found <"
+ << Dump.str() << '>';
+ this->setFailure(Msg.str());
+ }
+ }
+
+private:
+ std::string ExpectSubstring;
+};
+
+/// \brief Verify whether a node's pretty print matches a given string.
+class PrintVerifier : public MatchVerifier<ast_type_traits::DynTypedNode> {
+public:
+ void expectString(const std::string &Str) {
+ ExpectString = Str;
+ }
+
+protected:
+ void verify(const MatchFinder::MatchResult &Result,
+ const ast_type_traits::DynTypedNode &Node) {
+ std::string PrintStr;
+ llvm::raw_string_ostream Print(PrintStr);
+ Node.print(Print, Result.Context->getPrintingPolicy());
+
+ if (Print.str() != ExpectString) {
+ std::string MsgStr;
+ llvm::raw_string_ostream Msg(MsgStr);
+ Msg << "Expected pretty print <" << ExpectString << ">, found <"
+ << Print.str() << '>';
+ this->setFailure(Msg.str());
+ }
+ }
+
+private:
+ std::string ExpectString;
+};
+
} // end namespace ast_matchers
} // end namespace clang
diff --git a/unittests/AST/SourceLocationTest.cpp b/unittests/AST/SourceLocationTest.cpp
index f6c0edc..29156bc 100644
--- a/unittests/AST/SourceLocationTest.cpp
+++ b/unittests/AST/SourceLocationTest.cpp
@@ -155,5 +155,116 @@ TEST(InitListExpr, VectorLiteralInitListParens) {
"constant int2 i2 = (int2)(1, 2);", initListExpr(), Lang_OpenCL));
}
+class TemplateAngleBracketLocRangeVerifier : public RangeVerifier<TypeLoc> {
+protected:
+ virtual SourceRange getRange(const TypeLoc &Node) {
+ TemplateSpecializationTypeLoc T =
+ Node.getUnqualifiedLoc().castAs<TemplateSpecializationTypeLoc>();
+ assert(!T.isNull());
+ return SourceRange(T.getLAngleLoc(), T.getRAngleLoc());
+ }
+};
+
+TEST(TemplateSpecializationTypeLoc, AngleBracketLocations) {
+ TemplateAngleBracketLocRangeVerifier Verifier;
+ Verifier.expectRange(2, 8, 2, 10);
+ EXPECT_TRUE(Verifier.match(
+ "template<typename T> struct A {}; struct B{}; void f(\n"
+ "const A<B>&);",
+ loc(templateSpecializationType())));
+}
+
+TEST(CXXNewExpr, TypeParenRange) {
+ RangeVerifier<CXXNewExpr> Verifier;
+ Verifier.expectRange(1, 10, 1, 18);
+ EXPECT_TRUE(Verifier.match("int* a = new (int);", newExpr()));
+}
+
+class UnaryTransformTypeLocParensRangeVerifier : public RangeVerifier<TypeLoc> {
+protected:
+ virtual SourceRange getRange(const TypeLoc &Node) {
+ UnaryTransformTypeLoc T =
+ Node.getUnqualifiedLoc().castAs<UnaryTransformTypeLoc>();
+ assert(!T.isNull());
+ return SourceRange(T.getLParenLoc(), T.getRParenLoc());
+ }
+};
+
+TEST(UnaryTransformTypeLoc, ParensRange) {
+ UnaryTransformTypeLocParensRangeVerifier Verifier;
+ Verifier.expectRange(3, 26, 3, 28);
+ EXPECT_TRUE(Verifier.match(
+ "template <typename T>\n"
+ "struct S {\n"
+ "typedef __underlying_type(T) type;\n"
+ "};",
+ loc(unaryTransformType())));
+}
+
+TEST(CXXFunctionalCastExpr, SourceRange) {
+ RangeVerifier<CXXFunctionalCastExpr> Verifier;
+ Verifier.expectRange(2, 10, 2, 14);
+ EXPECT_TRUE(Verifier.match(
+ "int foo() {\n"
+ " return int{};\n"
+ "}",
+ functionalCastExpr(), Lang_CXX11));
+}
+
+TEST(CXXTemporaryObjectExpr, SourceRange) {
+ RangeVerifier<CXXTemporaryObjectExpr> Verifier;
+ Verifier.expectRange(2, 6, 2, 12);
+ EXPECT_TRUE(Verifier.match(
+ "struct A { A(int, int); };\n"
+ "A a( A{0, 0} );",
+ temporaryObjectExpr(), Lang_CXX11));
+}
+
+TEST(CXXUnresolvedConstructExpr, SourceRange) {
+ RangeVerifier<CXXUnresolvedConstructExpr> Verifier;
+ Verifier.expectRange(3, 10, 3, 12);
+ std::vector<std::string> Args;
+ Args.push_back("-fno-delayed-template-parsing");
+ EXPECT_TRUE(Verifier.match(
+ "template <typename U>\n"
+ "U foo() {\n"
+ " return U{};\n"
+ "}",
+ unresolvedConstructExpr(), Args, Lang_CXX11));
+}
+
+TEST(UsingDecl, SourceRange) {
+ RangeVerifier<UsingDecl> Verifier;
+ Verifier.expectRange(2, 22, 2, 25);
+ EXPECT_TRUE(Verifier.match(
+ "class B { protected: int i; };\n"
+ "class D : public B { B::i; };",
+ usingDecl()));
+}
+
+TEST(UnresolvedUsingValueDecl, SourceRange) {
+ RangeVerifier<UnresolvedUsingValueDecl> Verifier;
+ Verifier.expectRange(3, 3, 3, 6);
+ EXPECT_TRUE(Verifier.match(
+ "template <typename B>\n"
+ "class D : public B {\n"
+ " B::i;\n"
+ "};",
+ unresolvedUsingValueDecl()));
+}
+
+TEST(FriendDecl, InstantiationSourceRange) {
+ RangeVerifier<FriendDecl> Verifier;
+ Verifier.expectRange(4, 3, 4, 35);
+ EXPECT_TRUE(Verifier.match(
+ "template <typename T> class S;\n"
+ "template<class T> void operator+(S<T> x);\n"
+ "template<class T> struct S {\n"
+ " friend void operator+<>(S<T> src);\n"
+ "};\n"
+ "void test(S<double> s) { +s; }",
+ friendDecl(hasParent(recordDecl(isTemplateInstantiation())))));
+}
+
} // end namespace ast_matchers
} // end namespace clang
OpenPOWER on IntegriCloud