DiffConsumer.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. //===-- DiffConsumer.h - Difference Consumer --------------------*- 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. // This header defines the interface to the LLVM difference Consumer
  10. //
  11. //===----------------------------------------------------------------------===//
  12. #ifndef LLVM_TOOLS_LLVM_DIFF_DIFFCONSUMER_H
  13. #define LLVM_TOOLS_LLVM_DIFF_DIFFCONSUMER_H
  14. #include "DiffLog.h"
  15. #include "llvm/ADT/DenseMap.h"
  16. #include "llvm/ADT/SmallVector.h"
  17. #include "llvm/IR/Value.h"
  18. #include "llvm/Support/Casting.h"
  19. #include "llvm/Support/raw_ostream.h"
  20. namespace llvm {
  21. class StringRef;
  22. class Module;
  23. class Value;
  24. class Function;
  25. /// The interface for consumers of difference data.
  26. class Consumer {
  27. virtual void anchor();
  28. public:
  29. /// Record that a local context has been entered. Left and
  30. /// Right are IR "containers" of some sort which are being
  31. /// considered for structural equivalence: global variables,
  32. /// functions, blocks, instructions, etc.
  33. virtual void enterContext(const Value *Left, const Value *Right) = 0;
  34. /// Record that a local context has been exited.
  35. virtual void exitContext() = 0;
  36. /// Record a difference within the current context.
  37. virtual void log(StringRef Text) = 0;
  38. /// Record a formatted difference within the current context.
  39. virtual void logf(const LogBuilder &Log) = 0;
  40. /// Record a line-by-line instruction diff.
  41. virtual void logd(const DiffLogBuilder &Log) = 0;
  42. protected:
  43. virtual ~Consumer() {}
  44. };
  45. class DiffConsumer : public Consumer {
  46. private:
  47. struct DiffContext {
  48. DiffContext(const Value *L, const Value *R)
  49. : L(L), R(R), Differences(false), IsFunction(isa<Function>(L)) {}
  50. const Value *L;
  51. const Value *R;
  52. bool Differences;
  53. bool IsFunction;
  54. DenseMap<const Value *, unsigned> LNumbering;
  55. DenseMap<const Value *, unsigned> RNumbering;
  56. };
  57. raw_ostream &out;
  58. SmallVector<DiffContext, 5> contexts;
  59. bool Differences;
  60. unsigned Indent;
  61. void printValue(const Value *V, bool isL);
  62. void header();
  63. void indent();
  64. public:
  65. DiffConsumer()
  66. : out(errs()), Differences(false), Indent(0) {}
  67. void reset();
  68. bool hadDifferences() const;
  69. void enterContext(const Value *L, const Value *R) override;
  70. void exitContext() override;
  71. void log(StringRef text) override;
  72. void logf(const LogBuilder &Log) override;
  73. void logd(const DiffLogBuilder &Log) override;
  74. };
  75. }
  76. #endif