14da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===- unittest/Tooling/ASTMatchersTest.h - Matcher tests helpers ------===//
24da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
34da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//                     The LLVM Compiler Infrastructure
44da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
54da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// This file is distributed under the University of Illinois Open Source
64da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// License. See LICENSE.TXT for details.
74da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
84da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===----------------------------------------------------------------------===//
94da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
10176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#ifndef LLVM_CLANG_UNITTESTS_ASTMATCHERS_ASTMATCHERSTEST_H
11176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines#define LLVM_CLANG_UNITTESTS_ASTMATCHERS_ASTMATCHERSTEST_H
124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include "clang/ASTMatchers/ASTMatchFinder.h"
1451fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne#include "clang/Frontend/ASTUnit.h"
154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include "clang/Tooling/Tooling.h"
164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#include "gtest/gtest.h"
174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimeknamespace clang {
194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimeknamespace ast_matchers {
204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2151fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourneusing clang::tooling::buildASTFromCodeWithArgs;
224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekusing clang::tooling::newFrontendActionFactory;
2350f88b99c60c2ed31b339cd8bd484766cc9e916bNico Weberusing clang::tooling::runToolOnCodeWithArgs;
244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekusing clang::tooling::FrontendActionFactory;
250e2c34f92f00628d48968dfea096d36381f494cbStephen Hinesusing clang::tooling::FileContentMappings;
264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass BoundNodesCallback {
284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic:
294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  virtual ~BoundNodesCallback() {}
30452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper  virtual bool run(const BoundNodes *BoundNodes) = 0;
31452abbc76b775169dc01c359e94a7f666ebc8692Daniel Jasper  virtual bool run(const BoundNodes *BoundNodes, ASTContext *Context) = 0;
32d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne  virtual void onEndOfTranslationUnit() {}
334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek};
344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// If 'FindResultVerifier' is not NULL, sets *Verified to the result of
364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// running 'FindResultVerifier' with the bound nodes as argument.
374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// If 'FindResultVerifier' is NULL, sets *Verified to true when Run is called.
384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekclass VerifyMatch : public MatchFinder::MatchCallback {
394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekpublic:
404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  VerifyMatch(std::unique_ptr<BoundNodesCallback> FindResultVerifier, bool *Verified)
414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      : Verified(Verified), FindResultReviewer(std::move(FindResultVerifier)) {}
424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
4358878f85ab89b13e9eea4af3ccf055e42c557bc8Pirama Arumuga Nainar  void run(const MatchFinder::MatchResult &Result) override {
44c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    if (FindResultReviewer != nullptr) {
4511c98771ba5d7fb1ec5707f9e1c77a6cf65bbc59Daniel Jasper      *Verified |= FindResultReviewer->run(&Result.Nodes, Result.Context);
464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    } else {
474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      *Verified = true;
484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    }
494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }
504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  void onEndOfTranslationUnit() override {
52d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne    if (FindResultReviewer)
53d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne      FindResultReviewer->onEndOfTranslationUnit();
54d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne  }
55d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne
564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimekprivate:
574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  bool *const Verified;
584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const std::unique_ptr<BoundNodesCallback> FindResultReviewer;
594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek};
604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T>
620e2c34f92f00628d48968dfea096d36381f494cbStephen Hinestesting::AssertionResult matchesConditionally(
630e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    const std::string &Code, const T &AMatcher, bool ExpectMatch,
640e2c34f92f00628d48968dfea096d36381f494cbStephen Hines    llvm::StringRef CompileArg,
653ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    const FileContentMappings &VirtualMappedFiles = FileContentMappings(),
663ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    const std::string &Filename = "input.cc") {
67d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne  bool Found = false, DynamicFound = false;
684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  MatchFinder Finder;
69c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  VerifyMatch VerifyFound(nullptr, &Found);
706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Finder.addMatcher(AMatcher, &VerifyFound);
71c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  VerifyMatch VerifyDynamicFound(nullptr, &DynamicFound);
726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  if (!Finder.addDynamicMatcher(AMatcher, &VerifyDynamicFound))
73d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne    return testing::AssertionFailure() << "Could not add dynamic matcher";
74651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FrontendActionFactory> Factory(
75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      newFrontendActionFactory(&Finder));
764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Some tests need rtti/exceptions on.  Use an unknown-unknown triple so we
774967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // don't instantiate the full system toolchain.  On Linux, instantiating the
784967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // toolchain involves stat'ing large portions of /usr/lib, and this slows down
794967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // not only this test, but all other tests, via contention in the kernel.
804967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  //
814967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // FIXME: This is a hack to work around the fact that there's no way to do the
824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // equivalent of runToolOnCodeWithArgs without instantiating a full Driver.
834967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // We should consider having a function, at least for tests, that invokes cc1.
844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  std::vector<std::string> Args = {CompileArg, "-frtti", "-fexceptions",
854967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   "-target", "i386-unknown-unknown"};
864967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  if (!runToolOnCodeWithArgs(
874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          Factory->create(), Code, Args, Filename, "clang-tool",
884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar          std::make_shared<PCHContainerOperations>(), VirtualMappedFiles)) {
894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }
91d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne  if (Found != DynamicFound) {
92d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne    return testing::AssertionFailure() << "Dynamic match result ("
93d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne                                       << DynamicFound
94d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne                                       << ") does not match static result ("
95d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne                                       << Found << ")";
96d2bd58907f77e1c1b68a6fa8fc72e1c5b057a5b1Peter Collingbourne  }
974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  if (!Found && ExpectMatch) {
984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    return testing::AssertionFailure()
994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      << "Could not find match in \"" << Code << "\"";
1004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  } else if (Found && !ExpectMatch) {
1014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    return testing::AssertionFailure()
1024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      << "Found unexpected match in \"" << Code << "\"";
1034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }
1044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  return testing::AssertionSuccess();
1054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
1064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T>
1084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektesting::AssertionResult matches(const std::string &Code, const T &AMatcher) {
10931f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  return matchesConditionally(Code, AMatcher, true, "-std=c++11");
1104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
1114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T>
1134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektesting::AssertionResult notMatches(const std::string &Code,
1144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                                    const T &AMatcher) {
11531f7c08a0d2b140bf31a08894d1948649de53c15Daniel Jasper  return matchesConditionally(Code, AMatcher, false, "-std=c++11");
1164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
1174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1183ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainartemplate <typename T>
1193ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainartesting::AssertionResult matchesObjC(const std::string &Code,
1203ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                     const T &AMatcher) {
1213ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  return matchesConditionally(
1223ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    Code, AMatcher, true,
1233ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    "", FileContentMappings(), "input.m");
1243ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
1253ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
1263ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainartemplate <typename T>
12787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainartesting::AssertionResult matchesC(const std::string &Code, const T &AMatcher) {
12887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return matchesConditionally(Code, AMatcher, true, "", FileContentMappings(),
12987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                              "input.c");
13087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
13187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
13287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainartemplate <typename T>
1334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainartesting::AssertionResult matchesC99(const std::string &Code,
1344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                    const T &AMatcher) {
1354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  return matchesConditionally(Code, AMatcher, true, "-std=c99",
1364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                              FileContentMappings(), "input.c");
1374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar}
1384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
1394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainartemplate <typename T>
14087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainartesting::AssertionResult notMatchesC(const std::string &Code,
14187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                                     const T &AMatcher) {
14287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  return matchesConditionally(Code, AMatcher, false, "", FileContentMappings(),
14387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar                              "input.c");
14487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar}
14587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
14687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainartemplate <typename T>
1473ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainartesting::AssertionResult notMatchesObjC(const std::string &Code,
1483ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar                                     const T &AMatcher) {
1493ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar  return matchesConditionally(
1503ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    Code, AMatcher, false,
1513ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar    "", FileContentMappings(), "input.m");
1523ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar}
1533ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
1543ea9e33ea25e0c2b12db56418ba3f994eb662c04Pirama Arumuga Nainar
155176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// Function based on matchesConditionally with "-x cuda" argument added and
156176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines// small CUDA header prepended to the code string.
157176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestemplate <typename T>
158176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestesting::AssertionResult matchesConditionallyWithCuda(
159176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    const std::string &Code, const T &AMatcher, bool ExpectMatch,
160176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    llvm::StringRef CompileArg) {
161176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  const std::string CudaHeader =
162176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "typedef unsigned int size_t;\n"
163176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "#define __constant__ __attribute__((constant))\n"
164176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "#define __device__ __attribute__((device))\n"
165176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "#define __global__ __attribute__((global))\n"
166176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "#define __host__ __attribute__((host))\n"
167176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "#define __shared__ __attribute__((shared))\n"
168176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "struct dim3 {"
169176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "  unsigned x, y, z;"
170176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "  __host__ __device__ dim3(unsigned x, unsigned y = 1, unsigned z = 1)"
171176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "      : x(x), y(y), z(z) {}"
172176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "};"
173176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "typedef struct cudaStream *cudaStream_t;"
174176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "int cudaConfigureCall(dim3 gridSize, dim3 blockSize,"
175176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "                      size_t sharedSize = 0,"
176176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      "                      cudaStream_t stream = 0);";
177176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
178176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  bool Found = false, DynamicFound = false;
179176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  MatchFinder Finder;
180176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  VerifyMatch VerifyFound(nullptr, &Found);
181176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  Finder.addMatcher(AMatcher, &VerifyFound);
182176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  VerifyMatch VerifyDynamicFound(nullptr, &DynamicFound);
183176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (!Finder.addDynamicMatcher(AMatcher, &VerifyDynamicFound))
184176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return testing::AssertionFailure() << "Could not add dynamic matcher";
185176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  std::unique_ptr<FrontendActionFactory> Factory(
186176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      newFrontendActionFactory(&Finder));
1874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Some tests use typeof, which is a gnu extension.  Using an explicit
1884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // unknown-unknown triple is good for a large speedup, because it lets us
1894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // avoid constructing a full system triple.
1904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  std::vector<std::string> Args = {
1914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      "-xcuda",  "-fno-ms-extensions",      "--cuda-host-only", "-nocudainc",
1924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      "-target", "nvptx64-unknown-unknown", CompileArg};
193176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (!runToolOnCodeWithArgs(Factory->create(),
194176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                             CudaHeader + Code, Args)) {
195176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
196176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
197176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (Found != DynamicFound) {
198176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return testing::AssertionFailure() << "Dynamic match result ("
199176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                       << DynamicFound
200176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                       << ") does not match static result ("
201176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                       << Found << ")";
202176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
203176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  if (!Found && ExpectMatch) {
204176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return testing::AssertionFailure()
205176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      << "Could not find match in \"" << Code << "\"";
206176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  } else if (Found && !ExpectMatch) {
207176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines    return testing::AssertionFailure()
208176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines      << "Found unexpected match in \"" << Code << "\"";
209176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  }
210176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return testing::AssertionSuccess();
211176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
212176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
213176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestemplate <typename T>
214176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestesting::AssertionResult matchesWithCuda(const std::string &Code,
215176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                         const T &AMatcher) {
216176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return matchesConditionallyWithCuda(Code, AMatcher, true, "-std=c++11");
217176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
218176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
219176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestemplate <typename T>
220176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hinestesting::AssertionResult notMatchesWithCuda(const std::string &Code,
221176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines                                    const T &AMatcher) {
222176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines  return matchesConditionallyWithCuda(Code, AMatcher, false, "-std=c++11");
223176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines}
224176edba5311f6eff0cad2631449885ddf4fbc9eaStephen Hines
2254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T>
2264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektesting::AssertionResult
2274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekmatchAndVerifyResultConditionally(const std::string &Code, const T &AMatcher,
2284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                  std::unique_ptr<BoundNodesCallback> FindResultVerifier,
2294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek                                  bool ExpectResult) {
2304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  bool VerifiedResult = false;
2314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  MatchFinder Finder;
2324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  VerifyMatch VerifyVerifiedResult(std::move(FindResultVerifier), &VerifiedResult);
2336bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines  Finder.addMatcher(AMatcher, &VerifyVerifiedResult);
234651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<FrontendActionFactory> Factory(
235651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines      newFrontendActionFactory(&Finder));
2364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Some tests use typeof, which is a gnu extension.  Using an explicit
2374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // unknown-unknown triple is good for a large speedup, because it lets us
2384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // avoid constructing a full system triple.
2394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  std::vector<std::string> Args = {"-std=gnu++98", "-target",
2404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                                   "i386-unknown-unknown"};
24150f88b99c60c2ed31b339cd8bd484766cc9e916bNico Weber  if (!runToolOnCodeWithArgs(Factory->create(), Code, Args)) {
2424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    return testing::AssertionFailure() << "Parsing error in \"" << Code << "\"";
2434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }
2444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  if (!VerifiedResult && ExpectResult) {
2454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    return testing::AssertionFailure()
2464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      << "Could not verify result in \"" << Code << "\"";
2474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  } else if (VerifiedResult && !ExpectResult) {
2484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    return testing::AssertionFailure()
2494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      << "Verified unexpected result in \"" << Code << "\"";
2504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }
25151fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne
25251fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  VerifiedResult = false;
253651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines  std::unique_ptr<ASTUnit> AST(buildASTFromCodeWithArgs(Code, Args));
25451fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  if (!AST.get())
25551fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne    return testing::AssertionFailure() << "Parsing error in \"" << Code
25651fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne                                       << "\" while building AST";
25751fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  Finder.matchAST(AST->getASTContext());
25851fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  if (!VerifiedResult && ExpectResult) {
25951fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne    return testing::AssertionFailure()
26051fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne      << "Could not verify result in \"" << Code << "\" with AST";
26151fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  } else if (VerifiedResult && !ExpectResult) {
26251fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne    return testing::AssertionFailure()
26351fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne      << "Verified unexpected result in \"" << Code << "\" with AST";
26451fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne  }
26551fcdf84a794a01601c7c78889efa21fbfc1db08Peter Collingbourne
2664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  return testing::AssertionSuccess();
2674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
2684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// FIXME: Find better names for these functions (or document what they
2704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// do more precisely).
2714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T>
2724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektesting::AssertionResult
2734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekmatchAndVerifyResultTrue(const std::string &Code, const T &AMatcher,
2744967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                         std::unique_ptr<BoundNodesCallback> FindResultVerifier) {
2754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  return matchAndVerifyResultConditionally(
2764967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Code, AMatcher, std::move(FindResultVerifier), true);
2774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
2784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektemplate <typename T>
2804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimektesting::AssertionResult
2814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel KlimekmatchAndVerifyResultFalse(const std::string &Code, const T &AMatcher,
2824967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                          std::unique_ptr<BoundNodesCallback> FindResultVerifier) {
2834da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  return matchAndVerifyResultConditionally(
2844967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      Code, AMatcher, std::move(FindResultVerifier), false);
2854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek}
2864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2874967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// Implements a run method that returns whether BoundNodes contains a
2884967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// Decl bound to Id that can be dynamically cast to T.
2894967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar// Optionally checks that the check succeeded a specific number of times.
2904967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainartemplate <typename T>
2914967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarclass VerifyIdIsBoundTo : public BoundNodesCallback {
2924967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarpublic:
2934967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create an object that checks that a node of type \c T was bound to \c Id.
2944967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Does not check for a certain number of matches.
2954967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  explicit VerifyIdIsBoundTo(llvm::StringRef Id)
2964967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    : Id(Id), ExpectedCount(-1), Count(0) {}
2974967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
2984967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create an object that checks that a node of type \c T was bound to \c Id.
2994967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Checks that there were exactly \c ExpectedCount matches.
3004967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  VerifyIdIsBoundTo(llvm::StringRef Id, int ExpectedCount)
3014967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    : Id(Id), ExpectedCount(ExpectedCount), Count(0) {}
3024967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3034967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Create an object that checks that a node of type \c T was bound to \c Id.
3044967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Checks that there was exactly one match with the name \c ExpectedName.
3054967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  // Note that \c T must be a NamedDecl for this to work.
3064967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  VerifyIdIsBoundTo(llvm::StringRef Id, llvm::StringRef ExpectedName,
3074967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar                    int ExpectedCount = 1)
3084967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    : Id(Id), ExpectedCount(ExpectedCount), Count(0),
3094967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ExpectedName(ExpectedName) {}
3104967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3114967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  void onEndOfTranslationUnit() override {
3124967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (ExpectedCount != -1)
3134967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      EXPECT_EQ(ExpectedCount, Count);
3144967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (!ExpectedName.empty())
3154967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      EXPECT_EQ(ExpectedName, Name);
3164967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Count = 0;
3174967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    Name.clear();
3184967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
3194967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3204967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  ~VerifyIdIsBoundTo() override {
3214967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    EXPECT_EQ(0, Count);
3224967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    EXPECT_EQ("", Name);
3234967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
3244967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3254967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool run(const BoundNodes *Nodes) override {
3264967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    const BoundNodes::IDToNodeMap &M = Nodes->getMap();
3274967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    if (Nodes->getNodeAs<T>(Id)) {
3284967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      ++Count;
3294967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (const NamedDecl *Named = Nodes->getNodeAs<NamedDecl>(Id)) {
3304967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Name = Named->getNameAsString();
3314967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      } else if (const NestedNameSpecifier *NNS =
3324967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        Nodes->getNodeAs<NestedNameSpecifier>(Id)) {
3334967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        llvm::raw_string_ostream OS(Name);
3344967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        NNS->print(OS, PrintingPolicy(LangOptions()));
3354967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      }
3364967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      BoundNodes::IDToNodeMap::const_iterator I = M.find(Id);
3374967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      EXPECT_NE(M.end(), I);
3384967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      if (I != M.end())
3394967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar        EXPECT_EQ(Nodes->getNodeAs<T>(Id), I->second.get<T>());
3404967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      return true;
3414967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    }
3424967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    EXPECT_TRUE(M.count(Id) == 0 ||
3434967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar      M.find(Id)->second.template get<T>() == nullptr);
3444967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return false;
3454967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
3464967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3474967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  bool run(const BoundNodes *Nodes, ASTContext *Context) override {
3484967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar    return run(Nodes);
3494967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  }
3504967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3514967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainarprivate:
3524967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const std::string Id;
3534967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const int ExpectedCount;
3544967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  int Count;
3554967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  const std::string ExpectedName;
3564967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar  std::string Name;
3574967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar};
3584967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar
3594967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} // namespace ast_matchers
3604967a710c84587c654b56c828382219c3937dacbPirama Arumuga Nainar} // namespace clang
3614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
3624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#endif  // LLVM_CLANG_UNITTESTS_AST_MATCHERS_AST_MATCHERS_TEST_H
363