//===-- go-llvm-bstatement.h - decls for gofrontend 'Bstatement' class ----===//
//
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
//===----------------------------------------------------------------------===//
//
// Defines Bstatement and related classes.
//
//===----------------------------------------------------------------------===//

#ifndef LLVMGOFRONTEND_GO_LLVM_BSTATEMENT_H
#define LLVMGOFRONTEND_GO_LLVM_BSTATEMENT_H

// Currently these need to be included before backend.h
#include "go-llvm-linemap.h"
#include "go-location.h"
#include "go-llvm-btype.h"
//#include "go-llvm-bexpression.h"
#include "go-llvm-bnode.h"

#include "backend.h"

namespace llvm {
class Function;
class Instruction;
class Type;
class Value;
class raw_ostream;
}

// Class Bstatement encapsulates the IR for a statement, storing zero
// or more component Bexpressions, along with state related to
// statement control flow (if / switch / goto, etc). The specific
// contents/children of a given Bstatement are determined by its
// NodeFlavor (value of Bnode::flavor()).
//
// In the current gofrontend implementation, there is an extremely
// fluzzy/fluid line between Bexpression's, Bblocks, and Bstatements.
// For example, you can take a Bblock and turn it into a statement via
// Backend::block_statement. You can also combine an existing
// Bstatement with a Bexpression to form a second Bexpression via
// Backend::compound_expression. This is most likely due to the fact
// that the first backend (gcc) selected as a target for gofrontend
// uses a tree intermediate representation, where blocks, expressions,
// and statements are all simply tree fragments. With LLVM on the
// other hand, it is not so straightforward to have chunks of IR
// morphing back end forth between statements, expressions, and
// blocks.

class Bstatement : public Bnode {
 public:
  // no public constructor, use BnodeBuilder instead
  virtual ~Bstatement();

  // Function this statement is part of
  Bfunction *function() const { return function_; }

  // dump with source line info
  void srcDump(Llvm_linemap *);

  // If this is an expression statement (flavor N_ExprStmt), return
  // a pointer to the Bexpression it contains.
  Bexpression *getExprStmtExpr();

  // If this is a return statement (flavor N_ReturnStmt), return
  // a pointer to the Bexpression it contains.
  Bexpression *getReturnStmtExpr();

  // If this is an if statement (flavor N_IfStmt), return
  // components of the "if" (condition, true block, false block).
  Bexpression *getIfStmtCondition();
  Bstatement *getIfStmtTrueBlock();
  Bstatement *getIfStmtFalseBlock();

  // If this is a switch statement (flavor N_SwitchStmt), return
  // the Bexpresson for the value we're switching on, along
  // with info on the number of cases, Bexpressions for each case,
  // and Bstatement for each case.
  Bexpression *getSwitchStmtValue();
  unsigned     getSwitchStmtNumCases();
  std::vector<Bexpression *> getSwitchStmtNthCase(unsigned idx);
  Bstatement *getSwitchStmtNthStmt(unsigned idx);

  // If this is a defer statement (flavor N_DeferStmt), return
  // components of the defer.
  Bexpression *getDeferStmtUndeferCall();
  Bexpression *getDeferStmtDeferCall();

  // If this is an exception handling statement (flavor N_ExcepStmt), return
  // components of the statement.
  Bstatement *getExcepStmtBody();
  Bstatement *getExcepStmtOnException();
  Bstatement *getExcepStmtFinally();

  // If this is a goto statement (flavor N_GotoStmt), return
  // the target label for the goto.
  Blabel *getGotoStmtTargetLabel();

  // If this is a label statement (flavor N_LabelStmt), return
  // the label defined by this stmt.
  Blabel *getLabelStmtDefinedLabel();

  // Generic hook for collecting all statements that are children of
  // this statement. Used when walking statements to assign
  // instructions to LLVM blocks.
  std::vector<Bstatement *> getChildStmts();

 protected:
  friend class BnodeBuilder;
  Bstatement(NodeFlavor fl, Bfunction *func,
             const std::vector<Bnode *> &kids, Location loc);

 private:
  Bexpression *getNthChildAsExpr(NodeFlavor fl, unsigned cidx);
  Bstatement *getNthChildAsStmt(NodeFlavor fl, unsigned cidx);

 private:
  Bfunction *function_;
};

typedef unsigned LabelId;

// Back end label class. Encapsulates a label referred to by a label
// definition statement and/or some set of goto statements.

class Blabel {
public:
  Blabel(const Bfunction *function, LabelId lab, Location loc)
      : function_(const_cast<Bfunction *>(function)),
        placeholder_(nullptr), lab_(lab), location_(loc) {}
  LabelId label() const { return lab_; }
  Bfunction *function() { return function_; }
  Location location() const { return location_; }
  llvm::Value *placeholder() const { return placeholder_; }
  void setPlaceholder(llvm::Value *ph);

private:
  Bfunction *function_;
  llvm::Value *placeholder_;
  LabelId lab_;
  Location location_;
};

// A Bblock is essentially just a compound statement

class Bblock : public Bstatement {
 public:
  // no public constructor; use BnodeBuilder::mkBlock to create a
  // block, BnodeBuilder::addStatementToBlock to add stmts to it.
  virtual ~Bblock() { }

  // Local variables for this block
  const std::vector<Bvariable *> &vars() const { return vars_; }

  // Temporary vars can be tacked into an existing block via a
  // the backend temporary_variable() method-- allow for this here.
  void addTemporaryVariable(Bvariable *var);

  void setError() { error_ = true; }
  bool hasError() { return error_; }

 private:
  friend class BnodeBuilder;
  Bblock(Bfunction *func,
         const std::vector<Bvariable *> &vars,
         Location loc);

 private:
  std::vector<Bvariable *> vars_;
  bool error_;
};

#endif // LLVMGOFRONTEND_GO_LLVM_BSTATEMENT_H
