Ejemplo n.º 1
0
/// Return the type returned by DtoUnpaddedStruct called on a value of the
/// specified type.
/// Union types will get expanded into a struct, with a type for each member.
LLType* DtoUnpaddedStructType(Type* dty) {
    assert(dty->ty == Tstruct);

    typedef llvm::DenseMap<Type*, llvm::StructType*> CacheT;
    static llvm::ManagedStatic<CacheT> cache;
    CacheT::iterator it = cache->find(dty);
    if (it != cache->end())
        return it->second;

    TypeStruct* sty = static_cast<TypeStruct*>(dty);
    VarDeclarations& fields = sty->sym->fields;

    std::vector<LLType*> types;
    types.reserve(fields.dim);

    for (unsigned i = 0; i < fields.dim; i++) {
        LLType* fty;
        if (fields[i]->type->ty == Tstruct) {
            // Nested structs are the only members that can contain padding
            fty = DtoUnpaddedStructType(fields[i]->type);
        } else {
            fty = DtoType(fields[i]->type);
        }
        types.push_back(fty);
    }
    LLStructType* Ty = LLStructType::get(gIR->context(), types);
    cache->insert(std::make_pair(dty, Ty));
    return Ty;
}
Ejemplo n.º 2
0
Archivo: abi.cpp Proyecto: smunix/ldc
    void fixup(IrFuncTyArg& arg) {
        assert(arg.type->ty == Tstruct);
        // TODO: Check that no unions are passed in or returned.

        LLType* abiTy = DtoUnpaddedStructType(arg.type);

        if (abiTy && abiTy != arg.ltype) {
            arg.ltype = abiTy;
            arg.rewrite = &remove_padding;
        }
    }
Ejemplo n.º 3
0
/// Return the struct value represented by v without the padding fields.
/// Unions will be expanded, with a value for each member.
/// Note: v must be a pointer to a struct, but the return value will be a
///       first-class struct value.
LLValue* DtoUnpaddedStruct(Type* dty, LLValue* v) {
    assert(dty->ty == Tstruct);
    TypeStruct* sty = static_cast<TypeStruct*>(dty);
    VarDeclarations& fields = sty->sym->fields;

    LLValue* newval = llvm::UndefValue::get(DtoUnpaddedStructType(dty));

    for (unsigned i = 0; i < fields.dim; i++) {
        LLValue* fieldptr = DtoIndexAggregate(v, sty->sym, fields[i]);
        LLValue* fieldval;
        if (fields[i]->type->ty == Tstruct) {
            // Nested structs are the only members that can contain padding
            fieldval = DtoUnpaddedStruct(fields[i]->type, fieldptr);
        } else {
            fieldval = DtoLoad(fieldptr);
        }
        newval = DtoInsertValue(newval, fieldval, i);
    }
    return newval;
}
Ejemplo n.º 4
0
/// Return the struct value represented by v without the padding fields.
/// Unions will be expanded, with a value for each member.
/// Note: v must be a pointer to a struct, but the return value will be a
///       first-class struct value.
LLValue* DtoUnpaddedStruct(Type* dty, LLValue* v) {
    assert(dty->ty == Tstruct);
    TypeStruct* sty = (TypeStruct*) dty;
    Array& fields = sty->sym->fields;
    
    LLValue* newval = llvm::UndefValue::get(DtoUnpaddedStructType(dty));
    
    for (unsigned i = 0; i < fields.dim; i++) {
        VarDeclaration* vd = (VarDeclaration*) fields.data[i];
        LLValue* fieldptr = DtoIndexStruct(v, sty->sym, vd);
        LLValue* fieldval;
        if (vd->type->ty == Tstruct) {
            // Nested structs are the only members that can contain padding
            fieldval = DtoUnpaddedStruct(vd->type, fieldptr);
        } else {
            fieldval = DtoLoad(fieldptr);
        }
        newval = DtoInsertValue(newval, fieldval, i);
    }
    return newval;
}