Beispiel #1
0
LLConstant* DtoConstString(const char* str)
{
    llvm::StringRef s(str ? str : "");
#if LDC_LLVM_VER == 300
    LLConstant* init = LLConstantArray::get(gIR->context(), s, true);
#else
    LLConstant* init = llvm::ConstantDataArray::getString(gIR->context(), s, true);
#endif
    llvm::GlobalVariable* gvar = new llvm::GlobalVariable(
        *gIR->module, init->getType(), true, llvm::GlobalValue::InternalLinkage, init, ".str");
    LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
    return DtoConstSlice(
        DtoConstSize_t(s.size()),
        llvm::ConstantExpr::getGetElementPtr(gvar, idxs, true),
        Type::tchar->arrayOf()
    );
}
Beispiel #2
0
LLConstant *DtoConstString(const char *str) {
  llvm::StringRef s(str ? str : "");
  llvm::GlobalVariable *gvar = (gIR->stringLiteral1ByteCache.find(s) ==
                                gIR->stringLiteral1ByteCache.end())
                                   ? nullptr
                                   : gIR->stringLiteral1ByteCache[s];
  if (gvar == nullptr) {
    llvm::Constant *init =
        llvm::ConstantDataArray::getString(gIR->context(), s, true);
    gvar = new llvm::GlobalVariable(gIR->module, init->getType(), true,
                                    llvm::GlobalValue::PrivateLinkage, init,
                                    ".str");
    gvar->setUnnamedAddr(true);
    gIR->stringLiteral1ByteCache[s] = gvar;
  }
  LLConstant *idxs[] = {DtoConstUint(0), DtoConstUint(0)};
  return DtoConstSlice(DtoConstSize_t(s.size()),
                       llvm::ConstantExpr::getGetElementPtr(
#if LDC_LLVM_VER >= 307
                           gvar->getInitializer()->getType(),
#endif
                           gvar, idxs, true),
                       Type::tchar->arrayOf());
}
Beispiel #3
0
LLConstant * IrStruct::getClassInfoInterfaces()
{
    IF_LOG Logger::println("Building ClassInfo.interfaces");
    LOG_SCOPE;

    ClassDeclaration* cd = aggrdecl->isClassDeclaration();
    assert(cd);

    size_t n = interfacesWithVtbls.size();
    assert(stripModifiers(type)->irtype->isClass()->getNumInterfaceVtbls() == n &&
        "inconsistent number of interface vtables in this class");

    VarDeclarationIter interfaces_idx(ClassDeclaration::classinfo->fields, 3);

    if (n == 0)
        return getNullValue(DtoType(interfaces_idx->type));

// Build array of:
//
//     struct Interface
//     {
//         ClassInfo   classinfo;
//         void*[]     vtbl;
//         ptrdiff_t   offset;
//     }

    LLSmallVector<LLConstant*, 6> constants;
    constants.reserve(cd->vtblInterfaces->dim);

    LLType* classinfo_type = DtoType(ClassDeclaration::classinfo->type);
    LLType* voidptrptr_type = DtoType(
        Type::tvoid->pointerTo()->pointerTo());
    VarDeclarationIter idx(ClassDeclaration::classinfo->fields, 3);
    LLStructType* interface_type = isaStruct(DtoType(idx->type->nextOf()));
    assert(interface_type);

    for (size_t i = 0; i < n; ++i)
    {
        BaseClass* it = interfacesWithVtbls[i];

        IF_LOG Logger::println("Adding interface %s", it->base->toPrettyChars());

        IrStruct* irinter = it->base->ir.irStruct;
        assert(irinter && "interface has null IrStruct");
        IrTypeClass* itc = stripModifiers(irinter->type)->irtype->isClass();
        assert(itc && "null interface IrTypeClass");

        // classinfo
        LLConstant* ci = irinter->getClassInfoSymbol();
        ci = DtoBitCast(ci, classinfo_type);

        // vtbl
        LLConstant* vtb;
        // interface get a null
        if (cd->isInterfaceDeclaration())
        {
            vtb = DtoConstSlice(DtoConstSize_t(0), getNullValue(voidptrptr_type));
        }
        else
        {
            ClassGlobalMap::iterator itv = interfaceVtblMap.find(it->base);
            assert(itv != interfaceVtblMap.end() && "interface vtbl not found");
            vtb = itv->second;
            vtb = DtoBitCast(vtb, voidptrptr_type);
            vtb = DtoConstSlice(DtoConstSize_t(itc->getVtblSize()), vtb);
        }

        // offset
        LLConstant* off = DtoConstSize_t(it->offset);

        // create Interface struct
        LLConstant* inits[3] = { ci, vtb, off };
        LLConstant* entry = LLConstantStruct::get(interface_type, llvm::makeArrayRef(inits, 3));
        constants.push_back(entry);
    }

    // create Interface[N]
    LLArrayType* array_type = llvm::ArrayType::get(interface_type, n);

    // create and apply initializer
    LLConstant* arr = LLConstantArray::get(array_type, constants);
    classInterfacesArray->setInitializer(arr);

    // return null, only baseclass provide interfaces
    if (cd->vtblInterfaces->dim == 0)
    {
        return getNullValue(DtoType(interfaces_idx->type));
    }

    // only the interface explicitly implemented by this class
    // (not super classes) should show in ClassInfo
    LLConstant* idxs[2] = {
        DtoConstSize_t(0),
        DtoConstSize_t(n - cd->vtblInterfaces->dim)
    };

    LLConstant* ptr = llvm::ConstantExpr::getGetElementPtr(
        classInterfacesArray, idxs, true);

    // return as a slice
    return DtoConstSlice( DtoConstSize_t(cd->vtblInterfaces->dim), ptr );
}
Beispiel #4
0
LLConstant *DtoConstString(const char *str) {
  LLConstant *cString = DtoConstCString(str);
  LLConstant *length = DtoConstSize_t(str ? strlen(str) : 0);
  return DtoConstSlice(length, cString, Type::tchar->arrayOf());
}
Beispiel #5
0
void RTTIBuilder::push_array(uint64_t dim, llvm::Constant * ptr)
{
    inits.push_back(DtoConstSlice(DtoConstSize_t(dim), ptr));
}
Beispiel #6
0
void RTTIBuilder::push_void_array(uint64_t dim, llvm::Constant *ptr) {
  push(DtoConstSlice(DtoConstSize_t(dim), DtoBitCast(ptr, getVoidPtrType())));
}