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