blob: 0c34f50429f54b90c58a79edeb51c299c1353086 [file] [log] [blame]
//===-- go-llvm-bstatement.cpp - implementation of '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.
//
//===----------------------------------------------------------------------===//
//
// Methods for class Bstatement.
//
//===----------------------------------------------------------------------===//
#include "go-llvm-btype.h"
#include "go-llvm-bstatement.h"
#include "go-system.h"
#include "llvm/Support/raw_ostream.h"
Bstatement::Bstatement(NodeFlavor fl,
Bfunction *func,
const std::vector<Bnode *> &kids,
Location loc)
: Bnode(fl, kids, loc), function_(func)
{
}
Bstatement::~Bstatement()
{
}
void Bstatement::srcDump(Llvm_linemap *linemap)
{
std::string s;
llvm::raw_string_ostream os(s);
osdump(os, 0, linemap, false);
std::cerr << os.str();
}
std::vector<Bstatement *> Bstatement::getChildStmts()
{
std::vector<Bstatement *> rval;
for (auto &child : children()) {
Bstatement *st = child->castToBstatement();
if (st)
rval.push_back(st);
}
return rval;
}
Bexpression *Bstatement::getNthChildAsExpr(NodeFlavor fl, unsigned cidx)
{
assert(flavor() == fl);
const std::vector<Bnode *> &kids = children();
assert(cidx < kids.size());
Bexpression *e = kids[cidx]->castToBexpression();
assert(e);
return e;
}
Bstatement *Bstatement::getNthChildAsStmt(NodeFlavor fl, unsigned cidx)
{
assert(flavor() == fl);
const std::vector<Bnode *> &kids = children();
assert(cidx < kids.size());
Bstatement *s = kids[cidx]->castToBstatement();
assert(s);
return s;
}
Bexpression *Bstatement::getExprStmtExpr()
{
return getNthChildAsExpr(N_ExprStmt, 0);
}
Bexpression *Bstatement::getReturnStmtExpr()
{
return getNthChildAsExpr(N_ReturnStmt, 0);
}
Bexpression *Bstatement::getIfStmtCondition()
{
return getNthChildAsExpr(N_IfStmt, 0);
}
Bstatement *Bstatement::getIfStmtTrueBlock()
{
return getNthChildAsStmt(N_IfStmt, 1);
}
Bstatement *Bstatement::getIfStmtFalseBlock()
{
return getNthChildAsStmt(N_IfStmt, 2);
}
Bexpression *Bstatement::getDeferStmtUndeferCall()
{
return getNthChildAsExpr(N_DeferStmt, 0);
}
Bexpression *Bstatement::getDeferStmtDeferCall()
{
return getNthChildAsExpr(N_DeferStmt, 1);
}
Bexpression *Bstatement::getSwitchStmtValue()
{
return getNthChildAsExpr(N_SwitchStmt, 0);
}
Bstatement *Bstatement::getExcepStmtBody()
{
return getNthChildAsStmt(N_ExcepStmt, 0);
}
Bstatement *Bstatement::getExcepStmtOnException()
{
return getNthChildAsStmt(N_ExcepStmt, 1);
}
Bstatement *Bstatement::getExcepStmtFinally()
{
return getNthChildAsStmt(N_ExcepStmt, 2);
}
unsigned Bstatement::getSwitchStmtNumCases()
{
assert(flavor() == N_SwitchStmt);
SwitchDescriptor *swcases = getSwitchCases();
return swcases->cases().size();
}
std::vector<Bexpression *> Bstatement::getSwitchStmtNthCase(unsigned idx)
{
assert(flavor() == N_SwitchStmt);
SwitchDescriptor *swcases = getSwitchCases();
assert(idx < swcases->cases().size());
const SwitchCaseDesc &cdesc = swcases->cases().at(idx);
std::vector<Bexpression *> rval;
const std::vector<Bnode *> &kids = children();
for (unsigned ii = 0; ii < cdesc.len; ++ii) {
Bexpression *e = kids[ii+cdesc.st]->castToBexpression();
assert(e);
rval.push_back(e);
}
return rval;
}
Bstatement *Bstatement::getSwitchStmtNthStmt(unsigned idx)
{
assert(flavor() == N_SwitchStmt);
SwitchDescriptor *swcases = getSwitchCases();
assert(idx < swcases->cases().size());
const SwitchCaseDesc &cdesc = swcases->cases().at(idx);
const std::vector<Bnode *> &kids = children();
Bstatement *st = kids[cdesc.stmt]->castToBstatement();
assert(st);
return st;
}
Blabel *Bstatement::getGotoStmtTargetLabel()
{
return label();
}
Blabel *Bstatement::getLabelStmtDefinedLabel()
{
return label();
}
void Blabel::setPlaceholder(llvm::Value *ph)
{
assert(!placeholder_);
assert(ph);
placeholder_ = ph;
}
Bblock::Bblock(Bfunction *func,
const std::vector<Bvariable *> &vars,
Location loc)
: Bstatement(N_BlockStmt, func, std::vector<Bnode *>(), loc)
, vars_(vars), error_(false)
{
}
void Bblock::addTemporaryVariable(Bvariable *var)
{
vars_.push_back(var);
}