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