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