17d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//===-- DiffLog.h - Difference Log Builder and accessories ------*- C++ -*-===//
27d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//
37d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//                     The LLVM Compiler Infrastructure
47d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//
57d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// This file is distributed under the University of Illinois Open Source
67d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// License. See LICENSE.TXT for details.
77d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//
87d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//===----------------------------------------------------------------------===//
97d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//
107d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// This header defines the interface to the LLVM difference log builder.
117d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//
127d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//===----------------------------------------------------------------------===//
137d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_TOOLS_LLVM_DIFF_DIFFLOG_H
1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_TOOLS_LLVM_DIFF_DIFFLOG_H
167d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
177d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin#include "llvm/ADT/SmallVector.h"
187d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin#include "llvm/ADT/StringRef.h"
197d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
207d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinnamespace llvm {
217d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  class Instruction;
227d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  class Value;
237d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  class Consumer;
247d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
257d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  /// Trichotomy assumption
267d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  enum DiffChange { DC_match, DC_left, DC_right };
277d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
287d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  /// A temporary-object class for building up log messages.
297d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  class LogBuilder {
30cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    Consumer *consumer;
317d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
327d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    /// The use of a stored StringRef here is okay because
337d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    /// LogBuilder should be used only as a temporary, and as a
347d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    /// temporary it will be destructed before whatever temporary
357d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    /// might be initializing this format.
367d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    StringRef Format;
377d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
387d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    SmallVector<Value*, 4> Arguments;
397d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
407d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  public:
41cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    LogBuilder(Consumer &c, StringRef Format) : consumer(&c), Format(Format) {}
42cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    LogBuilder(LogBuilder &&L)
43cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar        : consumer(L.consumer), Format(L.Format),
44cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar          Arguments(std::move(L.Arguments)) {
45cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar      L.consumer = nullptr;
46cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar    }
477d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
487d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    LogBuilder &operator<<(Value *V) {
497d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Arguments.push_back(V);
507d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      return *this;
517d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    }
527d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
537d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    ~LogBuilder();
547d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
557d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    StringRef getFormat() const;
567d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    unsigned getNumArguments() const;
577d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    Value *getArgument(unsigned I) const;
587d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  };
597d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
607d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  /// A temporary-object class for building up diff messages.
617d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  class DiffLogBuilder {
627d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    typedef std::pair<Instruction*,Instruction*> DiffRecord;
637d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    SmallVector<DiffRecord, 20> Diff;
647d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
657d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    Consumer &consumer;
667d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
677d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  public:
687d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    DiffLogBuilder(Consumer &c) : consumer(c) {}
697d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    ~DiffLogBuilder();
707d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
717d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    void addMatch(Instruction *L, Instruction *R);
727d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    // HACK: VS 2010 has a bug in the stdlib that requires this.
737d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    void addLeft(Instruction *L);
747d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    void addRight(Instruction *R);
757d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
767d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    unsigned getNumLines() const;
777d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    DiffChange getLineKind(unsigned I) const;
787d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    Instruction *getLeft(unsigned I) const;
797d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    Instruction *getRight(unsigned I) const;
807d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  };
817d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
827d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin}
837d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
847d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin#endif
85