blob: da7ebaac59e24d2462f3a7cae1eb9335439e0543 [file] [log] [blame]
//===-- go-llvm-bvariable.cpp - implementation of 'Bvariable' 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 Bvariable.
//
//===----------------------------------------------------------------------===//
#include "go-llvm-bvariable.h"
#include "go-llvm-bexpression.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Instruction.h"
Bvariable::Bvariable(Btype *type, Location location,
const std::string &name, WhichVar which,
bool address_taken, llvm::Value *value)
: name_(name), value_(value), initializer_(nullptr),
type_(type), underlyingType_(nullptr),
location_(location), which_(which),
addrtaken_(address_taken), temporary_(false), declvar_(false)
{
}
Bvariable::Bvariable(Btype *zeroSizeType, Btype *underlyingNonZeroSizeType,
Location location, const std::string &name, WhichVar which,
bool address_taken, llvm::Value *value)
: name_(name), value_(value), initializer_(nullptr),
type_(zeroSizeType), underlyingType_(underlyingNonZeroSizeType),
location_(location), which_(which),
addrtaken_(address_taken), temporary_(false), declvar_(false)
{
assert(which == GlobalVar);
}
void Bvariable::setInitializer(llvm::Value *init)
{
assert(initializer_ == nullptr);
assert(init);
assert(flavor() == GlobalVar || llvm::isa<llvm::Instruction>(init));
initializer_ = init;
}
class CollectLastInstVisitor {
public:
CollectLastInstVisitor() : inst_(nullptr) { }
llvm::Instruction *instruction() const { return inst_; }
void visitNodePre(Bnode *node) { }
void visitNodePost(Bnode *node) {
Bexpression *expr = node->castToBexpression();
if (!expr)
return;
if (! expr->instructions().size())
return;
inst_ = expr->instructions().back();
}
private:
llvm::Instruction *inst_;
};
void Bvariable::setInitializerExpr(Bexpression *expr)
{
assert(expr);
CollectLastInstVisitor vis;
simple_walk_nodes(expr, vis);
assert(vis.instruction());
setInitializer(vis.instruction());
}
llvm::Instruction *Bvariable::initializerInstruction() const
{
assert(initializer_);
return llvm::cast<llvm::Instruction>(initializer_);
}
static void indent(llvm::raw_ostream &os, unsigned ilevel) {
for (unsigned i = 0; i < ilevel; ++i)
os << " ";
}
void Bvariable::dump()
{
std::string s;
llvm::raw_string_ostream os(s);
osdump(os, 0, nullptr, false);
std::cerr << os.str();
}
void Bvariable::srcDump(Linemap *linemap)
{
std::string s;
llvm::raw_string_ostream os(s);
osdump(os, 0, linemap, false);
std::cerr << os.str();
}
void Bvariable::osdump(llvm::raw_ostream &os, unsigned ilevel,
Linemap *linemap, bool terse) {
if (! terse) {
if (linemap) {
indent(os, ilevel);
os << linemap->to_string(location_) << "\n";
}
}
indent(os, ilevel);
const char *whtag = nullptr;
switch(which_) {
case ParamVar: whtag = "param"; break;
case GlobalVar: whtag = "global"; break;
case LocalVar: whtag = "local"; break;
case BlockVar: whtag = "block"; break;
case ErrorVar: whtag = "error"; break;
default: whtag = "<unknownwhichval>"; break;
}
os << whtag << " var '" << name_ << "' type: ";
type_->osdump(os, 0);
os << "\n";
}