示例#1
0
void AttribDeclaration::codegen(Ir* p)
{
    Array *d = include(NULL, NULL);

    if (d)
    {
        for (unsigned i = 0; i < d->dim; i++)
        {   Dsymbol *s = static_cast<Dsymbol *>(d->data[i]);
            s->codegen(p);
        }
    }
}
示例#2
0
void TemplateMixin::codegen(Ir* p)
{
    if (!errors && members)
    {
        for (unsigned i = 0; i < members->dim; i++)
        {
            Dsymbol *s = static_cast<Dsymbol *>(members->data[i]);
            if (s->isVarDeclaration())
                continue;
            s->codegen(p);
        }
    }
}
示例#3
0
void TemplateInstance::codegen(Ir* p)
{
#if LOG
    printf("TemplateInstance::codegen('%s', this = %p)\n", toChars(), this);
#endif
    if (ignore)
        return;

    if (!errors && members)
    {
        for (unsigned i = 0; i < members->dim; i++)
        {
            Dsymbol *s = static_cast<Dsymbol *>(members->data[i]);
            s->codegen(p);
        }
    }
}
示例#4
0
llvm::Module* Module::genLLVMModule(llvm::LLVMContext& context, Ir* sir)
{
    bool logenabled = Logger::enabled();
    if (llvmForceLogging && !logenabled)
    {
        Logger::enable();
    }

    Logger::println("Generating module: %s", (md ? md->toChars() : toChars()));
    LOG_SCOPE;

    if (global.params.verbose_cg)
        printf("codegen: %s (%s)\n", toPrettyChars(), srcfile->toChars());

    assert(!global.errors);

    // name the module
#if 1
    // Temporary workaround for http://llvm.org/bugs/show_bug.cgi?id=11479 –
    // just use the source file name, as it is unlikely to collide with a
    // symbol name used somewhere in the module.
    llvm::StringRef mname(srcfile->toChars());
#else
    llvm::StringRef mname(toChars());
    if (md != 0)
        mname = md->toChars();
#endif

    // create a new ir state
    // TODO look at making the instance static and moving most functionality into IrModule where it belongs
    IRState ir(new llvm::Module(mname, context));
    gIR = &ir;
    ir.dmodule = this;

    // reset all IR data stored in Dsymbols
    IrDsymbol::resetAll();

    sir->setState(&ir);

    // set target triple
    ir.module->setTargetTriple(global.params.targetTriple.str());

    // set final data layout
    ir.module->setDataLayout(gDataLayout->getStringRepresentation());
    if (Logger::enabled())
        Logger::cout() << "Final data layout: " << ir.module->getDataLayout() << '\n';

    // allocate the target abi
    gABI = TargetABI::getTarget();

    // debug info
    DtoDwarfCompileUnit(this);

    // handle invalid 'objectø module
    if (!ClassDeclaration::object) {
        error("is missing 'class Object'");
        fatal();
    }
    if (!ClassDeclaration::classinfo) {
        error("is missing 'class ClassInfo'");
        fatal();
    }

    LLVM_D_InitRuntime();

    // process module members
    for (unsigned k=0; k < members->dim; k++) {
        Dsymbol* dsym = static_cast<Dsymbol*>(members->data[k]);
        assert(dsym);
        dsym->codegen(sir);
    }

    // emit function bodies
    sir->emitFunctionBodies();

    // for singleobj-compilation, fully emit all seen template instances
    if (global.params.singleObj)
    {
        while (!ir.seenTemplateInstances.empty())
        {
            IRState::TemplateInstanceSet::iterator it, end = ir.seenTemplateInstances.end();
            for (it = ir.seenTemplateInstances.begin(); it != end; ++it)
                (*it)->codegen(sir);
            ir.seenTemplateInstances.clear();

            // emit any newly added function bodies
            sir->emitFunctionBodies();
        }
    }

    // finilize debug info
    DtoDwarfModuleEnd();

    // generate ModuleInfo
    genmoduleinfo();

    // verify the llvm
    verifyModule(*ir.module);

    gIR = NULL;

    if (llvmForceLogging && !logenabled)
    {
        Logger::disable();
    }

    sir->setState(NULL);

    return ir.module;
}
示例#5
0
void DtoResolveStruct(StructDeclaration* sd)
{
    // don't do anything if already been here
    if (sd->ir.resolved) return;
    // make sure above works :P
    sd->ir.resolved = true;

    // log what we're doing
    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 IrStruct
    IrStruct* irstruct = new IrStruct(sd);
    sd->ir.irStruct = irstruct;

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

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

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

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

    if (needs_def)
    {
        // emit typeinfo
        DtoTypeInfoOf(sd->type);
    }
}
示例#6
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 IrStruct
    assert(cd->ir.irStruct == NULL);
    IrStruct* irstruct = new IrStruct(cd);
    cd->ir.irStruct = irstruct;

    // 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 = irstruct->getClassInfoSymbol();

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

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

        // perform definition
        if (needs_def)
        {
            // set symbol initializers
            initZ->setInitializer(irstruct->getDefaultInit());
            vtblZ->setInitializer(irstruct->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(irstruct->getClassInfoInit());
    }
}