clang  13.0.0git
GtestMatchers.cpp
Go to the documentation of this file.
1 //===- GtestMatchers.cpp - AST Matchers for Gtest ---------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements several matchers for popular gtest macros. In general,
10 // AST matchers cannot match calls to macros. However, we can simulate such
11 // matches if the macro definition has identifiable elements that themselves can
12 // be matched. In that case, we can match on those elements and then check that
13 // the match occurs within an expansion of the desired macro. The more uncommon
14 // the identified elements, the more efficient this process will be.
15 //
16 //===----------------------------------------------------------------------===//
17 
19 #include "clang/AST/ASTConsumer.h"
20 #include "clang/AST/ASTContext.h"
23 #include "llvm/ADT/DenseMap.h"
24 #include "llvm/ADT/StringMap.h"
25 #include "llvm/ADT/StringRef.h"
26 
27 namespace clang {
28 namespace ast_matchers {
29 namespace {
30 
31 enum class MacroType {
32  Expect,
33  Assert,
34  On,
35 };
36 
37 } // namespace
38 
40  switch (Cmp) {
41  case GtestCmp::Eq:
42  return cxxMethodDecl(hasName("Compare"),
43  ofClass(cxxRecordDecl(isSameOrDerivedFrom(
44  hasName("::testing::internal::EqHelper")))));
45  case GtestCmp::Ne:
46  return functionDecl(hasName("::testing::internal::CmpHelperNE"));
47  case GtestCmp::Ge:
48  return functionDecl(hasName("::testing::internal::CmpHelperGE"));
49  case GtestCmp::Gt:
50  return functionDecl(hasName("::testing::internal::CmpHelperGT"));
51  case GtestCmp::Le:
52  return functionDecl(hasName("::testing::internal::CmpHelperLE"));
53  case GtestCmp::Lt:
54  return functionDecl(hasName("::testing::internal::CmpHelperLT"));
55  }
56  llvm_unreachable("Unhandled GtestCmp enum");
57 }
58 
59 static llvm::StringRef getMacroTypeName(MacroType Macro) {
60  switch (Macro) {
61  case MacroType::Expect:
62  return "EXPECT";
63  case MacroType::Assert:
64  return "ASSERT";
65  case MacroType::On:
66  return "ON";
67  }
68  llvm_unreachable("Unhandled MacroType enum");
69 }
70 
71 static llvm::StringRef getComparisonTypeName(GtestCmp Cmp) {
72  switch (Cmp) {
73  case GtestCmp::Eq:
74  return "EQ";
75  case GtestCmp::Ne:
76  return "NE";
77  case GtestCmp::Ge:
78  return "GE";
79  case GtestCmp::Gt:
80  return "GT";
81  case GtestCmp::Le:
82  return "LE";
83  case GtestCmp::Lt:
84  return "LT";
85  }
86  llvm_unreachable("Unhandled GtestCmp enum");
87 }
88 
89 static std::string getMacroName(MacroType Macro, GtestCmp Cmp) {
90  return (getMacroTypeName(Macro) + "_" + getComparisonTypeName(Cmp)).str();
91 }
92 
93 static std::string getMacroName(MacroType Macro, llvm::StringRef Operation) {
94  return (getMacroTypeName(Macro) + "_" + Operation).str();
95 }
96 
97 // Under the hood, ON_CALL is expanded to a call to `InternalDefaultActionSetAt`
98 // to set a default action spec to the underlying function mocker, while
99 // EXPECT_CALL is expanded to a call to `InternalExpectedAt` to set a new
100 // expectation spec.
101 static llvm::StringRef getSpecSetterName(MacroType Macro) {
102  switch (Macro) {
103  case MacroType::On:
104  return "InternalDefaultActionSetAt";
105  case MacroType::Expect:
106  return "InternalExpectedAt";
107  default:
108  llvm_unreachable("Unhandled MacroType enum");
109  }
110  llvm_unreachable("Unhandled MacroType enum");
111 }
112 
113 // In general, AST matchers cannot match calls to macros. However, we can
114 // simulate such matches if the macro definition has identifiable elements that
115 // themselves can be matched. In that case, we can match on those elements and
116 // then check that the match occurs within an expansion of the desired
117 // macro. The more uncommon the identified elements, the more efficient this
118 // process will be.
119 //
120 // We use this approach to implement the derived matchers gtestAssert and
121 // gtestExpect.
122 static internal::BindableMatcher<Stmt>
124  StatementMatcher Right) {
125  return callExpr(isExpandedFromMacro(getMacroName(Macro, Cmp)),
126  callee(getComparisonDecl(Cmp)), hasArgument(2, Left),
127  hasArgument(3, Right));
128 }
129 
130 static internal::BindableMatcher<Stmt>
131 gtestThatInternal(MacroType Macro, StatementMatcher Actual,
132  StatementMatcher Matcher) {
133  return cxxOperatorCallExpr(
134  isExpandedFromMacro(getMacroName(Macro, "THAT")),
135  hasOverloadedOperatorName("()"), hasArgument(2, Actual),
136  hasArgument(
138  "::testing::internal::PredicateFormatterFromMatcher"))),
139  ignoringImplicit(
141  "::testing::internal::"
142  "MakePredicateFormatterFromMatcher"))),
143  hasArgument(0, ignoringImplicit(Matcher)))))));
144 }
145 
146 static internal::BindableMatcher<Stmt>
147 gtestCallInternal(MacroType Macro, StatementMatcher MockCall, MockArgs Args) {
148  // A ON_CALL or EXPECT_CALL macro expands to different AST structures
149  // depending on whether the mock method has arguments or not.
150  switch (Args) {
151  // For example,
152  // `ON_CALL(mock, TwoParamMethod)` is expanded to
153  // `mock.gmock_TwoArgsMethod(WithoutMatchers(),
154  // nullptr).InternalDefaultActionSetAt(...)`.
155  // EXPECT_CALL is the same except
156  // that it calls `InternalExpectedAt` instead of `InternalDefaultActionSetAt`
157  // in the end.
158  case MockArgs::None:
159  return cxxMemberCallExpr(
160  isExpandedFromMacro(getMacroName(Macro, "CALL")),
161  callee(functionDecl(hasName(getSpecSetterName(Macro)))),
162  onImplicitObjectArgument(ignoringImplicit(MockCall)));
163  // For example,
164  // `ON_CALL(mock, TwoParamMethod(m1, m2))` is expanded to
165  // `mock.gmock_TwoParamMethod(m1,m2)(WithoutMatchers(),
166  // nullptr).InternalDefaultActionSetAt(...)`.
167  // EXPECT_CALL is the same except that it calls `InternalExpectedAt` instead
168  // of `InternalDefaultActionSetAt` in the end.
169  case MockArgs::Some:
170  return cxxMemberCallExpr(
171  isExpandedFromMacro(getMacroName(Macro, "CALL")),
172  callee(functionDecl(hasName(getSpecSetterName(Macro)))),
173  onImplicitObjectArgument(ignoringImplicit(cxxOperatorCallExpr(
174  hasOverloadedOperatorName("()"), argumentCountIs(3),
175  hasArgument(0, ignoringImplicit(MockCall))))));
176  }
177  llvm_unreachable("Unhandled MockArgs enum");
178 }
179 
180 static internal::BindableMatcher<Stmt>
181 gtestCallInternal(MacroType Macro, StatementMatcher MockObject,
182  llvm::StringRef MockMethodName, MockArgs Args) {
183  return gtestCallInternal(
184  Macro,
186  onImplicitObjectArgument(MockObject),
187  callee(functionDecl(hasName(("gmock_" + MockMethodName).str())))),
188  Args);
189 }
190 
191 internal::BindableMatcher<Stmt> gtestAssert(GtestCmp Cmp, StatementMatcher Left,
192  StatementMatcher Right) {
193  return gtestComparisonInternal(MacroType::Assert, Cmp, Left, Right);
194 }
195 
196 internal::BindableMatcher<Stmt> gtestExpect(GtestCmp Cmp, StatementMatcher Left,
197  StatementMatcher Right) {
198  return gtestComparisonInternal(MacroType::Expect, Cmp, Left, Right);
199 }
200 
201 internal::BindableMatcher<Stmt> gtestAssertThat(StatementMatcher Actual,
202  StatementMatcher Matcher) {
203  return gtestThatInternal(MacroType::Assert, Actual, Matcher);
204 }
205 
206 internal::BindableMatcher<Stmt> gtestExpectThat(StatementMatcher Actual,
207  StatementMatcher Matcher) {
208  return gtestThatInternal(MacroType::Expect, Actual, Matcher);
209 }
210 
211 internal::BindableMatcher<Stmt> gtestOnCall(StatementMatcher MockObject,
212  llvm::StringRef MockMethodName,
213  MockArgs Args) {
214  return gtestCallInternal(MacroType::On, MockObject, MockMethodName, Args);
215 }
216 
217 internal::BindableMatcher<Stmt> gtestOnCall(StatementMatcher MockCall,
218  MockArgs Args) {
219  return gtestCallInternal(MacroType::On, MockCall, Args);
220 }
221 
222 internal::BindableMatcher<Stmt> gtestExpectCall(StatementMatcher MockObject,
223  llvm::StringRef MockMethodName,
224  MockArgs Args) {
225  return gtestCallInternal(MacroType::Expect, MockObject, MockMethodName, Args);
226 }
227 
228 internal::BindableMatcher<Stmt> gtestExpectCall(StatementMatcher MockCall,
229  MockArgs Args) {
230  return gtestCallInternal(MacroType::Expect, MockCall, Args);
231 }
232 
233 } // end namespace ast_matchers
234 } // end namespace clang
clang::ast_matchers::GtestCmp::Eq
@ Eq
clang::ast_matchers::StatementMatcher
internal::Matcher< Stmt > StatementMatcher
Definition: ASTMatchers.h:142
clang::ast_matchers::MockArgs::None
@ None
clang::ast_matchers::gtestThatInternal
static internal::BindableMatcher< Stmt > gtestThatInternal(MacroType Macro, StatementMatcher Actual, StatementMatcher Matcher)
Definition: GtestMatchers.cpp:131
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::ast_matchers::getMacroName
static std::string getMacroName(MacroType Macro, GtestCmp Cmp)
Definition: GtestMatchers.cpp:89
clang::ast_matchers::GtestCmp::Lt
@ Lt
clang::ast_matchers::MockArgs::Some
@ Some
clang::ast_matchers::getMacroTypeName
static llvm::StringRef getMacroTypeName(MacroType Macro)
Definition: GtestMatchers.cpp:59
clang::ast_matchers::MockArgs
MockArgs
This enum indicates whether the mock method in the matched ON_CALL or EXPECT_CALL macro has arguments...
Definition: GtestMatchers.h:38
ASTMatchFinder.h
clang::ast_matchers::GtestCmp
GtestCmp
Gtest's comparison operations.
Definition: GtestMatchers.h:25
clang::ast_matchers::cxxOperatorCallExpr
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXOperatorCallExpr > cxxOperatorCallExpr
Matches overloaded operator calls.
Definition: ASTMatchersInternal.cpp:873
GtestMatchers.h
clang::ast_matchers::expr
const internal::VariadicDynCastAllOfMatcher< Stmt, Expr > expr
Matches expressions.
Definition: ASTMatchersInternal.cpp:876
clang::ast_matchers::gtestExpectThat
internal::BindableMatcher< Stmt > gtestExpectThat(StatementMatcher Actual, StatementMatcher Matcher)
Matcher for gtest's EXPECT_THAT macro.
Definition: GtestMatchers.cpp:206
clang::ast_matchers::cxxMethodDecl
const internal::VariadicDynCastAllOfMatcher< Decl, CXXMethodDecl > cxxMethodDecl
Matches method declarations.
Definition: ASTMatchersInternal.cpp:785
clang::ast_matchers::gtestComparisonInternal
static internal::BindableMatcher< Stmt > gtestComparisonInternal(MacroType Macro, GtestCmp Cmp, StatementMatcher Left, StatementMatcher Right)
Definition: GtestMatchers.cpp:123
clang::ast_matchers::gtestAssertThat
internal::BindableMatcher< Stmt > gtestAssertThat(StatementMatcher Actual, StatementMatcher Matcher)
Matcher for gtest's ASSERT_THAT macro.
Definition: GtestMatchers.cpp:201
clang::ast_matchers::gtestAssert
internal::BindableMatcher< Stmt > gtestAssert(GtestCmp Cmp, StatementMatcher Left, StatementMatcher Right)
Matcher for gtest's ASSERT comparison macros including ASSERT_EQ, ASSERT_NE, ASSERT_GE,...
Definition: GtestMatchers.cpp:191
ASTContext.h
clang::ast_matchers::GtestCmp::Le
@ Le
clang::ast_matchers::gtestExpectCall
internal::BindableMatcher< Stmt > gtestExpectCall(StatementMatcher MockObject, llvm::StringRef MockMethodName, MockArgs Args)
Matcher for gtest's EXPECT_CALL macro.
Definition: GtestMatchers.cpp:222
clang::ast_matchers::cxxMemberCallExpr
const internal::VariadicDynCastAllOfMatcher< Stmt, CXXMemberCallExpr > cxxMemberCallExpr
Matches member call expressions.
Definition: ASTMatchersInternal.cpp:806
clang::ast_matchers::getSpecSetterName
static llvm::StringRef getSpecSetterName(MacroType Macro)
Definition: GtestMatchers.cpp:101
clang::ast_matchers::gtestCallInternal
static internal::BindableMatcher< Stmt > gtestCallInternal(MacroType Macro, StatementMatcher MockCall, MockArgs Args)
Definition: GtestMatchers.cpp:147
clang::ast_matchers::GtestCmp::Gt
@ Gt
ASTConsumer.h
clang::ast_matchers::callExpr
const internal::VariadicDynCastAllOfMatcher< Stmt, CallExpr > callExpr
Matches call expressions.
Definition: ASTMatchersInternal.cpp:803
clang::ast_matchers::GtestCmp::Ne
@ Ne
clang::ast_matchers::functionDecl
const internal::VariadicDynCastAllOfMatcher< Decl, FunctionDecl > functionDecl
Matches function declarations.
Definition: ASTMatchersInternal.cpp:792
clang::ast_matchers::getComparisonDecl
static DeclarationMatcher getComparisonDecl(GtestCmp Cmp)
Definition: GtestMatchers.cpp:39
clang::ast_matchers::GtestCmp::Ge
@ Ge
clang::ast_matchers::gtestOnCall
internal::BindableMatcher< Stmt > gtestOnCall(StatementMatcher MockObject, llvm::StringRef MockMethodName, MockArgs Args)
Like the first gtestExpectCall overload but for ON_CALL.
Definition: GtestMatchers.cpp:211
clang::ast_matchers::getComparisonTypeName
static llvm::StringRef getComparisonTypeName(GtestCmp Cmp)
Definition: GtestMatchers.cpp:71
clang
Definition: CalledOnceCheck.h:17
RecursiveASTVisitor.h
clang::ast_matchers::classTemplateSpecializationDecl
const internal::VariadicDynCastAllOfMatcher< Decl, ClassTemplateSpecializationDecl > classTemplateSpecializationDecl
Matches C++ class template specializations.
Definition: ASTMatchersInternal.cpp:750
clang::ast_matchers::hasName
internal::Matcher< NamedDecl > hasName(StringRef Name)
Matches NamedDecl nodes that have the specified name.
Definition: ASTMatchers.h:2987
clang::ast_matchers::DeclarationMatcher
internal::Matcher< Decl > DeclarationMatcher
Types of matchers for the top-level classes in the AST class hierarchy.
Definition: ASTMatchers.h:141
clang::ast_matchers::cxxRecordDecl
const internal::VariadicDynCastAllOfMatcher< Decl, CXXRecordDecl > cxxRecordDecl
Matches C++ class declarations.
Definition: ASTMatchersInternal.cpp:745
clang::ast_matchers::hasOverloadedOperatorName
internal::PolymorphicMatcher< internal::HasOverloadedOperatorNameMatcher, AST_POLYMORPHIC_SUPPORTED_TYPES(CXXOperatorCallExpr, FunctionDecl), std::vector< std::string > > hasOverloadedOperatorName(StringRef Name)
Matches overloaded operator names.
Definition: ASTMatchers.h:3050
clang::ast_matchers::gtestExpect
internal::BindableMatcher< Stmt > gtestExpect(GtestCmp Cmp, StatementMatcher Left, StatementMatcher Right)
Matcher for gtest's EXPECT comparison macros including EXPECT_EQ, EXPECT_NE, EXPECT_GE,...
Definition: GtestMatchers.cpp:196