blob: 823da90bedea6edd4e57ba66d7a57b475331b6d6 [file] [log] [blame]
//===-- VMField.cpp - Compiler representation of a Java field ---*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the implementation of the Field class that represents a
// compile time representation of a Java class field (java.lang.Field).
//
//===----------------------------------------------------------------------===//
#include "VMField.h"
#include "Resolver.h"
#include "VMClass.h"
#include <llvm/Constants.h>
#include <llvm/DerivedTypes.h>
using namespace llvm;
using namespace llvm::Java;
VMField::VMField(const VMClass* parent, const Field* field)
: parent_(parent),
class_(parent->getClass(field->getDescriptorIndex())),
field_(field)
{
assert(isStatic() && "This should be a static field!");
// A java static field is constant if it is marked final and has a
// static initializer.
bool isConstant = field_->isFinal() && field->getConstantValueAttribute();
llvm::Constant* init = NULL;
if (ConstantValueAttribute* attr = field_->getConstantValueAttribute()) {
init = parent_->getConstant(attr->getValueIndex());
if (init->getType() != class_->getType())
init = ConstantExpr::getCast(init, class_->getType());
}
else
init = llvm::Constant::getNullValue(class_->getType());
data_.global = new GlobalVariable(class_->getType(),
isConstant,
GlobalVariable::ExternalLinkage,
init,
parent_->getName() + '/' + getName(),
parent_->getResolver()->getModule());
}
VMField::VMField(const VMClass* parent, const Field* field, int index)
: parent_(parent),
class_(parent->getClass(field->getDescriptorIndex())),
field_(field)
{
assert(!isStatic() && "This should be a member field!");
data_.index = index;
}
llvm::Constant* VMField::buildFieldDescriptor() const
{
llvm::Constant* fd = ConstantArray::get(getName() + getDescriptor());
return ConstantExpr::getPtrPtrFromArrayPtr(
new GlobalVariable(
fd->getType(),
true,
GlobalVariable::ExternalLinkage,
fd,
getName() + getDescriptor(),
parent_->getResolver()->getModule()));
}
llvm::Constant* VMField::buildFieldOffset() const
{
assert(!isStatic() && "This should be a member field!");
assert(!isa<OpaqueType>(getParent()->getType()) &&
"Should not be called before its owning class layout is computed!");
llvm::Constant* nullRef =
llvm::Constant::getNullValue(getParent()->getType());
std::vector<llvm::Constant*> indices;
indices.reserve(2);
indices.push_back(ConstantInt::get(Type::UIntTy, 0));
indices.push_back(ConstantInt::get(Type::UIntTy, getMemberIndex()));
return ConstantExpr::getCast(
ConstantExpr::getGetElementPtr(nullRef, indices), Type::UIntTy);
}