Esempio n. 1
0
llvm::Constant *
IrAggr::createInitializerConstant(const VarInitMap &explicitInitializers) {
  IF_LOG Logger::println("Creating initializer constant for %s",
                         aggrdecl->toChars());
  LOG_SCOPE;

  llvm::SmallVector<llvm::Constant *, 16> constants;

  unsigned offset = 0;
  if (type->ty == Tclass) {
    // add vtbl
    constants.push_back(getVtblSymbol());
    offset += Target::ptrsize;

    // add monitor (except for C++ classes)
    if (!aggrdecl->isClassDeclaration()->isCPPclass()) {
      constants.push_back(getNullValue(getVoidPtrType()));
      offset += Target::ptrsize;
    }
  }

  // Add the initializers for the member fields. While we are traversing the
  // class hierarchy, use the opportunity to populate interfacesWithVtbls if
  // we haven't done so previously (due to e.g. ClassReferenceExp, we can
  // have multiple initializer constants for a single class).
  addFieldInitializers(constants, explicitInitializers, aggrdecl, offset,
                       interfacesWithVtbls.empty());

  // tail padding?
  const size_t structsize = aggrdecl->size(Loc());
  if (offset < structsize)
    add_zeros(constants, offset, structsize);

  assert(!constants.empty());

  // get LL field types
  llvm::SmallVector<llvm::Type *, 16> types;
  types.reserve(constants.size());
  for (auto c : constants)
    types.push_back(c->getType());

  auto llStructType = getLLStructType();
  bool isCompatible = (types.size() == llStructType->getNumElements());
  if (isCompatible) {
    for (size_t i = 0; i < types.size(); i++) {
      if (types[i] != llStructType->getElementType(i)) {
        isCompatible = false;
        break;
      }
    }
  }

  // build constant
  LLStructType *llType =
      isCompatible ? llStructType
                   : LLStructType::get(gIR->context(), types, isPacked());
  llvm::Constant *c = LLConstantStruct::get(llType, constants);
  IF_LOG Logger::cout() << "final initializer: " << *c << std::endl;
  return c;
}
Esempio n. 2
0
std::vector<llvm::Constant*> IrStruct::createClassDefaultInitializer()
{
    ClassDeclaration* cd = aggrdecl->isClassDeclaration();
    assert(cd && "invalid class aggregate");

    IF_LOG Logger::println("Building class default initializer %s @ %s", cd->toPrettyChars(), cd->loc.toChars());
    LOG_SCOPE;
    IF_LOG Logger::println("Instance size: %u", cd->structsize);

    // find the fields that contribute to the default initializer.
    // these will define the default type.

    std::vector<llvm::Constant*> constants;
    constants.reserve(32);

    // add vtbl
    constants.push_back(getVtblSymbol());
    // add monitor
    constants.push_back(getNullValue(DtoType(Type::tvoid->pointerTo())));

    // we start right after the vtbl and monitor
    size_t offset = PTRSIZE * 2;
    size_t field_index = 2;

    // add data members recursively
    addBaseClassInits(constants, cd, offset, field_index);

    // tail padding?
    if (offset < cd->structsize)
        add_zeros(constants, cd->structsize - offset);

    return constants;
}
Esempio n. 3
0
llvm::Constant* IrAggr::createInitializerConstant(
    const VarInitMap& explicitInitializers,
    llvm::StructType* initializerType)
{
    IF_LOG Logger::println("Creating initializer constant for %s", aggrdecl->toChars());
    LOG_SCOPE;

    llvm::SmallVector<llvm::Constant*, 16> constants;

    unsigned offset = 0;
    if (type->ty == Tclass)
    {
        // add vtbl
        constants.push_back(getVtblSymbol());
        // add monitor
        constants.push_back(getNullValue(DtoType(Type::tvoid->pointerTo())));

        // we start right after the vtbl and monitor
        offset = Target::ptrsize * 2;
    }

    // Add the initializers for the member fields. While we are traversing the
    // class hierarchy, use the opportunity to populate interfacesWithVtbls if
    // we haven't done so previously (due to e.g. ClassReferenceExp, we can
    // have multiple initializer constants for a single class).
    addFieldInitializers(constants, explicitInitializers, aggrdecl, offset,
        interfacesWithVtbls.empty());

    // tail padding?
    const size_t structsize = aggrdecl->size(Loc());
    if (offset < structsize)
    {
        add_zeros(constants, offset, structsize);
    }

    // get initializer type
    if (!initializerType || initializerType->isOpaque())
    {
        llvm::SmallVector<llvm::Constant*, 16>::iterator itr, end = constants.end();
        llvm::SmallVector<llvm::Type*, 16> types;
        types.reserve(constants.size());
        for (itr = constants.begin(); itr != end; ++itr)
            types.push_back((*itr)->getType());
        if (!initializerType)
            initializerType = LLStructType::get(gIR->context(), types, isPacked());
        else
            initializerType->setBody(types, isPacked());
    }

    // build constant
    assert(!constants.empty());
    llvm::Constant* c = LLConstantStruct::get(initializerType, constants);
    IF_LOG Logger::cout() << "final initializer: " << *c << std::endl;
    return c;
}