14d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek//===- unittest/AST/MatchVerifier.h - AST unit test support ---------------===// 24d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// 34d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// The LLVM Compiler Infrastructure 44d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// 54d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// This file is distributed under the University of Illinois Open Source 64d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// License. See LICENSE.TXT for details. 74d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// 84d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek//===----------------------------------------------------------------------===// 94d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// 104d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// Provides MatchVerifier, a base class to implement gtest matchers that 114d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// verify things that can be matched on the AST. 124d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// 134d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// Also implements matchers based on MatchVerifier: 144d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// LocationVerifier and RangeVerifier to verify whether a matched node has 154d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// the expected source location or source range. 164d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek// 174d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek//===----------------------------------------------------------------------===// 184d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 194d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek#include "clang/AST/ASTContext.h" 204d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek#include "clang/ASTMatchers/ASTMatchFinder.h" 214d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek#include "clang/ASTMatchers/ASTMatchers.h" 224d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek#include "clang/Tooling/Tooling.h" 234d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek#include "gtest/gtest.h" 244d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 254d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimeknamespace clang { 264d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimeknamespace ast_matchers { 274d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 28bd9cbd22b832ce65a085801259cf2d3df77830e4Enea Zaffanellaenum Language { Lang_C, Lang_C89, Lang_CXX, Lang_CXX11, Lang_OpenCL }; 294d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 304d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek/// \brief Base class for verifying some property of nodes found by a matcher. 314d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimektemplate <typename NodeType> 324d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekclass MatchVerifier : public MatchFinder::MatchCallback { 334d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekpublic: 344d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek template <typename MatcherType> 354d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek testing::AssertionResult match(const std::string &Code, 364d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek const MatcherType &AMatcher) { 3751da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella std::vector<std::string> Args; 3851da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella return match(Code, AMatcher, Args, Lang_CXX); 394d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 404d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 414d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek template <typename MatcherType> 424d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek testing::AssertionResult match(const std::string &Code, 4351da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella const MatcherType &AMatcher, 4451da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella Language L) { 4551da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella std::vector<std::string> Args; 4651da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella return match(Code, AMatcher, Args, L); 4751da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella } 4851da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella 4951da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella template <typename MatcherType> 5051da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella testing::AssertionResult match(const std::string &Code, 5151da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella const MatcherType &AMatcher, 5251da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella std::vector<std::string>& Args, 5351da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella Language L); 544d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 554d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekprotected: 564d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek virtual void run(const MatchFinder::MatchResult &Result); 574d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek virtual void verify(const MatchFinder::MatchResult &Result, 58ff9a01000ff74a994aa3da26ea2ec732c97291b7Manuel Klimek const NodeType &Node) {} 594d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 604d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek void setFailure(const Twine &Result) { 614d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Verified = false; 624d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek VerifyResult = Result.str(); 634d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 644d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 654d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek void setSuccess() { 664d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Verified = true; 674d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 684d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 694d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekprivate: 704d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek bool Verified; 714d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek std::string VerifyResult; 724d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek}; 734d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 744d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek/// \brief Runs a matcher over some code, and returns the result of the 754d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek/// verifier for the matched node. 764d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimektemplate <typename NodeType> template <typename MatcherType> 774d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimektesting::AssertionResult MatchVerifier<NodeType>::match( 7851da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella const std::string &Code, const MatcherType &AMatcher, 7951da1426b5ec43b6ac42777b2f28f89e3d3b3dcaEnea Zaffanella std::vector<std::string>& Args, Language L) { 804d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek MatchFinder Finder; 814d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Finder.addMatcher(AMatcher.bind(""), this); 82651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines std::unique_ptr<tooling::FrontendActionFactory> Factory( 834d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek tooling::newFrontendActionFactory(&Finder)); 844d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 854d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek StringRef FileName; 864d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek switch (L) { 874d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek case Lang_C: 884d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Args.push_back("-std=c99"); 894d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek FileName = "input.c"; 904d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek break; 914d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek case Lang_C89: 924d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Args.push_back("-std=c89"); 934d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek FileName = "input.c"; 944d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek break; 954d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek case Lang_CXX: 964d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Args.push_back("-std=c++98"); 974d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek FileName = "input.cc"; 984d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek break; 99bd9cbd22b832ce65a085801259cf2d3df77830e4Enea Zaffanella case Lang_CXX11: 100bd9cbd22b832ce65a085801259cf2d3df77830e4Enea Zaffanella Args.push_back("-std=c++11"); 101bd9cbd22b832ce65a085801259cf2d3df77830e4Enea Zaffanella FileName = "input.cc"; 102bd9cbd22b832ce65a085801259cf2d3df77830e4Enea Zaffanella break; 103afbcab8d10d4208c7ad8da79e948432117d4a326Richard Smith case Lang_OpenCL: 104afbcab8d10d4208c7ad8da79e948432117d4a326Richard Smith FileName = "input.cl"; 1054d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 1064d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 1074d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek // Default to failure in case callback is never called 1084d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek setFailure("Could not find match"); 1094d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, Args, FileName)) 1104d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek return testing::AssertionFailure() << "Parsing error"; 1114d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek if (!Verified) 1124d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek return testing::AssertionFailure() << VerifyResult; 1134d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek return testing::AssertionSuccess(); 1144d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek} 1154d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 1164d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimektemplate <typename NodeType> 1174d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekvoid MatchVerifier<NodeType>::run(const MatchFinder::MatchResult &Result) { 1184d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek const NodeType *Node = Result.Nodes.getNodeAs<NodeType>(""); 1194d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek if (!Node) { 1204d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek setFailure("Matched node has wrong type"); 1214d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } else { 1224d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek // Callback has been called, default to success. 1234d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek setSuccess(); 1244d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek verify(Result, *Node); 1254d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 1264d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek} 1274d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 12800841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbournetemplate <> 12900841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourneinline void MatchVerifier<ast_type_traits::DynTypedNode>::run( 13000841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne const MatchFinder::MatchResult &Result) { 13100841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne BoundNodes::IDToNodeMap M = Result.Nodes.getMap(); 13200841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne BoundNodes::IDToNodeMap::const_iterator I = M.find(""); 13300841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne if (I == M.end()) { 13400841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne setFailure("Node was not bound"); 13500841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne } else { 13600841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne // Callback has been called, default to success. 13700841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne setSuccess(); 13800841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne verify(Result, I->second); 13900841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne } 14000841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne} 14100841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne 1424d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek/// \brief Verify whether a node has the correct source location. 1434d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek/// 1444d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek/// By default, Node.getSourceLocation() is checked. This can be changed 1454d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek/// by overriding getLocation(). 1464d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimektemplate <typename NodeType> 1474d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekclass LocationVerifier : public MatchVerifier<NodeType> { 1484d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekpublic: 1494d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek void expectLocation(unsigned Line, unsigned Column) { 1504d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek ExpectLine = Line; 1514d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek ExpectColumn = Column; 1524d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 1534d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 1544d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekprotected: 1554d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek void verify(const MatchFinder::MatchResult &Result, const NodeType &Node) { 1564d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek SourceLocation Loc = getLocation(Node); 1574d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek unsigned Line = Result.SourceManager->getSpellingLineNumber(Loc); 1584d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek unsigned Column = Result.SourceManager->getSpellingColumnNumber(Loc); 1594d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek if (Line != ExpectLine || Column != ExpectColumn) { 1604d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek std::string MsgStr; 1614d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek llvm::raw_string_ostream Msg(MsgStr); 1624d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Msg << "Expected location <" << ExpectLine << ":" << ExpectColumn 1634d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek << ">, found <"; 1644d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Loc.print(Msg, *Result.SourceManager); 1654d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Msg << '>'; 1664d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek this->setFailure(Msg.str()); 1674d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 1684d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 1694d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 1704d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek virtual SourceLocation getLocation(const NodeType &Node) { 1714d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek return Node.getLocation(); 1724d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 1734d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 1744d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekprivate: 1754d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek unsigned ExpectLine, ExpectColumn; 1764d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek}; 1774d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 1784d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek/// \brief Verify whether a node has the correct source range. 1794d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek/// 1804d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek/// By default, Node.getSourceRange() is checked. This can be changed 1814d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek/// by overriding getRange(). 1824d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimektemplate <typename NodeType> 1834d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekclass RangeVerifier : public MatchVerifier<NodeType> { 1844d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekpublic: 1854d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek void expectRange(unsigned BeginLine, unsigned BeginColumn, 1864d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek unsigned EndLine, unsigned EndColumn) { 1874d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek ExpectBeginLine = BeginLine; 1884d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek ExpectBeginColumn = BeginColumn; 1894d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek ExpectEndLine = EndLine; 1904d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek ExpectEndColumn = EndColumn; 1914d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 1924d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 1934d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekprotected: 1944d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek void verify(const MatchFinder::MatchResult &Result, const NodeType &Node) { 1954d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek SourceRange R = getRange(Node); 1964d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek SourceLocation Begin = R.getBegin(); 1974d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek SourceLocation End = R.getEnd(); 1984d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek unsigned BeginLine = Result.SourceManager->getSpellingLineNumber(Begin); 1994d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek unsigned BeginColumn = Result.SourceManager->getSpellingColumnNumber(Begin); 2004d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek unsigned EndLine = Result.SourceManager->getSpellingLineNumber(End); 2014d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek unsigned EndColumn = Result.SourceManager->getSpellingColumnNumber(End); 2024d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek if (BeginLine != ExpectBeginLine || BeginColumn != ExpectBeginColumn || 2034d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek EndLine != ExpectEndLine || EndColumn != ExpectEndColumn) { 2044d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek std::string MsgStr; 2054d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek llvm::raw_string_ostream Msg(MsgStr); 2064d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Msg << "Expected range <" << ExpectBeginLine << ":" << ExpectBeginColumn 2074d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek << '-' << ExpectEndLine << ":" << ExpectEndColumn << ">, found <"; 2084d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Begin.print(Msg, *Result.SourceManager); 2094d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Msg << '-'; 2104d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek End.print(Msg, *Result.SourceManager); 2114d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek Msg << '>'; 2124d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek this->setFailure(Msg.str()); 2134d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 2144d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 2154d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 2164d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek virtual SourceRange getRange(const NodeType &Node) { 2174d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek return Node.getSourceRange(); 2184d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek } 2194d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 2204d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimekprivate: 2214d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek unsigned ExpectBeginLine, ExpectBeginColumn, ExpectEndLine, ExpectEndColumn; 2224d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek}; 2234d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek 22400841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne/// \brief Verify whether a node's dump contains a given substring. 22500841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourneclass DumpVerifier : public MatchVerifier<ast_type_traits::DynTypedNode> { 22600841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbournepublic: 22700841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne void expectSubstring(const std::string &Str) { 22800841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne ExpectSubstring = Str; 22900841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne } 23000841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne 23100841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourneprotected: 23200841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne void verify(const MatchFinder::MatchResult &Result, 23300841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne const ast_type_traits::DynTypedNode &Node) { 23400841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne std::string DumpStr; 23500841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne llvm::raw_string_ostream Dump(DumpStr); 23600841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne Node.dump(Dump, *Result.SourceManager); 23700841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne 23800841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne if (Dump.str().find(ExpectSubstring) == std::string::npos) { 23900841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne std::string MsgStr; 24000841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne llvm::raw_string_ostream Msg(MsgStr); 24100841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne Msg << "Expected dump substring <" << ExpectSubstring << ">, found <" 24200841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne << Dump.str() << '>'; 24300841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne this->setFailure(Msg.str()); 24400841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne } 24500841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne } 24600841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne 24700841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourneprivate: 24800841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne std::string ExpectSubstring; 24900841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne}; 25000841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne 25100841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne/// \brief Verify whether a node's pretty print matches a given string. 25200841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourneclass PrintVerifier : public MatchVerifier<ast_type_traits::DynTypedNode> { 25300841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbournepublic: 25400841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne void expectString(const std::string &Str) { 25500841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne ExpectString = Str; 25600841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne } 25700841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne 25800841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourneprotected: 25900841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne void verify(const MatchFinder::MatchResult &Result, 26000841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne const ast_type_traits::DynTypedNode &Node) { 26100841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne std::string PrintStr; 26200841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne llvm::raw_string_ostream Print(PrintStr); 26300841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne Node.print(Print, Result.Context->getPrintingPolicy()); 26400841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne 26500841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne if (Print.str() != ExpectString) { 26600841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne std::string MsgStr; 26700841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne llvm::raw_string_ostream Msg(MsgStr); 26800841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne Msg << "Expected pretty print <" << ExpectString << ">, found <" 26900841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne << Print.str() << '>'; 27000841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne this->setFailure(Msg.str()); 27100841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne } 27200841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne } 27300841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne 27400841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourneprivate: 27500841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne std::string ExpectString; 27600841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne}; 27700841f5d6273d9088cfe308bacf6f5a80470c829Peter Collingbourne 2784d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek} // end namespace ast_matchers 2794d0e9f58076037d84a7da0b407c3de8f76a9d552Manuel Klimek} // end namespace clang 280