private static void BuildStringConcatFunction(Module stringModule, CommonExternalFunctions externalFunctions) { LLVMValueRef stringConcatFunction = stringModule.AddFunction(StringConcatName, CommonModuleSignatures[StringConcatName]); LLVMBasicBlockRef entryBlock = stringConcatFunction.AppendBasicBlock("entry"); var builder = new IRBuilder(); builder.PositionBuilderAtEnd(entryBlock); LLVMValueRef slice0 = stringConcatFunction.GetParam(0u), slice1 = stringConcatFunction.GetParam(1u), sliceSize0 = builder.CreateExtractValue(slice0, 1u, "sliceSize0"), sliceSize1 = builder.CreateExtractValue(slice1, 1u, "sliceSize1"), concatSize = builder.CreateAdd(sliceSize0, sliceSize1, "concatSize"), concatAllocationPtr = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), concatSize, "concatAllocationPtr"), concatAllocationOffsetPtr = builder.CreateGEP(concatAllocationPtr, new LLVMValueRef[] { sliceSize0 }, "concatAllocationOffsetPtr"), stringPtr = stringConcatFunction.GetParam(2u), stringAllocationPtrPtr = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"), stringSizePtr = builder.CreateStructGEP(stringPtr, 1u, "stringSizePtr"); builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { slice0, concatAllocationPtr }, string.Empty); builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { slice1, concatAllocationOffsetPtr }, string.Empty); builder.CreateStore(concatAllocationPtr, stringAllocationPtrPtr); builder.CreateStore(concatSize, stringSizePtr); builder.CreateRetVoid(); }
private static void BuildOpenFileHandleFunction(Module fileModule, CommonExternalFunctions externalFunctions) { LLVMValueRef openFileHandleFunction = fileModule.AddFunction(OpenFileHandleName, CommonModuleSignatures[OpenFileHandleName]); LLVMBasicBlockRef entryBlock = openFileHandleFunction.AppendBasicBlock("entry"); var builder = new IRBuilder(); builder.PositionBuilderAtEnd(entryBlock); LLVMValueRef pathSliceRef = openFileHandleFunction.GetParam(0u), nullTerminatedStringPtr = builder.CreateCall(_createNullTerminatedStringFromSliceFunction, new LLVMValueRef[] { pathSliceRef }, "nullTerminatedStringtPtr"), readWriteAccess = (0xC0000000u).AsLLVMValue(), noShareMode = 0u.AsLLVMValue(), openAlways = (0x4u).AsLLVMValue(), fileAttributeNormal = (0x80u).AsLLVMValue(), fileHandleOptionPtr = openFileHandleFunction.GetParam(1u), fileHandleIsSomePtr = builder.CreateStructGEP(fileHandleOptionPtr, 0u, "fileHandleIsSomePtr"), fileHandleInnerValuePtr = builder.CreateStructGEP(fileHandleOptionPtr, 1u, "fileHandleInnerValuePtr"), fileHandleInnerValueFileHandlePtr = builder.CreateStructGEP(fileHandleInnerValuePtr, 0u, "fileHandleInnerValueFileHandlePtr"), fileHandle = builder.CreateCall( externalFunctions.CreateFileAFunction, new LLVMValueRef[] { nullTerminatedStringPtr, readWriteAccess, noShareMode, LLVMExtensions.NullVoidPointer, openAlways, fileAttributeNormal, LLVMExtensions.NullVoidPointer }, "fileHandle"); builder.CreateFree(nullTerminatedStringPtr); builder.CreateStore(true.AsLLVMValue(), fileHandleIsSomePtr); builder.CreateStore(fileHandle, fileHandleInnerValueFileHandlePtr); builder.CreateRetVoid(); }
private static void BuildStringFromSliceFunction(Module stringModule, CommonExternalFunctions externalFunctions) { LLVMValueRef stringFromSliceFunction = stringModule.AddFunction(StringFromSliceName, CommonModuleSignatures[StringFromSliceName]); LLVMBasicBlockRef entryBlock = stringFromSliceFunction.AppendBasicBlock("entry"); var builder = new IRBuilder(); builder.PositionBuilderAtEnd(entryBlock); LLVMValueRef stringSliceReference = stringFromSliceFunction.GetParam(0u), stringPtr = stringFromSliceFunction.GetParam(1u), stringAllocationPtrPtr = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"), stringSizePtr = builder.CreateStructGEP(stringPtr, 1u, "stringSizePtr"); LLVMValueRef sliceAllocationPtr = builder.CreateExtractValue(stringSliceReference, 0u, "sliceAllocationPtr"); LLVMValueRef sliceSize = builder.CreateExtractValue(stringSliceReference, 1u, "sliceSize"); // Get a pointer to a heap allocation big enough for the string LLVMValueRef allocationPtr = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), sliceSize, "allocationPtr"); builder.CreateStore(allocationPtr, stringAllocationPtrPtr); // Copy the data from the string slice to the heap allocation LLVMValueRef sizeExtend = builder.CreateSExt(sliceSize, LLVMTypeRef.Int64Type(), "sizeExtend"); builder.CreateCall(externalFunctions.CopyMemoryFunction, new LLVMValueRef[] { allocationPtr, sliceAllocationPtr, sizeExtend }, string.Empty); // Copy actual size into string handle builder.CreateStore(sliceSize, stringSizePtr); builder.CreateRetVoid(); }
public FunctionCompiler(Module module, string functionName, Dictionary <VariableReference, ValueSource> variableValues) { Module = module; _variableValues = variableValues; LLVMTypeRef functionType = LLVMSharp.LLVM.FunctionType(LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { }, false); _topLevelFunction = Module.AddFunction(functionName, functionType); LLVMBasicBlockRef entryBlock = _topLevelFunction.AppendBasicBlock("entry"); _builder = new IRBuilder(); _builder.PositionBuilderAtEnd(entryBlock); _commonExternalFunctions = new CommonExternalFunctions(module); InitializeLocalAllocations(); }
private static void BuildCopySliceToPointerFunction(Module stringModule, CommonExternalFunctions externalFunctions) { _copySliceToPointerFunction = stringModule.AddFunction(CopySliceToPointerName, CommonModuleSignatures[CopySliceToPointerName]); LLVMBasicBlockRef entryBlock = _copySliceToPointerFunction.AppendBasicBlock("entry"); var builder = new IRBuilder(); builder.PositionBuilderAtEnd(entryBlock); LLVMValueRef slice = _copySliceToPointerFunction.GetParam(0u), sourcePtr = builder.CreateExtractValue(slice, 0u, "sourcePtr"), size = builder.CreateExtractValue(slice, 1u, "size"), sizeExtend = builder.CreateSExt(size, LLVMTypeRef.Int64Type(), "sizeExtend"), destinationPtr = _copySliceToPointerFunction.GetParam(1u); builder.CreateCall(externalFunctions.CopyMemoryFunction, new LLVMValueRef[] { destinationPtr, sourcePtr, sizeExtend }, string.Empty); builder.CreateRetVoid(); }
private static void BuildDropFileHandleFunction(Module fileModule, CommonExternalFunctions externalFunctions) { LLVMValueRef dropFileHandleFunction = fileModule.AddFunction(DropFileHandleName, CommonModuleSignatures[DropFileHandleName]); LLVMBasicBlockRef entryBlock = dropFileHandleFunction.AppendBasicBlock("entry"); var builder = new IRBuilder(); builder.PositionBuilderAtEnd(entryBlock); LLVMValueRef fileHandleStructPtr = dropFileHandleFunction.GetParam(0u), fileHandlePtr = builder.CreateStructGEP(fileHandleStructPtr, 0u, "fileHandlePtr"), fileHandle = builder.CreateLoad(fileHandlePtr, "fileHandle"); builder.CreateCall( externalFunctions.CloseHandleFunction, new LLVMValueRef[] { fileHandle }, "closeHandleResult"); builder.CreateRetVoid(); }
private static void CreateFileModule(Module fileModule) { CommonExternalFunctions externalFunctions = new CommonExternalFunctions(fileModule); CommonModuleSignatures[OpenFileHandleName] = LLVMSharp.LLVM.FunctionType( LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { LLVMExtensions.StringSliceReferenceType, LLVMTypeRef.PointerType(LLVMExtensions.FileHandleType.CreateLLVMOptionType(), 0), }, false); BuildOpenFileHandleFunction(fileModule, externalFunctions); CommonModuleSignatures[ReadLineFromFileHandleName] = LLVMSharp.LLVM.FunctionType( LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.FileHandleType, 0), LLVMTypeRef.PointerType(LLVMExtensions.StringType.CreateLLVMOptionType(), 0), }, false); BuildReadLineFromFileHandleFunction(fileModule, externalFunctions); CommonModuleSignatures[WriteStringToFileHandleName] = LLVMSharp.LLVM.FunctionType( LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.FileHandleType, 0), LLVMExtensions.StringSliceReferenceType, }, false); BuildWriteStringToFileHandleFunction(fileModule, externalFunctions); CommonModuleSignatures[DropFileHandleName] = LLVMSharp.LLVM.FunctionType( LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.FileHandleType, 0), }, false); BuildDropFileHandleFunction(fileModule, externalFunctions); }
private static void BuildOutputStringSliceFunction(Module stringModule, CommonExternalFunctions externalFunctions) { LLVMValueRef outputStringSliceFunction = stringModule.AddFunction(OutputStringSliceName, CommonModuleSignatures[OutputStringSliceName]); LLVMBasicBlockRef entryBlock = outputStringSliceFunction.AppendBasicBlock("entry"); var builder = new IRBuilder(); builder.PositionBuilderAtEnd(entryBlock); LLVMValueRef stringSlice = outputStringSliceFunction.GetParam(0u); builder.CreateCall( externalFunctions.OutputStringFunction, new LLVMValueRef[] { builder.CreateExtractValue(stringSlice, 0u, "stringBufferPtr"), builder.CreateExtractValue(stringSlice, 1u, "stringSize") }, string.Empty); builder.CreateRetVoid(); }
private static void BuildStringAppendFunction(Module stringModule, CommonExternalFunctions externalFunctions) { _stringAppendFunction = stringModule.AddFunction(StringAppendName, CommonModuleSignatures[StringAppendName]); LLVMBasicBlockRef entryBlock = _stringAppendFunction.AppendBasicBlock("entry"); var builder = new IRBuilder(); builder.PositionBuilderAtEnd(entryBlock); LLVMValueRef stringPtr = _stringAppendFunction.GetParam(0u), sliceReference = _stringAppendFunction.GetParam(1u); // for now, always create a new allocation, rather than trying to use existing one // compute the new allocation size and allocate it LLVMValueRef stringAllocationPtrPtr = builder.CreateStructGEP(stringPtr, 0u, "stringAllocationPtrPtr"), stringSizePtr = builder.CreateStructGEP(stringPtr, 1u, "stringSizePtr"), stringAllocationPtr = builder.CreateLoad(stringAllocationPtrPtr, "stringAllocationPtr"), stringSize = builder.CreateLoad(stringSizePtr, "stringSize"), sliceSize = builder.CreateExtractValue(sliceReference, 1u, "sliceSize"), appendedSize = builder.CreateAdd(stringSize, sliceSize, "appendedSize"), newAllocationPtr = builder.CreateArrayMalloc(LLVMTypeRef.Int8Type(), appendedSize, "newAllocationPtr"); // copy from old allocation to new allocation LLVMValueRef stringSlice = builder.CreateCall(_stringFromSliceRetFunction, new LLVMValueRef[] { stringPtr }, "stringSlice"); builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { stringSlice, newAllocationPtr }, string.Empty); // copy from slice to offset in new allocation LLVMValueRef newAllocationOffsetPtr = builder.CreateGEP(newAllocationPtr, new LLVMValueRef[] { stringSize }, "newAllocationOffsetPtr"); builder.CreateCall(_copySliceToPointerFunction, new LLVMValueRef[] { sliceReference, newAllocationOffsetPtr }, string.Empty); // free old allocation and update string fields builder.CreateFree(stringAllocationPtr); builder.CreateStore(newAllocationPtr, stringAllocationPtrPtr); builder.CreateStore(appendedSize, stringSizePtr); builder.CreateRetVoid(); }
private static void BuildWriteStringToFileHandleFunction(Module fileModule, CommonExternalFunctions externalFunctions) { LLVMValueRef writeStringToFileHandleFunction = fileModule.AddFunction(WriteStringToFileHandleName, CommonModuleSignatures[WriteStringToFileHandleName]); LLVMBasicBlockRef entryBlock = writeStringToFileHandleFunction.AppendBasicBlock("entry"); var builder = new IRBuilder(); builder.PositionBuilderAtEnd(entryBlock); LLVMValueRef fileHandleStructPtr = writeStringToFileHandleFunction.GetParam(0u), fileHandlePtr = builder.CreateStructGEP(fileHandleStructPtr, 0u, "fileHandlePtr"), fileHandle = builder.CreateLoad(fileHandlePtr, "fileHandle"), stringSlice = writeStringToFileHandleFunction.GetParam(1u), stringSliceAllocationPtr = builder.CreateExtractValue(stringSlice, 0u, "stringSliceAllocationPtr"), stringSliceLength = builder.CreateExtractValue(stringSlice, 1u, "stringSliceLength"), bytesWrittenPtr = builder.CreateAlloca(LLVMTypeRef.Int32Type(), "bytesWrittenPtr"); builder.CreateCall( externalFunctions.WriteFileFunction, new LLVMValueRef[] { fileHandle, stringSliceAllocationPtr, stringSliceLength, bytesWrittenPtr, LLVMExtensions.NullVoidPointer }, "writeFileResult"); builder.CreateRetVoid(); }
private static void CreateStringModule(Module stringModule) { var externalFunctions = new CommonExternalFunctions(stringModule); CommonModuleSignatures[CopySliceToPointerName] = LLVMSharp.LLVM.FunctionType( LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { LLVMExtensions.StringSliceReferenceType, LLVMTypeRef.PointerType(LLVMTypeRef.Int8Type(), 0) }, false); BuildCopySliceToPointerFunction(stringModule, externalFunctions); CommonModuleSignatures[CreateEmptyStringName] = LLVMSharp.LLVM.FunctionType( LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0) }, false); BuildCreateEmptyStringFunction(stringModule); CommonModuleSignatures[CreateNullTerminatedStringFromSliceName] = LLVMSharp.LLVM.FunctionType( LLVMExtensions.BytePointerType, new LLVMTypeRef[] { LLVMExtensions.StringSliceReferenceType }, false); BuildCreateNullTerminatedStringFromSlice(stringModule); CommonModuleSignatures[DropStringName] = LLVMSharp.LLVM.FunctionType( LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0) }, false); BuildDropStringFunction(stringModule); CommonModuleSignatures[OutputStringSliceName] = LLVMSharp.LLVM.FunctionType( LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { LLVMExtensions.StringSliceReferenceType }, false); BuildOutputStringSliceFunction(stringModule, externalFunctions); CommonModuleSignatures[StringFromSliceName] = LLVMSharp.LLVM.FunctionType( LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { LLVMExtensions.StringSliceReferenceType, LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0) }, false); BuildStringFromSliceFunction(stringModule, externalFunctions); CommonModuleSignatures[StringToSliceRetName] = LLVMSharp.LLVM.FunctionType( LLVMExtensions.StringSliceReferenceType, new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0), }, false); BuildStringToSliceRetFunction(stringModule); CommonModuleSignatures[StringToSliceName] = LLVMSharp.LLVM.FunctionType( LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0), LLVMTypeRef.PointerType(LLVMExtensions.StringSliceReferenceType, 0) }, false); BuildStringToSliceFunction(stringModule); CommonModuleSignatures[StringAppendName] = LLVMSharp.LLVM.FunctionType( LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0), LLVMExtensions.StringSliceReferenceType }, false); BuildStringAppendFunction(stringModule, externalFunctions); CommonModuleSignatures[StringConcatName] = LLVMSharp.LLVM.FunctionType( LLVMSharp.LLVM.VoidType(), new LLVMTypeRef[] { LLVMExtensions.StringSliceReferenceType, LLVMExtensions.StringSliceReferenceType, LLVMTypeRef.PointerType(LLVMExtensions.StringType, 0) }, false); BuildStringConcatFunction(stringModule, externalFunctions); stringModule.VerifyAndThrowIfInvalid(); }
private static void BuildReadLineFromFileHandleFunction(Module fileModule, CommonExternalFunctions externalFunctions) { LLVMValueRef readLineFromFileHandleFunction = fileModule.AddFunction(ReadLineFromFileHandleName, CommonModuleSignatures[ReadLineFromFileHandleName]); LLVMBasicBlockRef entryBlock = readLineFromFileHandleFunction.AppendBasicBlock("entry"); var builder = new IRBuilder(); builder.PositionBuilderAtEnd(entryBlock); LLVMBasicBlockRef loopStartBlock = readLineFromFileHandleFunction.AppendBasicBlock("loopStart"), handleByteBlock = readLineFromFileHandleFunction.AppendBasicBlock("handleByte"), byteIsCRBlock = readLineFromFileHandleFunction.AppendBasicBlock("byteIsCR"), byteIsNotCRBlock = readLineFromFileHandleFunction.AppendBasicBlock("byteIsNotCR"), notNewLineBlock = readLineFromFileHandleFunction.AppendBasicBlock("notNewLine"), appendCRBlock = readLineFromFileHandleFunction.AppendBasicBlock("appendCR"), appendByteBlock = readLineFromFileHandleFunction.AppendBasicBlock("appendByte"), loopEndBlock = readLineFromFileHandleFunction.AppendBasicBlock("loopEnd"), nonEmptyStringBlock = readLineFromFileHandleFunction.AppendBasicBlock("nonEmptyString"), emptyStringBlock = readLineFromFileHandleFunction.AppendBasicBlock("emptyString"); LLVMValueRef fileHandlePtr = readLineFromFileHandleFunction.GetParam(0u), stringPtr = builder.CreateAlloca(LLVMExtensions.StringType, "stringPtr"), carriageReturnPtr = builder.CreateAlloca(LLVMTypeRef.Int8Type(), "carriageReturnPtr"), carriageReturn = ((byte)0xD).AsLLVMValue(), byteReadPtr = builder.CreateAlloca(LLVMTypeRef.Int8Type(), "byteReadPtr"), bytesReadPtr = builder.CreateAlloca(LLVMTypeRef.Int32Type(), "bytesReadPtr"), nonEmptyStringPtr = builder.CreateAlloca(LLVMTypeRef.Int1Type(), "nonEmptyStringPtr"), seenCRPtr = builder.CreateAlloca(LLVMTypeRef.Int1Type(), "seenCRPtr"); builder.CreateStore(carriageReturn, carriageReturnPtr); builder.CreateStore(false.AsLLVMValue(), seenCRPtr); builder.CreateStore(false.AsLLVMValue(), nonEmptyStringPtr); builder.CreateCall(_createEmptyStringFunction, new LLVMValueRef[] { stringPtr }, string.Empty); builder.CreateBr(loopStartBlock); builder.PositionBuilderAtEnd(loopStartBlock); LLVMValueRef hFilePtr = builder.CreateStructGEP(fileHandlePtr, 0u, "hFilePtr"), hFile = builder.CreateLoad(hFilePtr, "hFile"); LLVMValueRef readFileResult = builder.CreateCall( externalFunctions.ReadFileFunction, new LLVMValueRef[] { hFile, byteReadPtr, 1.AsLLVMValue(), bytesReadPtr, LLVMExtensions.NullVoidPointer }, "readFileResult"), readFileResultBool = builder.CreateICmp(LLVMIntPredicate.LLVMIntNE, readFileResult, 0.AsLLVMValue(), "readFileResultBool"), bytesRead = builder.CreateLoad(bytesReadPtr, "bytesRead"), zeroBytesRead = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, bytesRead, 0.AsLLVMValue(), "zeroBytesRead"), eof = builder.CreateAnd(readFileResultBool, zeroBytesRead, "eof"); builder.CreateCondBr(eof, loopEndBlock, handleByteBlock); builder.PositionBuilderAtEnd(handleByteBlock); LLVMValueRef byteRead = builder.CreateLoad(byteReadPtr, "byteRead"), byteReadIsCR = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, byteRead, carriageReturn, "byteReadIsCR"); builder.CreateCondBr(byteReadIsCR, byteIsCRBlock, byteIsNotCRBlock); builder.PositionBuilderAtEnd(byteIsCRBlock); builder.CreateStore(true.AsLLVMValue(), seenCRPtr); builder.CreateBr(loopStartBlock); builder.PositionBuilderAtEnd(byteIsNotCRBlock); LLVMValueRef byteIsLF = builder.CreateICmp(LLVMIntPredicate.LLVMIntEQ, byteRead, ((byte)0xA).AsLLVMValue(), "byteIsLF"), seenCR = builder.CreateLoad(seenCRPtr, "seenCR"), newLine = builder.CreateAnd(byteIsLF, seenCR, "newLine"); builder.CreateCondBr(newLine, loopEndBlock, notNewLineBlock); builder.PositionBuilderAtEnd(notNewLineBlock); builder.CreateCondBr(seenCR, appendCRBlock, appendByteBlock); builder.PositionBuilderAtEnd(appendCRBlock); LLVMValueRef crSlice = builder.BuildStringSliceReferenceValue(carriageReturnPtr, 1.AsLLVMValue()); builder.CreateCall(_stringAppendFunction, new LLVMValueRef[] { stringPtr, crSlice }, string.Empty); builder.CreateBr(appendByteBlock); builder.PositionBuilderAtEnd(appendByteBlock); LLVMValueRef byteSlice = builder.BuildStringSliceReferenceValue(byteReadPtr, 1.AsLLVMValue()); builder.CreateCall(_stringAppendFunction, new LLVMValueRef[] { stringPtr, byteSlice }, string.Empty); builder.CreateStore(true.AsLLVMValue(), nonEmptyStringPtr); builder.CreateStore(false.AsLLVMValue(), seenCRPtr); builder.CreateBr(loopStartBlock); builder.PositionBuilderAtEnd(loopEndBlock); LLVMValueRef optionStringPtr = readLineFromFileHandleFunction.GetParam(1u), optionStringIsSomePtr = builder.CreateStructGEP(optionStringPtr, 0u, "optionStringIsSomePtr"), nonEmptyString = builder.CreateLoad(nonEmptyStringPtr, "nonEmptyString"); builder.CreateCondBr(nonEmptyString, nonEmptyStringBlock, emptyStringBlock); builder.PositionBuilderAtEnd(nonEmptyStringBlock); builder.CreateStore(true.AsLLVMValue(), optionStringIsSomePtr); LLVMValueRef optionStringInnerValuePtr = builder.CreateStructGEP(optionStringPtr, 1u, "optionStringInnerValuePtr"), stringValue = builder.CreateLoad(stringPtr, "string"); builder.CreateStore(stringValue, optionStringInnerValuePtr); builder.CreateRetVoid(); builder.PositionBuilderAtEnd(emptyStringBlock); builder.CreateStore(false.AsLLVMValue(), optionStringIsSomePtr); builder.CreateCall(_dropStringFunction, new LLVMValueRef[] { stringPtr }, string.Empty); builder.CreateRetVoid(); }