// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_IL_PRINTER_H_
#define RUNTIME_VM_IL_PRINTER_H_

#include "vm/flow_graph.h"
#include "vm/intermediate_language.h"

namespace dart {

class BufferFormatter : public ValueObject {
 public:
  BufferFormatter(char* buffer, intptr_t size)
      : position_(0), buffer_(buffer), size_(size) {}

  void VPrint(const char* format, va_list args);
  void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);

 private:
  intptr_t position_;
  char* buffer_;
  const intptr_t size_;

  DISALLOW_COPY_AND_ASSIGN(BufferFormatter);
};


class ParsedFunction;


// Graph printing.
class FlowGraphPrinter : public ValueObject {
 public:
  static const intptr_t kPrintAll = -1;

  explicit FlowGraphPrinter(const FlowGraph& flow_graph,
                            bool print_locations = false)
      : function_(flow_graph.function()),
        block_order_(flow_graph.reverse_postorder()),
        print_locations_(print_locations) {}

  // Print the instructions in a block terminated by newlines.  Add "goto N"
  // to the end of the block if it ends with an unconditional jump to
  // another block and that block is not next in reverse postorder.
  void PrintBlocks();
  void PrintInstruction(Instruction* instr);
  static void PrintOneInstruction(Instruction* instr, bool print_locations);
  static void PrintTypeCheck(const ParsedFunction& parsed_function,
                             TokenPosition token_pos,
                             Value* value,
                             const AbstractType& dst_type,
                             const String& dst_name,
                             bool eliminated);
  static void PrintBlock(BlockEntryInstr* block, bool print_locations);

  static void PrintGraph(const char* phase, FlowGraph* flow_graph);

  // Debugging helper function. If 'num_checks_to_print' is not specified
  // all checks will be printed.
  static void PrintICData(const ICData& ic_data,
                          intptr_t num_checks_to_print = kPrintAll);

  static bool ShouldPrint(const Function& function);

  static bool PassesFilter(const char* filter, const Function& function);

 private:
  const Function& function_;
  const GrowableArray<BlockEntryInstr*>& block_order_;
  const bool print_locations_;
};

}  // namespace dart

#endif  // RUNTIME_VM_IL_PRINTER_H_
