Esempio n. 1
0
void DtoResolveStruct(StructDeclaration* sd)
{
    // Make sure to resolve each struct type exactly once.
    if (sd->ir.resolved) return;
    sd->ir.resolved = true;

    Logger::println("Resolving struct type: %s (%s)", sd->toChars(), sd->loc.toChars());
    LOG_SCOPE;

    // make sure type exists
    DtoType(sd->type);

    // if it's a forward declaration, all bets are off. The type should be enough
    if (sd->sizeok != 1)
        return;

    // create the IrAggr
    IrAggr* irstruct = new IrAggr(sd);
    sd->ir.irStruct = irstruct;

    // Set up our field metadata.
    for (ArrayIter<VarDeclaration> it(sd->fields); !it.done(); it.next())
    {
        VarDeclaration* vd = it.get();
        assert(!vd->ir.irField);
        (void)new IrField(vd);
    }

    // perform definition
    bool emitGlobalData = mustDefineSymbol(sd);
    if (emitGlobalData)
    {
        // emit the initZ symbol
        LLGlobalVariable* initZ = irstruct->getInitSymbol();

        // set initZ initializer
        initZ->setInitializer(irstruct->getDefaultInit());
    }

    // emit members
    if (sd->members)
    {
        for (ArrayIter<Dsymbol> it(sd->members); !it.done(); it.next())
        {
            it.get()->codegen(Type::sir);
        }
    }

    if (emitGlobalData)
    {
        // emit typeinfo
        DtoTypeInfoOf(sd->type);
    }
}
Esempio n. 2
0
  void visit(StructDeclaration *decl) override {
    IF_LOG Logger::println("StructDeclaration::codegen: '%s'",
                           decl->toPrettyChars());
    LOG_SCOPE

    if (decl->ir->isDefined()) {
      return;
    }

    if (decl->type->ty == Terror) {
      error(decl->loc, "had semantic errors when compiling");
      decl->ir->setDefined();
      return;
    }

    if (!(decl->members && decl->symtab)) {
      return;
    }

    DtoResolveStruct(decl);
    decl->ir->setDefined();

    for (auto m : *decl->members) {
      m->accept(this);
    }

    // Skip __initZ and typeinfo for @compute device code.
    // TODO: support global variables and thus __initZ
    if (!irs->dcomputetarget) {
      // Define the __initZ symbol.
      IrAggr *ir = getIrAggr(decl);
      auto &initZ = ir->getInitSymbol();
      auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
      initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
      setLinkage(decl, initGlobal);

      // emit typeinfo
      DtoTypeInfoOf(decl->type, /*base=*/false);
    }

    // Emit __xopEquals/__xopCmp/__xtoHash.
    if (decl->xeq && decl->xeq != decl->xerreq) {
      decl->xeq->accept(this);
    }
    if (decl->xcmp && decl->xcmp != decl->xerrcmp) {
      decl->xcmp->accept(this);
    }
    if (decl->xhash) {
      decl->xhash->accept(this);
    }
  }
Esempio n. 3
0
  void visit(ClassDeclaration *decl) override {
    IF_LOG Logger::println("ClassDeclaration::codegen: '%s'",
                           decl->toPrettyChars());
    LOG_SCOPE

    assert(!irs->dcomputetarget);

    if (decl->ir->isDefined()) {
      return;
    }

    if (decl->type->ty == Terror) {
      error(decl->loc, "had semantic errors when compiling");
      decl->ir->setDefined();
      return;
    }

    if (decl->members && decl->symtab) {
      DtoResolveClass(decl);
      decl->ir->setDefined();

      for (auto m : *decl->members) {
        m->accept(this);
      }

      IrAggr *ir = getIrAggr(decl);
      const auto lwc = DtoLinkage(decl);

      auto &initZ = ir->getInitSymbol();
      auto initGlobal = llvm::cast<LLGlobalVariable>(initZ);
      initZ = irs->setGlobalVarInitializer(initGlobal, ir->getDefaultInit());
      setLinkage(lwc, initGlobal);

      llvm::GlobalVariable *vtbl = ir->getVtblSymbol();
      vtbl->setInitializer(ir->getVtblInit());
      setLinkage(lwc, vtbl);

      llvm::GlobalVariable *classZ = ir->getClassInfoSymbol();
      if (!isSpeculativeType(decl->type)) {
        classZ->setInitializer(ir->getClassInfoInit());
        setLinkage(lwc, classZ);
      }
    }
  }
Esempio n. 4
0
void DtoResolveClass(ClassDeclaration* cd)
{
    // make sure the base classes are processed first
    ArrayIter<BaseClass> base_iter(cd->baseclasses);
    while (base_iter.more())
    {
        BaseClass* bc = base_iter.get();
        if (bc)
        {
            bc->base->codegen(Type::sir);
        }
        base_iter.next();
    }

    if (cd->ir.resolved) return;
    cd->ir.resolved = true;

    Logger::println("DtoResolveClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
    LOG_SCOPE;

    // make sure type exists
    DtoType(cd->type);

    // create IrAggr
    assert(cd->ir.irAggr == NULL);
    IrAggr* irAggr = new IrAggr(cd);
    cd->ir.irAggr = irAggr;

    // make sure all fields really get their ir field
    ArrayIter<VarDeclaration> it(cd->fields);
    for (; !it.done(); it.next())
    {
        VarDeclaration* vd = it.get();
        if (vd->ir.irField == NULL) {
            new IrField(vd);
        } else {
            IF_LOG Logger::println("class field already exists!!!");
        }
    }

    bool needs_def = mustDefineSymbol(cd);

    // emit the ClassZ symbol
    LLGlobalVariable* ClassZ = irAggr->getClassInfoSymbol();

    // emit the interfaceInfosZ symbol if necessary
    if (cd->vtblInterfaces && cd->vtblInterfaces->dim > 0)
        irAggr->getInterfaceArraySymbol(); // initializer is applied when it's built

    // interface only emit typeinfo and classinfo
    if (cd->isInterfaceDeclaration())
    {
        irAggr->initializeInterface();
    }
    else
    {
        // emit the initZ symbol
        LLGlobalVariable* initZ = irAggr->getInitSymbol();
        // emit the vtblZ symbol
        LLGlobalVariable* vtblZ = irAggr->getVtblSymbol();

        // perform definition
        if (needs_def)
        {
            // set symbol initializers
            initZ->setInitializer(irAggr->getDefaultInit());
            vtblZ->setInitializer(irAggr->getVtblInit());
        }
    }

    // emit members
    if (cd->members)
    {
        ArrayIter<Dsymbol> it(*cd->members);
        while (!it.done())
        {
            Dsymbol* member = it.get();
            if (member)
                member->codegen(Type::sir);
            it.next();
        }
    }

    if (needs_def)
    {
        // emit typeinfo
        DtoTypeInfoOf(cd->type);

        // define classinfo
        ClassZ->setInitializer(irAggr->getClassInfoInit());
    }
}