Home | History | Annotate | Download | only in llvm-diff
      1 //===-- DiffConsumer.h - Difference Consumer --------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This header defines the interface to the LLVM difference Consumer
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef _LLVM_DIFFCONSUMER_H_
     15 #define _LLVM_DIFFCONSUMER_H_
     16 
     17 #include "DiffLog.h"
     18 #include "llvm/ADT/DenseMap.h"
     19 #include "llvm/ADT/SmallVector.h"
     20 #include "llvm/ADT/StringRef.h"
     21 #include "llvm/Support/Casting.h"
     22 #include "llvm/Support/raw_ostream.h"
     23 
     24 namespace llvm {
     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(Value *Left, 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(Value *L, Value *R)
     59         : L(L), R(R), Differences(false), IsFunction(isa<Function>(L)) {}
     60       Value *L;
     61       Value *R;
     62       bool Differences;
     63       bool IsFunction;
     64       DenseMap<Value*,unsigned> LNumbering;
     65       DenseMap<Value*,unsigned> RNumbering;
     66     };
     67 
     68     raw_ostream &out;
     69     SmallVector<DiffContext, 5> contexts;
     70     bool Differences;
     71     unsigned Indent;
     72 
     73     void printValue(Value *V, bool isL);
     74     void header();
     75     void indent();
     76 
     77   public:
     78     DiffConsumer()
     79       : out(errs()), Differences(false), Indent(0) {}
     80 
     81     bool hadDifferences() const;
     82     void enterContext(Value *L, Value *R);
     83     void exitContext();
     84     void log(StringRef text);
     85     void logf(const LogBuilder &Log);
     86     void logd(const DiffLogBuilder &Log);
     87   };
     88 }
     89 
     90 #endif
     91