1221337Sdim//===-- DiffLog.h - Difference Log Builder and accessories ------*- C++ -*-===//
2221337Sdim//
3221337Sdim//                     The LLVM Compiler Infrastructure
4221337Sdim//
5221337Sdim// This file is distributed under the University of Illinois Open Source
6221337Sdim// License. See LICENSE.TXT for details.
7221337Sdim//
8221337Sdim//===----------------------------------------------------------------------===//
9221337Sdim//
10221337Sdim// This header defines the interface to the LLVM difference log builder.
11221337Sdim//
12221337Sdim//===----------------------------------------------------------------------===//
13221337Sdim
14280031Sdim#ifndef LLVM_TOOLS_LLVM_DIFF_DIFFLOG_H
15280031Sdim#define LLVM_TOOLS_LLVM_DIFF_DIFFLOG_H
16221337Sdim
17221337Sdim#include "llvm/ADT/SmallVector.h"
18221337Sdim#include "llvm/ADT/StringRef.h"
19221337Sdim
20221337Sdimnamespace llvm {
21221337Sdim  class Instruction;
22221337Sdim  class Value;
23221337Sdim  class Consumer;
24221337Sdim
25221337Sdim  /// Trichotomy assumption
26221337Sdim  enum DiffChange { DC_match, DC_left, DC_right };
27221337Sdim
28221337Sdim  /// A temporary-object class for building up log messages.
29221337Sdim  class LogBuilder {
30296417Sdim    Consumer *consumer;
31221337Sdim
32221337Sdim    /// The use of a stored StringRef here is okay because
33221337Sdim    /// LogBuilder should be used only as a temporary, and as a
34221337Sdim    /// temporary it will be destructed before whatever temporary
35221337Sdim    /// might be initializing this format.
36221337Sdim    StringRef Format;
37221337Sdim
38221337Sdim    SmallVector<Value*, 4> Arguments;
39221337Sdim
40221337Sdim  public:
41296417Sdim    LogBuilder(Consumer &c, StringRef Format) : consumer(&c), Format(Format) {}
42296417Sdim    LogBuilder(LogBuilder &&L)
43296417Sdim        : consumer(L.consumer), Format(L.Format),
44296417Sdim          Arguments(std::move(L.Arguments)) {
45296417Sdim      L.consumer = nullptr;
46296417Sdim    }
47221337Sdim
48221337Sdim    LogBuilder &operator<<(Value *V) {
49221337Sdim      Arguments.push_back(V);
50221337Sdim      return *this;
51221337Sdim    }
52221337Sdim
53221337Sdim    ~LogBuilder();
54221337Sdim
55221337Sdim    StringRef getFormat() const;
56221337Sdim    unsigned getNumArguments() const;
57221337Sdim    Value *getArgument(unsigned I) const;
58221337Sdim  };
59221337Sdim
60221337Sdim  /// A temporary-object class for building up diff messages.
61221337Sdim  class DiffLogBuilder {
62221337Sdim    typedef std::pair<Instruction*,Instruction*> DiffRecord;
63221337Sdim    SmallVector<DiffRecord, 20> Diff;
64221337Sdim
65221337Sdim    Consumer &consumer;
66221337Sdim
67221337Sdim  public:
68221337Sdim    DiffLogBuilder(Consumer &c) : consumer(c) {}
69221337Sdim    ~DiffLogBuilder();
70221337Sdim
71221337Sdim    void addMatch(Instruction *L, Instruction *R);
72221337Sdim    // HACK: VS 2010 has a bug in the stdlib that requires this.
73221337Sdim    void addLeft(Instruction *L);
74221337Sdim    void addRight(Instruction *R);
75221337Sdim
76221337Sdim    unsigned getNumLines() const;
77221337Sdim    DiffChange getLineKind(unsigned I) const;
78221337Sdim    Instruction *getLeft(unsigned I) const;
79221337Sdim    Instruction *getRight(unsigned I) const;
80221337Sdim  };
81221337Sdim
82221337Sdim}
83221337Sdim
84221337Sdim#endif
85