void vaCopy(LLValue* pDest, LLValue* src) { // Analog to va_start, we need to allocate a new __va_list struct on the stack, // fill it with a bitcopy of the source struct... src = DtoLoad(DtoBitCast(src, getValistType()->getPointerTo())); // *(__va_list*)src LLValue* valistmem = DtoAllocaDump(src, 0, "__va_list_mem"); // ... and finally set the passed 'dest' char* pointer to the new struct's address. DtoStore(DtoBitCast(valistmem, getVoidPtrType()), DtoBitCast(pDest, getPtrToType(getVoidPtrType()))); }
void vaCopy(DLValue *dest, DValue *src) override { // Analog to va_start, we first need to allocate a new __va_list struct on // the stack and set `dest` to its address. LLValue *valistmem = DtoRawAlloca(getValistType(), 0, "__va_list_mem"); DtoStore(valistmem, DtoBitCast(DtoLVal(dest), getPtrToType(valistmem->getType()))); // Then fill the new struct with a bitcopy of the source struct. // `src` is a char* pointer to the source struct. DtoMemCpy(valistmem, DtoRVal(src)); }
LLValue *prepareVaStart(DLValue *ap) override { // Since the user only created a char* pointer (ap) on the stack before // invoking va_start, we first need to allocate the actual __va_list struct // and set `ap` to its address. LLValue *valistmem = DtoRawAlloca(getValistType(), 0, "__va_list_mem"); DtoStore(valistmem, DtoBitCast(DtoLVal(ap), getPtrToType(valistmem->getType()))); // Pass a i8* pointer to the actual struct to LLVM's va_start intrinsic. return DtoBitCast(valistmem, getVoidPtrType()); }
LLValue* prepareVaStart(LLValue* pAp) { // Since the user only created a char* pointer (ap) on the stack before invoking va_start, // we first need to allocate the actual __va_list struct and set 'ap' to its address. LLValue* valistmem = DtoRawAlloca(getValistType(), 0, "__va_list_mem"); valistmem = DtoBitCast(valistmem, getVoidPtrType()); DtoStore(valistmem, pAp); // ap = (void*)__va_list_mem // pass a void* pointer to the actual struct to LLVM's va_start intrinsic return valistmem; }