public override LLVMValueRef Emit(EmittingContext pContext) { pContext.EmitDebugLocation(this); var variable = pContext.AllocateVariable("string_temp", this); var literal = EscapeString(); //Save length var length = pContext.GetArrayLength(variable); LLVM.BuildStore(pContext.Builder, pContext.GetInt(literal.Length), length); //Allocate space for our string LLVMValueRef dataArray; using (var b = new VariableDeclarationBuilder(pContext)) { var charArray = LLVMTypeRef.ArrayType(SmallTypeCache.GetLLVMType(SmallTypeCache.Char, pContext), (uint)(literal.Length + 1)); //Need to allocate 1 more space for the /0 dataArray = LLVM.BuildAlloca(b.Builder, charArray, ""); } //Store the string constant in the allocated array var data = pContext.GetString(literal); LLVM.BuildStore(pContext.Builder, data, dataArray); //Store the allocated array in the string variable var dataAccess = LLVM.BuildInBoundsGEP(pContext.Builder, dataArray, new LLVMValueRef[] { pContext.GetInt(0), pContext.GetInt(0) }, ""); var variableData = LLVM.BuildInBoundsGEP(pContext.Builder, variable, new LLVMValueRef[] { pContext.GetInt(0), pContext.GetInt(1) }, ""); LLVM.BuildStore(pContext.Builder, dataAccess, variableData); return(variable); }
public override LLVMValueRef Emit(EmittingContext pContext) { pContext.EmitDebugLocation(this); var variable = pContext.AllocateVariable("array_temp", this); var size = Size.Emit(pContext); var length = pContext.GetArrayLength(variable); LLVM.BuildStore(pContext.Builder, size, length); var data = pContext.AllocateArrayLiteral(Type.GetElementType(), size); var variableData = LLVM.BuildInBoundsGEP(pContext.Builder, variable, new LLVMValueRef[] { pContext.GetInt(0), pContext.GetInt(1) }, ""); LLVM.BuildStore(pContext.Builder, data, variableData); return(variable); }
public override LLVMValueRef Emit(EmittingContext pContext) { pContext.EmitDebugLocation(this); LLVMValueRef value; switch (Operator) { case UnaryExpressionOperator.Not: value = Value.Emit(pContext); Utils.LlvmHelper.LoadIfPointer(ref value, pContext); return(LLVM.BuildNot(pContext.Builder, value, "")); case UnaryExpressionOperator.Negative: value = Value.Emit(pContext); Utils.LlvmHelper.LoadIfPointer(ref value, pContext); return(LLVM.BuildNeg(pContext.Builder, value, "")); case UnaryExpressionOperator.Length: var arr = Value.Emit(pContext); return(LLVM.BuildLoad(pContext.Builder, pContext.GetArrayLength(arr), "")); case UnaryExpressionOperator.PreIncrement: case UnaryExpressionOperator.PreDecrement: case UnaryExpressionOperator.PostIncrement: case UnaryExpressionOperator.PostDecrement: var variable = (IdentifierSyntax)Value; variable.DoNotLoad = true; LLVMValueRef v = variable.Emit(pContext); BinaryExpressionOperator op = BinaryExpressionOperator.Equals; switch (Operator) { case UnaryExpressionOperator.PostDecrement: case UnaryExpressionOperator.PreDecrement: op = BinaryExpressionOperator.Subtraction; break; case UnaryExpressionOperator.PostIncrement: case UnaryExpressionOperator.PreIncrement: op = BinaryExpressionOperator.Addition; break; } value = BinaryExpressionSyntax.EmitOperator(v, op, pContext.GetInt(1), pContext); //Post unary we want to return the original variable value if (Operator == UnaryExpressionOperator.PostIncrement || Operator == UnaryExpressionOperator.PostDecrement) { //Save the old value to a temp variable that we will return var temp = pContext.AllocateVariable("<temp_unary>", Value); LLVMValueRef tempValue = Utils.LlvmHelper.IsPointer(v) ? LLVM.BuildLoad(pContext.Builder, v, "") : v; LLVM.BuildStore(pContext.Builder, tempValue, temp); //Increment the variable Utils.LlvmHelper.LoadIfPointer(ref value, pContext); if (Value.SyntaxType == SyntaxType.Identifier || Value.SyntaxType == SyntaxType.MemberAccess) { LLVM.BuildStore(pContext.Builder, value, v); } return(temp); } //If it isn't a variable we cane save we need to return the addition if (Value.SyntaxType == SyntaxType.Identifier || Value.SyntaxType == SyntaxType.MemberAccess) { LLVM.BuildStore(pContext.Builder, value, v); } return(value); default: throw new NotSupportedException(); } }