Пример #1
0
        public bool VisitConstant(Constant constant)
        {
            ValueSource outputAllocation = GetTerminalValueSource(constant.OutputTerminal);

            if (constant.DataType.IsInteger())
            {
                LLVMValueRef constantValueRef;
                switch (constant.DataType.GetKind())
                {
                case NITypeKind.Int8:
                    constantValueRef = ((sbyte)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.UInt8:
                    constantValueRef = ((byte)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.Int16:
                    constantValueRef = ((short)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.UInt16:
                    constantValueRef = ((ushort)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.Int32:
                    constantValueRef = ((int)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.UInt32:
                    constantValueRef = ((uint)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.Int64:
                    constantValueRef = ((long)constant.Value).AsLLVMValue();
                    break;

                case NITypeKind.UInt64:
                    constantValueRef = ((ulong)constant.Value).AsLLVMValue();
                    break;

                default:
                    throw new NotSupportedException("Unsupported numeric constant type: " + constant.DataType);
                }
                outputAllocation.UpdateValue(_builder, constantValueRef);
            }
            else if (constant.Value is bool)
            {
                LLVMValueRef constantValueRef = ((bool)constant.Value).AsLLVMValue();
                outputAllocation.UpdateValue(_builder, constantValueRef);
            }
            else if (constant.Value is string)
            {
                VariableReference output = constant.OutputTerminal.GetTrueVariable();
                if (output.Type.IsRebarReferenceType() && output.Type.GetReferentType() == DataTypes.StringSliceType)
                {
                    string       stringValue         = (string)constant.Value;
                    int          length              = Encoding.UTF8.GetByteCount(stringValue);
                    LLVMValueRef stringValueConstant = LLVMSharp.LLVM.ConstString(stringValue, (uint)length, true);
                    LLVMValueRef stringConstantPtr   = Module.AddGlobal(stringValueConstant.TypeOf(), $"string{constant.UniqueId}");
                    stringConstantPtr.SetInitializer(stringValueConstant);

                    LLVMValueRef castPointer = _builder.CreateBitCast(
                        stringConstantPtr,
                        LLVMTypeRef.PointerType(LLVMTypeRef.Int8Type(), 0),
                        "ptrCast");
                    LLVMValueRef[] stringSliceFields = new LLVMValueRef[]
                    {
                        castPointer,
                        length.AsLLVMValue()
                    };
                    LLVMValueRef stringSliceValue = LLVMValueRef.ConstStruct(stringSliceFields, false);
                    outputAllocation.UpdateValue(_builder, stringSliceValue);
                }
            }
            else
            {
                throw new NotImplementedException();
            }
            return(true);
        }