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