Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===--- MatchConsumer.h - MatchConsumer abstraction ------------*- C++ -*-===//
  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. /// \file This file defines the *MatchConsumer* abstraction: a computation over
  10. /// match results, specifically the `ast_matchers::MatchFinder::MatchResult`
  11. /// class.
  12. ///
  13. //===----------------------------------------------------------------------===//
  14.  
  15. #ifndef LLVM_CLANG_TOOLING_TRANSFORMER_MATCHCONSUMER_H
  16. #define LLVM_CLANG_TOOLING_TRANSFORMER_MATCHCONSUMER_H
  17.  
  18. #include "clang/AST/ASTTypeTraits.h"
  19. #include "clang/ASTMatchers/ASTMatchFinder.h"
  20. #include "llvm/ADT/StringRef.h"
  21. #include "llvm/Support/Errc.h"
  22. #include "llvm/Support/Error.h"
  23.  
  24. namespace clang {
  25. namespace transformer {
  26. /// A failable computation over nodes bound by AST matchers.
  27. ///
  28. /// The computation should report any errors though its return value (rather
  29. /// than terminating the program) to enable usage in interactive scenarios like
  30. /// clang-query.
  31. ///
  32. /// This is a central abstraction of the Transformer framework.
  33. template <typename T>
  34. using MatchConsumer =
  35.     std::function<Expected<T>(const ast_matchers::MatchFinder::MatchResult &)>;
  36.  
  37. /// Creates an error that signals that a `MatchConsumer` expected a certain node
  38. /// to be bound by AST matchers, but it was not actually bound.
  39. inline llvm::Error notBoundError(llvm::StringRef Id) {
  40.   return llvm::make_error<llvm::StringError>(llvm::errc::invalid_argument,
  41.                                              "Id not bound: " + Id);
  42. }
  43.  
  44. /// Chooses between the two consumers, based on whether \p ID is bound in the
  45. /// match.
  46. template <typename T>
  47. MatchConsumer<T> ifBound(std::string ID, MatchConsumer<T> TrueC,
  48.                          MatchConsumer<T> FalseC) {
  49.   return [=](const ast_matchers::MatchFinder::MatchResult &Result) {
  50.     auto &Map = Result.Nodes.getMap();
  51.     return (Map.find(ID) != Map.end() ? TrueC : FalseC)(Result);
  52.   };
  53. }
  54.  
  55. /// A failable computation over nodes bound by AST matchers, with (limited)
  56. /// reflection via the `toString` method.
  57. ///
  58. /// The computation should report any errors though its return value (rather
  59. /// than terminating the program) to enable usage in interactive scenarios like
  60. /// clang-query.
  61. ///
  62. /// This is a central abstraction of the Transformer framework. It is a
  63. /// generalization of `MatchConsumer` and intended to replace it.
  64. template <typename T> class MatchComputation {
  65. public:
  66.   virtual ~MatchComputation() = default;
  67.  
  68.   /// Evaluates the computation and (potentially) updates the accumulator \c
  69.   /// Result.  \c Result is undefined in the case of an error. `Result` is an
  70.   /// out parameter to optimize case where the computation involves composing
  71.   /// the result of sub-computation evaluations.
  72.   virtual llvm::Error eval(const ast_matchers::MatchFinder::MatchResult &Match,
  73.                            T *Result) const = 0;
  74.  
  75.   /// Convenience version of `eval`, for the case where the computation is being
  76.   /// evaluated on its own.
  77.   llvm::Expected<T> eval(const ast_matchers::MatchFinder::MatchResult &R) const;
  78.  
  79.   /// Constructs a string representation of the computation, for informational
  80.   /// purposes. The representation must be deterministic, but is not required to
  81.   /// be unique.
  82.   virtual std::string toString() const = 0;
  83.  
  84. protected:
  85.   MatchComputation() = default;
  86.  
  87.   // Since this is an abstract class, copying/assigning only make sense for
  88.   // derived classes implementing `clone()`.
  89.   MatchComputation(const MatchComputation &) = default;
  90.   MatchComputation &operator=(const MatchComputation &) = default;
  91. };
  92.  
  93. template <typename T>
  94. llvm::Expected<T> MatchComputation<T>::eval(
  95.     const ast_matchers::MatchFinder::MatchResult &R) const {
  96.   T Output;
  97.   if (auto Err = eval(R, &Output))
  98.     return std::move(Err);
  99.   return Output;
  100. }
  101. } // namespace transformer
  102. } // namespace clang
  103. #endif // LLVM_CLANG_TOOLING_TRANSFORMER_MATCHCONSUMER_H
  104.