Clang Project

clang_source_code/unittests/AST/ASTPrint.h
1//===- unittests/AST/ASTPrint.h ------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Helpers to simplify testing of printing of AST constructs provided in the/
10// form of the source code.
11//
12//===----------------------------------------------------------------------===//
13
14#include "clang/AST/ASTContext.h"
15#include "clang/ASTMatchers/ASTMatchFinder.h"
16#include "clang/Tooling/Tooling.h"
17#include "llvm/ADT/SmallString.h"
18#include "gtest/gtest.h"
19
20namespace clang {
21
22using PolicyAdjusterType =
23    Optional<llvm::function_ref<void(PrintingPolicy &Policy)>>;
24
25static void PrintStmt(raw_ostream &Outconst ASTContext *Context,
26                      const Stmt *S, PolicyAdjusterType PolicyAdjuster) {
27   (0) . __assert_fail ("S != nullptr && \"Expected non-null Stmt\"", "/home/seafit/code_projects/clang_source/clang/unittests/AST/ASTPrint.h", 27, __PRETTY_FUNCTION__))" file_link="../../../include/assert.h.html#88" macro="true">assert(S != nullptr && "Expected non-null Stmt");
28  PrintingPolicy Policy = Context->getPrintingPolicy();
29  if (PolicyAdjuster)
30    (*PolicyAdjuster)(Policy);
31  S->printPretty(Out/*Helper*/ nullptrPolicy);
32}
33
34class PrintMatch : public ast_matchers::MatchFinder::MatchCallback {
35  SmallString<1024Printed;
36  unsigned NumFoundStmts;
37  PolicyAdjusterType PolicyAdjuster;
38
39public:
40  PrintMatch(PolicyAdjusterType PolicyAdjuster)
41      : NumFoundStmts(0), PolicyAdjuster(PolicyAdjuster) {}
42
43  void run(const ast_matchers::MatchFinder::MatchResult &Result) override {
44    const Stmt *S = Result.Nodes.getNodeAs<Stmt>("id");
45    if (!S)
46      return;
47    NumFoundStmts++;
48    if (NumFoundStmts > 1)
49      return;
50
51    llvm::raw_svector_ostream Out(Printed);
52    PrintStmt(Out, Result.Context, S, PolicyAdjuster);
53  }
54
55  StringRef getPrinted() const { return Printed; }
56
57  unsigned getNumFoundStmts() const { return NumFoundStmts; }
58};
59
60template <typename T>
61::testing::AssertionResult
62PrintedStmtMatches(StringRef Code, const std::vector<std::string> &Args,
63                   const T &NodeMatch, StringRef ExpectedPrinted,
64                   PolicyAdjusterType PolicyAdjuster = None) {
65
66  PrintMatch Printer(PolicyAdjuster);
67  ast_matchers::MatchFinder Finder;
68  Finder.addMatcher(NodeMatch, &Printer);
69  std::unique_ptr<tooling::FrontendActionFactoryFactory(
70      tooling::newFrontendActionFactory(&Finder));
71
72  if (!tooling::runToolOnCodeWithArgs(Factory->create(), Code, Args))
73    return testing::AssertionFailure()
74           << "Parsing error in \"" << Code.str() << "\"";
75
76  if (Printer.getNumFoundStmts() == 0)
77    return testing::AssertionFailure() << "Matcher didn't find any statements";
78
79  if (Printer.getNumFoundStmts() > 1)
80    return testing::AssertionFailure()
81           << "Matcher should match only one statement (found "
82           << Printer.getNumFoundStmts() << ")";
83
84  if (Printer.getPrinted() != ExpectedPrinted)
85    return ::testing::AssertionFailure()
86           << "Expected \"" << ExpectedPrinted.str() << "\", got \""
87           << Printer.getPrinted().str() << "\"";
88
89  return ::testing::AssertionSuccess();
90}
91
92// namespace clang
93
clang::PrintMatch::Printed
clang::PrintMatch::NumFoundStmts
clang::PrintMatch::PolicyAdjuster
clang::PrintMatch::run
clang::PrintMatch::getPrinted
clang::PrintMatch::getNumFoundStmts