Test function for c++/ir interop for strings. Function will do: int StringTest(StringValue* strval) { strval->ptr[0] = 'A'; int len = strval->len; strval->len = 1; return len; } Corresponding IR is: define i32 @StringTest(%StringValue* %str) { entry: %str_ptr = getelementptr inbounds %StringValue* %str, i32 0, i32 0 %ptr = load i8** %str_ptr %first_char_ptr = getelementptr i8* %ptr, i32 0 store i
| 381 | // ret i32 %len |
| 382 | // } |
| 383 | llvm::Function* CodegenStringTest(LlvmCodeGen* codegen) { |
| 384 | llvm::PointerType* string_val_ptr_type = |
| 385 | codegen->GetSlotPtrType(ColumnType(TYPE_STRING)); |
| 386 | EXPECT_TRUE(string_val_ptr_type != NULL); |
| 387 | |
| 388 | LlvmCodeGen::FnPrototype prototype(codegen, "StringTest", codegen->i32_type()); |
| 389 | prototype.AddArgument(LlvmCodeGen::NamedVariable("str", string_val_ptr_type)); |
| 390 | LlvmBuilder builder(codegen->context()); |
| 391 | |
| 392 | llvm::Value* str; |
| 393 | llvm::Function* interop_fn = prototype.GeneratePrototype(&builder, &str); |
| 394 | |
| 395 | // strval->ptr[0] = 'A' |
| 396 | llvm::Function* str_ptr_fn = codegen->GetFunction( |
| 397 | IRFunction::STRING_VALUE_PTR, false); |
| 398 | llvm::Function* str_len_fn = codegen->GetFunction( |
| 399 | IRFunction::STRING_VALUE_LEN, false); |
| 400 | llvm::Function* str_setlen_fn = codegen->GetFunction( |
| 401 | IRFunction::STRING_VALUE_SETLEN, false); |
| 402 | |
| 403 | llvm::Value* str_ptr = builder.CreateCall(str_ptr_fn, |
| 404 | llvm::ArrayRef<llvm::Value*>({str}), "ptr"); |
| 405 | |
| 406 | llvm::Value* first_char_offset[] = {codegen->GetI32Constant(0)}; |
| 407 | llvm::Value* first_char_ptr = |
| 408 | builder.CreateGEP(str_ptr, first_char_offset, "first_char_ptr"); |
| 409 | builder.CreateStore(codegen->GetI8Constant('A'), first_char_ptr); |
| 410 | |
| 411 | // Update and return old len |
| 412 | llvm::Value* str_len = builder.CreateCall(str_len_fn, |
| 413 | llvm::ArrayRef<llvm::Value*>({str}), "len"); |
| 414 | |
| 415 | builder.CreateCall(str_setlen_fn, |
| 416 | llvm::ArrayRef<llvm::Value*>({str, codegen->GetI32Constant(1)})); |
| 417 | |
| 418 | builder.CreateRet(str_len); |
| 419 | |
| 420 | return codegen->FinalizeFunction(interop_fn); |
| 421 | } |
| 422 | |
| 423 | // This test validates that the llvm StringValue struct matches the c++ stringvalue |
| 424 | // struct. Just create a simple StringValue struct and make sure the IR can read it |
no test coverage detected