1*349cc55cSDimitry Andric //===-- DiffLog.h - Difference Log Builder and accessories ------*- C++ -*-===//
2*349cc55cSDimitry Andric //
3*349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*349cc55cSDimitry Andric //
7*349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8*349cc55cSDimitry Andric //
9*349cc55cSDimitry Andric // This header defines the interface to the LLVM difference log builder.
10*349cc55cSDimitry Andric //
11*349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
12*349cc55cSDimitry Andric 
13*349cc55cSDimitry Andric #ifndef LLVM_TOOLS_LLVM_DIFF_DIFFLOG_H
14*349cc55cSDimitry Andric #define LLVM_TOOLS_LLVM_DIFF_DIFFLOG_H
15*349cc55cSDimitry Andric 
16*349cc55cSDimitry Andric #include "llvm/ADT/SmallVector.h"
17*349cc55cSDimitry Andric #include "llvm/ADT/StringRef.h"
18*349cc55cSDimitry Andric 
19*349cc55cSDimitry Andric namespace llvm {
20*349cc55cSDimitry Andric   class Instruction;
21*349cc55cSDimitry Andric   class Value;
22*349cc55cSDimitry Andric   class Consumer;
23*349cc55cSDimitry Andric 
24*349cc55cSDimitry Andric   /// Trichotomy assumption
25*349cc55cSDimitry Andric   enum DiffChange { DC_match, DC_left, DC_right };
26*349cc55cSDimitry Andric 
27*349cc55cSDimitry Andric   /// A temporary-object class for building up log messages.
28*349cc55cSDimitry Andric   class LogBuilder {
29*349cc55cSDimitry Andric     Consumer *consumer;
30*349cc55cSDimitry Andric 
31*349cc55cSDimitry Andric     /// The use of a stored StringRef here is okay because
32*349cc55cSDimitry Andric     /// LogBuilder should be used only as a temporary, and as a
33*349cc55cSDimitry Andric     /// temporary it will be destructed before whatever temporary
34*349cc55cSDimitry Andric     /// might be initializing this format.
35*349cc55cSDimitry Andric     StringRef Format;
36*349cc55cSDimitry Andric 
37*349cc55cSDimitry Andric     SmallVector<const Value *, 4> Arguments;
38*349cc55cSDimitry Andric 
39*349cc55cSDimitry Andric   public:
LogBuilder(Consumer & c,StringRef Format)40*349cc55cSDimitry Andric     LogBuilder(Consumer &c, StringRef Format) : consumer(&c), Format(Format) {}
LogBuilder(LogBuilder && L)41*349cc55cSDimitry Andric     LogBuilder(LogBuilder &&L)
42*349cc55cSDimitry Andric         : consumer(L.consumer), Format(L.Format),
43*349cc55cSDimitry Andric           Arguments(std::move(L.Arguments)) {
44*349cc55cSDimitry Andric       L.consumer = nullptr;
45*349cc55cSDimitry Andric     }
46*349cc55cSDimitry Andric 
47*349cc55cSDimitry Andric     LogBuilder &operator<<(const Value *V) {
48*349cc55cSDimitry Andric       Arguments.push_back(V);
49*349cc55cSDimitry Andric       return *this;
50*349cc55cSDimitry Andric     }
51*349cc55cSDimitry Andric 
52*349cc55cSDimitry Andric     ~LogBuilder();
53*349cc55cSDimitry Andric 
54*349cc55cSDimitry Andric     StringRef getFormat() const;
55*349cc55cSDimitry Andric     unsigned getNumArguments() const;
56*349cc55cSDimitry Andric     const Value *getArgument(unsigned I) const;
57*349cc55cSDimitry Andric   };
58*349cc55cSDimitry Andric 
59*349cc55cSDimitry Andric   /// A temporary-object class for building up diff messages.
60*349cc55cSDimitry Andric   class DiffLogBuilder {
61*349cc55cSDimitry Andric     typedef std::pair<const Instruction *, const Instruction *> DiffRecord;
62*349cc55cSDimitry Andric     SmallVector<DiffRecord, 20> Diff;
63*349cc55cSDimitry Andric 
64*349cc55cSDimitry Andric     Consumer &consumer;
65*349cc55cSDimitry Andric 
66*349cc55cSDimitry Andric   public:
DiffLogBuilder(Consumer & c)67*349cc55cSDimitry Andric     DiffLogBuilder(Consumer &c) : consumer(c) {}
68*349cc55cSDimitry Andric     ~DiffLogBuilder();
69*349cc55cSDimitry Andric 
70*349cc55cSDimitry Andric     void addMatch(const Instruction *L, const Instruction *R);
71*349cc55cSDimitry Andric     // HACK: VS 2010 has a bug in the stdlib that requires this.
72*349cc55cSDimitry Andric     void addLeft(const Instruction *L);
73*349cc55cSDimitry Andric     void addRight(const Instruction *R);
74*349cc55cSDimitry Andric 
75*349cc55cSDimitry Andric     unsigned getNumLines() const;
76*349cc55cSDimitry Andric     DiffChange getLineKind(unsigned I) const;
77*349cc55cSDimitry Andric     const Instruction *getLeft(unsigned I) const;
78*349cc55cSDimitry Andric     const Instruction *getRight(unsigned I) const;
79*349cc55cSDimitry Andric   };
80*349cc55cSDimitry Andric 
81*349cc55cSDimitry Andric }
82*349cc55cSDimitry Andric 
83*349cc55cSDimitry Andric #endif
84