1//===- unittest/ASTMatchers/Dynamic/VariantValueTest.cpp - VariantValue unit tests -===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===-----------------------------------------------------------------------------===//
9
10#include "../ASTMatchersTest.h"
11#include "clang/ASTMatchers/Dynamic/VariantValue.h"
12#include "gtest/gtest.h"
13
14namespace clang {
15namespace ast_matchers {
16namespace dynamic {
17namespace {
18
19using ast_matchers::internal::DynTypedMatcher;
20using ast_matchers::internal::Matcher;
21
22TEST(VariantValueTest, Unsigned) {
23  const unsigned kUnsigned = 17;
24  VariantValue Value = kUnsigned;
25
26  EXPECT_TRUE(Value.isUnsigned());
27  EXPECT_EQ(kUnsigned, Value.getUnsigned());
28
29  EXPECT_TRUE(Value.hasValue());
30  EXPECT_FALSE(Value.isString());
31  EXPECT_FALSE(Value.isMatcher());
32}
33
34TEST(VariantValueTest, String) {
35  const ::std::string kString = "string";
36  VariantValue Value = kString;
37
38  EXPECT_TRUE(Value.isString());
39  EXPECT_EQ(kString, Value.getString());
40  EXPECT_EQ("String", Value.getTypeAsString());
41
42  EXPECT_TRUE(Value.hasValue());
43  EXPECT_FALSE(Value.isUnsigned());
44  EXPECT_FALSE(Value.isMatcher());
45}
46
47TEST(VariantValueTest, DynTypedMatcher) {
48  VariantValue Value = VariantMatcher::SingleMatcher(stmt());
49
50  EXPECT_TRUE(Value.hasValue());
51  EXPECT_FALSE(Value.isUnsigned());
52  EXPECT_FALSE(Value.isString());
53
54  EXPECT_TRUE(Value.isMatcher());
55  EXPECT_FALSE(Value.getMatcher().hasTypedMatcher<Decl>());
56  EXPECT_TRUE(Value.getMatcher().hasTypedMatcher<UnaryOperator>());
57  EXPECT_EQ("Matcher<Stmt>", Value.getTypeAsString());
58
59  // Can only convert to compatible matchers.
60  Value = VariantMatcher::SingleMatcher(recordDecl());
61  EXPECT_TRUE(Value.isMatcher());
62  EXPECT_TRUE(Value.getMatcher().hasTypedMatcher<Decl>());
63  EXPECT_FALSE(Value.getMatcher().hasTypedMatcher<UnaryOperator>());
64  EXPECT_EQ("Matcher<Decl>", Value.getTypeAsString());
65
66  Value = VariantMatcher::SingleMatcher(ignoringImpCasts(expr()));
67  EXPECT_TRUE(Value.isMatcher());
68  EXPECT_FALSE(Value.getMatcher().hasTypedMatcher<Decl>());
69  EXPECT_FALSE(Value.getMatcher().hasTypedMatcher<Stmt>());
70  EXPECT_TRUE(Value.getMatcher().hasTypedMatcher<Expr>());
71  EXPECT_TRUE(Value.getMatcher().hasTypedMatcher<IntegerLiteral>());
72  EXPECT_FALSE(Value.getMatcher().hasTypedMatcher<GotoStmt>());
73  EXPECT_EQ("Matcher<Expr>", Value.getTypeAsString());
74}
75
76TEST(VariantValueTest, Assignment) {
77  VariantValue Value = std::string("A");
78  EXPECT_TRUE(Value.isString());
79  EXPECT_EQ("A", Value.getString());
80  EXPECT_TRUE(Value.hasValue());
81  EXPECT_FALSE(Value.isUnsigned());
82  EXPECT_FALSE(Value.isMatcher());
83  EXPECT_EQ("String", Value.getTypeAsString());
84
85  Value = VariantMatcher::SingleMatcher(recordDecl());
86  EXPECT_TRUE(Value.hasValue());
87  EXPECT_FALSE(Value.isUnsigned());
88  EXPECT_FALSE(Value.isString());
89  EXPECT_TRUE(Value.isMatcher());
90  EXPECT_TRUE(Value.getMatcher().hasTypedMatcher<Decl>());
91  EXPECT_FALSE(Value.getMatcher().hasTypedMatcher<UnaryOperator>());
92  EXPECT_EQ("Matcher<Decl>", Value.getTypeAsString());
93
94  Value = 17;
95  EXPECT_TRUE(Value.isUnsigned());
96  EXPECT_EQ(17U, Value.getUnsigned());
97  EXPECT_TRUE(Value.hasValue());
98  EXPECT_FALSE(Value.isMatcher());
99  EXPECT_FALSE(Value.isString());
100
101  Value = VariantValue();
102  EXPECT_FALSE(Value.hasValue());
103  EXPECT_FALSE(Value.isUnsigned());
104  EXPECT_FALSE(Value.isString());
105  EXPECT_FALSE(Value.isMatcher());
106  EXPECT_EQ("Nothing", Value.getTypeAsString());
107}
108
109TEST(VariantValueTest, ImplicitBool) {
110  VariantValue Value;
111  bool IfTrue = false;
112  if (Value) {
113    IfTrue = true;
114  }
115  EXPECT_FALSE(IfTrue);
116  EXPECT_TRUE(!Value);
117
118  Value = std::string();
119  IfTrue = false;
120  if (Value) {
121    IfTrue = true;
122  }
123  EXPECT_TRUE(IfTrue);
124  EXPECT_FALSE(!Value);
125}
126
127TEST(VariantValueTest, Matcher) {
128  EXPECT_TRUE(matches("class X {};", VariantValue(VariantMatcher::SingleMatcher(
129                                                      recordDecl(hasName("X"))))
130                                         .getMatcher()
131                                         .getTypedMatcher<Decl>()));
132  EXPECT_TRUE(
133      matches("int x;", VariantValue(VariantMatcher::SingleMatcher(varDecl()))
134                            .getMatcher()
135                            .getTypedMatcher<Decl>()));
136  EXPECT_TRUE(
137      matches("int foo() { return 1 + 1; }",
138              VariantValue(VariantMatcher::SingleMatcher(functionDecl()))
139                  .getMatcher()
140                  .getTypedMatcher<Decl>()));
141  // Can't get the wrong matcher.
142  EXPECT_FALSE(VariantValue(VariantMatcher::SingleMatcher(varDecl()))
143                   .getMatcher()
144                   .hasTypedMatcher<Stmt>());
145#if !defined(NDEBUG) && GTEST_HAS_DEATH_TEST
146  // Trying to get the wrong matcher fails an assertion in Matcher<T>.  We don't
147  // do this test when building with MSVC because its debug C runtime prints the
148  // assertion failure message as a wide string, which gtest doesn't understand.
149  EXPECT_DEATH(VariantValue(VariantMatcher::SingleMatcher(varDecl()))
150                   .getMatcher()
151                   .getTypedMatcher<Stmt>(),
152               "hasTypedMatcher");
153#endif
154
155  EXPECT_FALSE(matches(
156      "int x;", VariantValue(VariantMatcher::SingleMatcher(functionDecl()))
157                    .getMatcher()
158                    .getTypedMatcher<Decl>()));
159  EXPECT_FALSE(
160      matches("int foo() { return 1 + 1; }",
161              VariantValue(VariantMatcher::SingleMatcher(declRefExpr()))
162                  .getMatcher()
163                  .getTypedMatcher<Stmt>()));
164}
165
166} // end anonymous namespace
167} // end namespace dynamic
168} // end namespace ast_matchers
169} // end namespace clang
170