1525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko//===- unittests/AST/StmtPrinterTest.cpp --- Statement printer tests ------===//
2525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko//
3525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko//                     The LLVM Compiler Infrastructure
4525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko//
5525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko// This file is distributed under the University of Illinois Open Source
6525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko// License. See LICENSE.TXT for details.
7525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko//
8525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko//===----------------------------------------------------------------------===//
9525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko//
10525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko// This file contains tests for Stmt::printPretty() and related methods.
11525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko//
12525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko// Search this file for WRONG to see test cases that are producing something
13525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko// completely wrong, invalid C++ or just misleading.
14525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko//
15525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko// These tests have a coding convention:
16525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko// * statements to be printed should be contained within a function named 'A'
17525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko//   unless it should have some special name (e.g., 'operator+');
18525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko// * additional helper declarations are 'Z', 'Y', 'X' and so on.
19525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko//
20525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko//===----------------------------------------------------------------------===//
21525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
22525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko#include "clang/AST/ASTContext.h"
23525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko#include "clang/ASTMatchers/ASTMatchFinder.h"
24525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko#include "clang/Tooling/Tooling.h"
25525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko#include "llvm/ADT/SmallString.h"
26525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko#include "gtest/gtest.h"
27525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
28525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenkousing namespace clang;
29525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenkousing namespace ast_matchers;
30525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenkousing namespace tooling;
31525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
32525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenkonamespace {
33525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
34525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenkovoid PrintStmt(raw_ostream &Out, const ASTContext *Context, const Stmt *S) {
35ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  assert(S != nullptr && "Expected non-null Stmt");
36525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  PrintingPolicy Policy = Context->getPrintingPolicy();
37ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  S->printPretty(Out, /*Helper*/ nullptr, Policy);
38525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko}
39525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
40525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenkoclass PrintMatch : public MatchFinder::MatchCallback {
41525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  SmallString<1024> Printed;
42525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  unsigned NumFoundStmts;
43525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
44525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenkopublic:
45525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  PrintMatch() : NumFoundStmts(0) {}
46525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
47525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  virtual void run(const MatchFinder::MatchResult &Result) {
48525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    const Stmt *S = Result.Nodes.getStmtAs<Stmt>("id");
49525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    if (!S)
50525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko      return;
51525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    NumFoundStmts++;
52525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    if (NumFoundStmts > 1)
53525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko      return;
54525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
55525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    llvm::raw_svector_ostream Out(Printed);
56525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    PrintStmt(Out, Result.Context, S);
57525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  }
58525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
59525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  StringRef getPrinted() const {
60525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    return Printed;
61525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  }
62525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
63525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  unsigned getNumFoundStmts() const {
64525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    return NumFoundStmts;
65525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  }
66525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko};
67525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
68651f13cea278ec967336033dd032faef0e9fc2ecStephen Hinestemplate <typename T>
69651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines::testing::AssertionResult
70651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesPrintedStmtMatches(StringRef Code, const std::vector<std::string> &Args,
71651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                   const T &NodeMatch, StringRef ExpectedPrinted) {
72525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
73525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  PrintMatch Printer;
74525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  MatchFinder Finder;
75525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  Finder.addMatcher(NodeMatch, &Printer);
76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FrontendActionFactory> Factory(
77651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      newFrontendActionFactory(&Finder));
78525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
79525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  if (!runToolOnCodeWithArgs(Factory->create(), Code, Args))
80651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    return testing::AssertionFailure()
81651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      << "Parsing error in \"" << Code.str() << "\"";
82525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
83525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  if (Printer.getNumFoundStmts() == 0)
84525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    return testing::AssertionFailure()
85525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko        << "Matcher didn't find any statements";
86525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
87525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  if (Printer.getNumFoundStmts() > 1)
88525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    return testing::AssertionFailure()
89525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko        << "Matcher should match only one statement "
90525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko           "(found " << Printer.getNumFoundStmts() << ")";
91525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
92525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  if (Printer.getPrinted() != ExpectedPrinted)
93525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    return ::testing::AssertionFailure()
94651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      << "Expected \"" << ExpectedPrinted.str() << "\", "
95651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines         "got \"" << Printer.getPrinted().str() << "\"";
96525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
97525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  return ::testing::AssertionSuccess();
98525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko}
99525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
100651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines::testing::AssertionResult
101651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesPrintedStmtCXX98Matches(StringRef Code, const StatementMatcher &NodeMatch,
102651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        StringRef ExpectedPrinted) {
103651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::vector<std::string> Args;
104651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Args.push_back("-std=c++98");
105651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Args.push_back("-Wno-unused-value");
106651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted);
107651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
108651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
109525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko::testing::AssertionResult PrintedStmtCXX98Matches(
110525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                                              StringRef Code,
111525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                                              StringRef ContainingFunction,
112525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                                              StringRef ExpectedPrinted) {
113525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  std::vector<std::string> Args;
114525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  Args.push_back("-std=c++98");
115525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  Args.push_back("-Wno-unused-value");
116525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  return PrintedStmtMatches(Code,
117525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                            Args,
118525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                            functionDecl(hasName(ContainingFunction),
119525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                                         has(compoundStmt(has(stmt().bind("id"))))),
120525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                            ExpectedPrinted);
121525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko}
122525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines::testing::AssertionResult
124651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesPrintedStmtCXX11Matches(StringRef Code, const StatementMatcher &NodeMatch,
125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines                        StringRef ExpectedPrinted) {
126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::vector<std::string> Args;
127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Args.push_back("-std=c++11");
128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  Args.push_back("-Wno-unused-value");
129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  return PrintedStmtMatches(Code, Args, NodeMatch, ExpectedPrinted);
130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
132525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko::testing::AssertionResult PrintedStmtMSMatches(
133525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                                              StringRef Code,
134525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                                              StringRef ContainingFunction,
135525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                                              StringRef ExpectedPrinted) {
136525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  std::vector<std::string> Args;
137ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  Args.push_back("-target");
138ef8225444452a1486bd721f3285301fe84643b00Stephen Hines  Args.push_back("i686-pc-win32");
139525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  Args.push_back("-std=c++98");
140525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  Args.push_back("-fms-extensions");
141525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  Args.push_back("-Wno-unused-value");
142525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  return PrintedStmtMatches(Code,
143525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                            Args,
144525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                            functionDecl(hasName(ContainingFunction),
145525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                                         has(compoundStmt(has(stmt().bind("id"))))),
146525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko                            ExpectedPrinted);
147525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko}
148525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
149525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko} // unnamed namespace
150525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
151525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri GribenkoTEST(StmtPrinter, TestIntegerLiteral) {
152525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  ASSERT_TRUE(PrintedStmtCXX98Matches(
153525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "void A() {"
154525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "  1, -1, 1U, 1u,"
155525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "  1L, 1l, -1L, 1UL, 1ul,"
156525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "  1LL, -1LL, 1ULL;"
157525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "}",
158525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "A",
159525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "1 , -1 , 1U , 1U , "
160525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "1L , 1L , -1L , 1UL , 1UL , "
161525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "1LL , -1LL , 1ULL"));
162525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    // Should be: with semicolon
163525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko}
164525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
165525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri GribenkoTEST(StmtPrinter, TestMSIntegerLiteral) {
166525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  ASSERT_TRUE(PrintedStmtMSMatches(
167525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "void A() {"
168525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "  1i8, -1i8, 1ui8, "
169525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "  1i16, -1i16, 1ui16, "
170525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "  1i32, -1i32, 1ui32, "
17196794f1f38119691879e99a3f4298cd442130cf2NAKAMURA Takumi    "  1i64, -1i64, 1ui64;"
172525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "}",
173525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "A",
174ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    "1i8 , -1i8 , 1Ui8 , "
175ef8225444452a1486bd721f3285301fe84643b00Stephen Hines    "1i16 , -1i16 , 1Ui16 , "
176525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "1 , -1 , 1U , "
17796794f1f38119691879e99a3f4298cd442130cf2NAKAMURA Takumi    "1LL , -1LL , 1ULL"));
178525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    // Should be: with semicolon
179525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko}
180525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko
181525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri GribenkoTEST(StmtPrinter, TestFloatingPointLiteral) {
182525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko  ASSERT_TRUE(PrintedStmtCXX98Matches(
183525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "void A() { 1.0f, -1.0f, 1.0, -1.0, 1.0l, -1.0l; }",
184525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "A",
185525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    "1.F , -1.F , 1. , -1. , 1.L , -1.L"));
186525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko    // Should be: with semicolon
187525394e6c2b0cd0ef4de47a402e82029402ff360Dmitri Gribenko}
188651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
189651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(StmtPrinter, TestCXXConversionDeclImplicit) {
190651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ASSERT_TRUE(PrintedStmtCXX98Matches(
191651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "struct A {"
192651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "operator void *();"
193651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "A operator&(A);"
194651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "};"
195651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "void bar(void *);"
196651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "void foo(A a, A b) {"
197651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "  bar(a & b);"
198651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "}",
199651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    memberCallExpr(anything()).bind("id"),
200651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "a & b"));
201651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
202651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines
203651f13cea278ec967336033dd032faef0e9fc2ecStephen HinesTEST(StmtPrinter, TestCXXConversionDeclExplicit) {
204651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  ASSERT_TRUE(PrintedStmtCXX11Matches(
205651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "struct A {"
206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "operator void *();"
207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      "A operator&(A);"
208651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "};"
209651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "void bar(void *);"
210651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "void foo(A a, A b) {"
211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "  auto x = (a & b).operator void *();"
212651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "}",
213651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    memberCallExpr(anything()).bind("id"),
214651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    "(a & b)"));
215651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    // WRONG; Should be: (a & b).operator void *()
216651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines}
217