From 952eddef9aff85b1e92626e89baaf7a360e2ac85 Mon Sep 17 00:00:00 2001
From: dim <dim@FreeBSD.org>
Date: Sun, 22 Dec 2013 00:07:40 +0000
Subject: Vendor import of clang release_34 branch r197841 (effectively, 3.4
 RC3): https://llvm.org/svn/llvm-project/cfe/branches/release_34@197841

---
 unittests/ASTMatchers/Dynamic/RegistryTest.cpp | 347 +++++++++++++++++++++++++
 1 file changed, 347 insertions(+)
 create mode 100644 unittests/ASTMatchers/Dynamic/RegistryTest.cpp

(limited to 'unittests/ASTMatchers/Dynamic/RegistryTest.cpp')

diff --git a/unittests/ASTMatchers/Dynamic/RegistryTest.cpp b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
new file mode 100644
index 0000000..e716484
--- /dev/null
+++ b/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
@@ -0,0 +1,347 @@
+//===- unittest/ASTMatchers/Dynamic/RegistryTest.cpp - Registry unit tests -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===-----------------------------------------------------------------------===//
+
+#include <vector>
+
+#include "../ASTMatchersTest.h"
+#include "clang/ASTMatchers/Dynamic/Registry.h"
+#include "gtest/gtest.h"
+
+namespace clang {
+namespace ast_matchers {
+namespace dynamic {
+namespace {
+
+using ast_matchers::internal::Matcher;
+
+class RegistryTest : public ::testing::Test {
+public:
+  std::vector<ParserValue> Args() { return std::vector<ParserValue>(); }
+  std::vector<ParserValue> Args(const VariantValue &Arg1) {
+    std::vector<ParserValue> Out(1);
+    Out[0].Value = Arg1;
+    return Out;
+  }
+  std::vector<ParserValue> Args(const VariantValue &Arg1,
+                                const VariantValue &Arg2) {
+    std::vector<ParserValue> Out(2);
+    Out[0].Value = Arg1;
+    Out[1].Value = Arg2;
+    return Out;
+  }
+
+  VariantMatcher constructMatcher(StringRef MatcherName,
+                                  Diagnostics *Error = NULL) {
+    Diagnostics DummyError;
+    if (!Error) Error = &DummyError;
+    const VariantMatcher Out =
+        Registry::constructMatcher(MatcherName, SourceRange(), Args(), Error);
+    EXPECT_EQ("", DummyError.toStringFull());
+    return Out;
+  }
+
+  VariantMatcher constructMatcher(StringRef MatcherName,
+                                  const VariantValue &Arg1,
+                                  Diagnostics *Error = NULL) {
+    Diagnostics DummyError;
+    if (!Error) Error = &DummyError;
+    const VariantMatcher Out = Registry::constructMatcher(
+        MatcherName, SourceRange(), Args(Arg1), Error);
+    EXPECT_EQ("", DummyError.toStringFull());
+    return Out;
+  }
+
+  VariantMatcher constructMatcher(StringRef MatcherName,
+                                  const VariantValue &Arg1,
+                                  const VariantValue &Arg2,
+                                  Diagnostics *Error = NULL) {
+    Diagnostics DummyError;
+    if (!Error) Error = &DummyError;
+    const VariantMatcher Out = Registry::constructMatcher(
+        MatcherName, SourceRange(), Args(Arg1, Arg2), Error);
+    EXPECT_EQ("", DummyError.toStringFull());
+    return Out;
+  }
+};
+
+TEST_F(RegistryTest, CanConstructNoArgs) {
+  Matcher<Stmt> IsArrowValue = constructMatcher(
+      "memberExpr", constructMatcher("isArrow")).getTypedMatcher<Stmt>();
+  Matcher<Stmt> BoolValue =
+      constructMatcher("boolLiteral").getTypedMatcher<Stmt>();
+
+  const std::string ClassSnippet = "struct Foo { int x; };\n"
+                                   "Foo *foo = new Foo;\n"
+                                   "int i = foo->x;\n";
+  const std::string BoolSnippet = "bool Foo = true;\n";
+
+  EXPECT_TRUE(matches(ClassSnippet, IsArrowValue));
+  EXPECT_TRUE(matches(BoolSnippet, BoolValue));
+  EXPECT_FALSE(matches(ClassSnippet, BoolValue));
+  EXPECT_FALSE(matches(BoolSnippet, IsArrowValue));
+}
+
+TEST_F(RegistryTest, ConstructWithSimpleArgs) {
+  Matcher<Decl> Value = constructMatcher(
+      "namedDecl", constructMatcher("hasName", std::string("X")))
+      .getTypedMatcher<Decl>();
+  EXPECT_TRUE(matches("class X {};", Value));
+  EXPECT_FALSE(matches("int x;", Value));
+
+  Value = functionDecl(constructMatcher("parameterCountIs", 2)
+                           .getTypedMatcher<FunctionDecl>());
+  EXPECT_TRUE(matches("void foo(int,int);", Value));
+  EXPECT_FALSE(matches("void foo(int);", Value));
+}
+
+TEST_F(RegistryTest, ConstructWithMatcherArgs) {
+  Matcher<Decl> HasInitializerSimple = constructMatcher(
+      "varDecl", constructMatcher("hasInitializer", constructMatcher("stmt")))
+      .getTypedMatcher<Decl>();
+  Matcher<Decl> HasInitializerComplex = constructMatcher(
+      "varDecl",
+      constructMatcher("hasInitializer", constructMatcher("callExpr")))
+      .getTypedMatcher<Decl>();
+
+  std::string code = "int i;";
+  EXPECT_FALSE(matches(code, HasInitializerSimple));
+  EXPECT_FALSE(matches(code, HasInitializerComplex));
+
+  code = "int i = 1;";
+  EXPECT_TRUE(matches(code, HasInitializerSimple));
+  EXPECT_FALSE(matches(code, HasInitializerComplex));
+
+  code = "int y(); int i = y();";
+  EXPECT_TRUE(matches(code, HasInitializerSimple));
+  EXPECT_TRUE(matches(code, HasInitializerComplex));
+
+  Matcher<Decl> HasParameter =
+      functionDecl(constructMatcher(
+          "hasParameter", 1, constructMatcher("hasName", std::string("x")))
+                       .getTypedMatcher<FunctionDecl>());
+  EXPECT_TRUE(matches("void f(int a, int x);", HasParameter));
+  EXPECT_FALSE(matches("void f(int x, int a);", HasParameter));
+}
+
+TEST_F(RegistryTest, OverloadedMatchers) {
+  Matcher<Stmt> CallExpr0 = constructMatcher(
+      "callExpr",
+      constructMatcher("callee", constructMatcher("memberExpr",
+                                                  constructMatcher("isArrow"))))
+      .getTypedMatcher<Stmt>();
+
+  Matcher<Stmt> CallExpr1 = constructMatcher(
+      "callExpr",
+      constructMatcher(
+          "callee",
+          constructMatcher("methodDecl",
+                           constructMatcher("hasName", std::string("x")))))
+      .getTypedMatcher<Stmt>();
+
+  std::string Code = "class Y { public: void x(); }; void z() { Y y; y.x(); }";
+  EXPECT_FALSE(matches(Code, CallExpr0));
+  EXPECT_TRUE(matches(Code, CallExpr1));
+
+  Code = "class Z { public: void z() { this->z(); } };";
+  EXPECT_TRUE(matches(Code, CallExpr0));
+  EXPECT_FALSE(matches(Code, CallExpr1));
+}
+
+TEST_F(RegistryTest, PolymorphicMatchers) {
+  const VariantMatcher IsDefinition = constructMatcher("isDefinition");
+  Matcher<Decl> Var =
+      constructMatcher("varDecl", IsDefinition).getTypedMatcher<Decl>();
+  Matcher<Decl> Class =
+      constructMatcher("recordDecl", IsDefinition).getTypedMatcher<Decl>();
+  Matcher<Decl> Func =
+      constructMatcher("functionDecl", IsDefinition).getTypedMatcher<Decl>();
+  EXPECT_TRUE(matches("int a;", Var));
+  EXPECT_FALSE(matches("extern int a;", Var));
+  EXPECT_TRUE(matches("class A {};", Class));
+  EXPECT_FALSE(matches("class A;", Class));
+  EXPECT_TRUE(matches("void f(){};", Func));
+  EXPECT_FALSE(matches("void f();", Func));
+
+  Matcher<Decl> Anything = constructMatcher("anything").getTypedMatcher<Decl>();
+  Matcher<Decl> RecordDecl = constructMatcher(
+      "recordDecl", constructMatcher("hasName", std::string("Foo")),
+      VariantMatcher::SingleMatcher(Anything)).getTypedMatcher<Decl>();
+
+  EXPECT_TRUE(matches("int Foo;", Anything));
+  EXPECT_TRUE(matches("class Foo {};", Anything));
+  EXPECT_TRUE(matches("void Foo(){};", Anything));
+  EXPECT_FALSE(matches("int Foo;", RecordDecl));
+  EXPECT_TRUE(matches("class Foo {};", RecordDecl));
+  EXPECT_FALSE(matches("void Foo(){};", RecordDecl));
+
+  Matcher<Stmt> ConstructExpr = constructMatcher(
+      "constructExpr",
+      constructMatcher(
+          "hasDeclaration",
+          constructMatcher(
+              "methodDecl",
+              constructMatcher(
+                  "ofClass", constructMatcher("hasName", std::string("Foo"))))))
+                                    .getTypedMatcher<Stmt>();
+  EXPECT_FALSE(matches("class Foo { public: Foo(); };", ConstructExpr));
+  EXPECT_TRUE(
+      matches("class Foo { public: Foo(); }; Foo foo = Foo();", ConstructExpr));
+}
+
+TEST_F(RegistryTest, TemplateArgument) {
+  Matcher<Decl> HasTemplateArgument = constructMatcher(
+      "classTemplateSpecializationDecl",
+      constructMatcher(
+          "hasAnyTemplateArgument",
+          constructMatcher("refersToType",
+                           constructMatcher("asString", std::string("int")))))
+      .getTypedMatcher<Decl>();
+  EXPECT_TRUE(matches("template<typename T> class A {}; A<int> a;",
+                      HasTemplateArgument));
+  EXPECT_FALSE(matches("template<typename T> class A {}; A<char> a;",
+                       HasTemplateArgument));
+}
+
+TEST_F(RegistryTest, TypeTraversal) {
+  Matcher<Type> M = constructMatcher(
+      "pointerType",
+      constructMatcher("pointee", constructMatcher("isConstQualified"),
+                       constructMatcher("isInteger"))).getTypedMatcher<Type>();
+  EXPECT_FALSE(matches("int *a;", M));
+  EXPECT_TRUE(matches("int const *b;", M));
+
+  M = constructMatcher(
+      "arrayType",
+      constructMatcher("hasElementType", constructMatcher("builtinType")))
+      .getTypedMatcher<Type>();
+  EXPECT_FALSE(matches("struct A{}; A a[7];;", M));
+  EXPECT_TRUE(matches("int b[7];", M));
+}
+
+TEST_F(RegistryTest, CXXCtorInitializer) {
+  Matcher<Decl> CtorDecl = constructMatcher(
+      "constructorDecl",
+      constructMatcher(
+          "hasAnyConstructorInitializer",
+          constructMatcher("forField",
+                           constructMatcher("hasName", std::string("foo")))))
+      .getTypedMatcher<Decl>();
+  EXPECT_TRUE(matches("struct Foo { Foo() : foo(1) {} int foo; };", CtorDecl));
+  EXPECT_FALSE(matches("struct Foo { Foo() {} int foo; };", CtorDecl));
+  EXPECT_FALSE(matches("struct Foo { Foo() : bar(1) {} int bar; };", CtorDecl));
+}
+
+TEST_F(RegistryTest, Adaptative) {
+  Matcher<Decl> D = constructMatcher(
+      "recordDecl",
+      constructMatcher(
+          "has",
+          constructMatcher("recordDecl",
+                           constructMatcher("hasName", std::string("X")))))
+      .getTypedMatcher<Decl>();
+  EXPECT_TRUE(matches("class X {};", D));
+  EXPECT_TRUE(matches("class Y { class X {}; };", D));
+  EXPECT_FALSE(matches("class Y { class Z {}; };", D));
+
+  Matcher<Stmt> S = constructMatcher(
+      "forStmt",
+      constructMatcher(
+          "hasDescendant",
+          constructMatcher("varDecl",
+                           constructMatcher("hasName", std::string("X")))))
+      .getTypedMatcher<Stmt>();
+  EXPECT_TRUE(matches("void foo() { for(int X;;); }", S));
+  EXPECT_TRUE(matches("void foo() { for(;;) { int X; } }", S));
+  EXPECT_FALSE(matches("void foo() { for(;;); }", S));
+  EXPECT_FALSE(matches("void foo() { if (int X = 0){} }", S));
+
+  S = constructMatcher(
+      "compoundStmt", constructMatcher("hasParent", constructMatcher("ifStmt")))
+      .getTypedMatcher<Stmt>();
+  EXPECT_TRUE(matches("void foo() { if (true) { int x = 42; } }", S));
+  EXPECT_FALSE(matches("void foo() { if (true) return; }", S));
+}
+
+TEST_F(RegistryTest, VariadicOp) {
+  Matcher<Decl> D = constructMatcher(
+      "anyOf",
+      constructMatcher("recordDecl",
+                       constructMatcher("hasName", std::string("Foo"))),
+      constructMatcher("namedDecl",
+                       constructMatcher("hasName", std::string("foo"))))
+      .getTypedMatcher<Decl>();
+
+  EXPECT_TRUE(matches("void foo(){}", D));
+  EXPECT_TRUE(matches("struct Foo{};", D));
+  EXPECT_FALSE(matches("int i = 0;", D));
+
+  D = constructMatcher(
+      "allOf", constructMatcher("recordDecl"),
+      constructMatcher(
+          "namedDecl",
+          constructMatcher("anyOf",
+                           constructMatcher("hasName", std::string("Foo")),
+                           constructMatcher("hasName", std::string("Bar")))))
+      .getTypedMatcher<Decl>();
+
+  EXPECT_FALSE(matches("void foo(){}", D));
+  EXPECT_TRUE(matches("struct Foo{};", D));
+  EXPECT_FALSE(matches("int i = 0;", D));
+  EXPECT_TRUE(matches("class Bar{};", D));
+  EXPECT_FALSE(matches("class OtherBar{};", D));
+}
+
+TEST_F(RegistryTest, Errors) {
+  // Incorrect argument count.
+  OwningPtr<Diagnostics> Error(new Diagnostics());
+  EXPECT_TRUE(constructMatcher("hasInitializer", Error.get()).isNull());
+  EXPECT_EQ("Incorrect argument count. (Expected = 1) != (Actual = 0)",
+            Error->toString());
+  Error.reset(new Diagnostics());
+  EXPECT_TRUE(constructMatcher("isArrow", std::string(), Error.get()).isNull());
+  EXPECT_EQ("Incorrect argument count. (Expected = 0) != (Actual = 1)",
+            Error->toString());
+
+  // Bad argument type
+  Error.reset(new Diagnostics());
+  EXPECT_TRUE(constructMatcher("ofClass", std::string(), Error.get()).isNull());
+  EXPECT_EQ("Incorrect type for arg 1. (Expected = Matcher<CXXRecordDecl>) != "
+            "(Actual = String)",
+            Error->toString());
+  Error.reset(new Diagnostics());
+  EXPECT_TRUE(constructMatcher("recordDecl", constructMatcher("recordDecl"),
+                               constructMatcher("parameterCountIs", 3),
+                               Error.get()).isNull());
+  EXPECT_EQ("Incorrect type for arg 2. (Expected = Matcher<CXXRecordDecl>) != "
+            "(Actual = Matcher<FunctionDecl>)",
+            Error->toString());
+
+  // Bad argument type with variadic.
+  Error.reset(new Diagnostics());
+  EXPECT_TRUE(constructMatcher("anyOf", std::string(), Error.get()).isNull());
+  EXPECT_EQ(
+      "Incorrect type for arg 1. (Expected = Matcher<>) != (Actual = String)",
+      Error->toString());
+  Error.reset(new Diagnostics());
+  EXPECT_TRUE(constructMatcher(
+      "recordDecl",
+      constructMatcher("allOf",
+                       constructMatcher("isDerivedFrom", std::string("FOO")),
+                       constructMatcher("isArrow")),
+      Error.get()).isNull());
+  EXPECT_EQ("Incorrect type for arg 1. "
+            "(Expected = Matcher<CXXRecordDecl>) != "
+            "(Actual = Matcher<CXXRecordDecl>&Matcher<MemberExpr>)",
+            Error->toString());
+}
+
+} // end anonymous namespace
+} // end namespace dynamic
+} // end namespace ast_matchers
+} // end namespace clang
-- 
cgit v1.1