Esempio n. 1
0
        public ClepsType GetClepsNativeLLVMType(LLVMTypeRef llvmType)
        {
            if (llvmType.TypeKind == LLVMTypeKind.LLVMIntegerTypeKind)
            {
                if (llvmType.GetIntTypeWidth() == 1)
                {
                    return(ClepsType.GetBasicType("System.LLVMTypes.I1", 0 /* ptr indirection level */));
                }
                else if (llvmType.GetIntTypeWidth() == 32)
                {
                    return(ClepsType.GetBasicType("System.LLVMTypes.I32", 0 /* ptr indirection level */));
                }
            }
            else if (llvmType.TypeKind == LLVMTypeKind.LLVMVoidTypeKind)
            {
                //void type does not have a special implementation in Cleps - use the same thing for LLVM or cleps native types
                return(ClepsType.GetVoidType());
            }

            throw new Exception("Unknown llvm type - cannot convert to cleps native type");
        }
Esempio n. 2
0
        private void AddEntryPoint(ClassManager classManager, CompileStatus status, LLVMContextRef context, LLVMModuleRef module, LLVMBuilderRef builder)
        {
            LLVMTypeRef       functionType  = LLVM.FunctionType(LLVM.Int32TypeInContext(context), new LLVMTypeRef[] { }, false);
            LLVMValueRef      functionValue = LLVM.AddFunction(module, "main", functionType);
            LLVMBasicBlockRef blockValue    = LLVM.AppendBasicBlockInContext(context, functionValue, "entry");

            LLVM.PositionBuilderAtEnd(builder, blockValue);

            LLVMValueRef intRet = LLVM.ConstInt(LLVM.Int32Type(), 0, false);

            if (classManager.MainFunctionFullNames.Count < 1)
            {
                status.AddError(new CompilerError("", 0, 0, "No main functions found in the program"));
            }
            else if (classManager.MainFunctionFullNames.Count > 1)
            {
                status.AddError(new CompilerError("", 0, 0, "Multiple main functions found in the program: " + String.Join(",", classManager.MainFunctionFullNames)));
            }
            else
            {
                LLVMValueRef functionToCall        = LLVM.GetNamedFunction(module, classManager.MainFunctionFullNames.First());
                LLVMValueRef intOrIntMappedTypeRet = LLVM.BuildCall(builder, functionToCall, new LLVMValueRef[0], "entryPointCall");
                LLVMTypeRef  returnType            = LLVM.TypeOf(intOrIntMappedTypeRet);

                if (returnType.TypeKind == LLVMTypeKind.LLVMIntegerTypeKind && returnType.GetIntTypeWidth() == 32)
                {
                    intRet = intOrIntMappedTypeRet;
                }
                else
                {
                    LLVMValueRef intMappedTypeRetPtr = LLVM.BuildAlloca(builder, LLVM.TypeOf(intOrIntMappedTypeRet), "intMappedType");
                    LLVM.BuildStore(builder, intOrIntMappedTypeRet, intMappedTypeRetPtr);
                    //Extract the first field to get the int value from the mapped type
                    //See rawtypemap for more details
                    LLVMValueRef fieldPtr = LLVM.BuildStructGEP(builder, intMappedTypeRetPtr, 0, "returnIntFieldPtr");
                    intRet = LLVM.BuildLoad(builder, fieldPtr, "returnValue");
                }
            }

            LLVM.BuildRet(builder, intRet);
        }
Esempio n. 3
0
        public LLVMValueRef BuildCast(LLVMBuilderRef builder, LLVMValueRef elem, LLVMTypeRef targetType)
        {
            // Check if the type of the element equals the targe type
            if (CompareType(elem, targetType))
            {
                // There is no need to cast
                // Just return the element
                return(elem);
            }

            // Strings need special handling
            if (CompareType(targetType, StringType))
            {
                LLVMValueRef indices;
                var          gep = LLVM.BuildGEP(builder, elem, out indices, 0u, "tmpgep");
                var          ptr = LLVM.BuildPointerCast(builder, gep, StringType, "tmpptrcast");
                return(ptr);
            }

            string strtype1, strtype2;

            switch (targetType.TypeKind)
            {
            case LLVMTypeKind.LLVMIntegerTypeKind:

                // Check if the integer fits
                if (IsInteger(elem))
                {
                    var lwidth = elem.TypeOf().GetIntTypeWidth();
                    var rwidth = targetType.GetIntTypeWidth();
                    if (lwidth > rwidth)
                    {
                        // The width of the result type is higher
                        // than the width of the element type
                        // Throw an exception
                        strtype1 = elem.TypeOf().PrintTypeToString();
                        strtype2 = targetType.PrintTypeToString();
                        throw LoreException.Create(Visitor.Location)
                              .Describe($"Unable to cast element of type '{strtype1}' to '{strtype2}':")
                              .Describe($"The element is too big for the target integer type.");
                    }
                }

                // Perform a float to signed integer cast if needed
                else if (IsFloatOrDouble(elem))
                {
                    elem = LLVM.BuildFPToSI(builder, elem, targetType, "tmpfptosicast");
                }

                // Unsupported element type
                else
                {
                    // Unable to perform a meaningful cast
                    strtype1 = elem.TypeOf().PrintTypeToString();
                    strtype2 = targetType.PrintTypeToString();
                    throw LoreException.Create(Visitor.Location).Describe($"Unable to cast element of type '{strtype1}' to '{strtype2}':");
                }

                // Perform an integer cast
                return(LLVM.BuildIntCast(builder, elem, targetType, "tmpcast"));

            case LLVMTypeKind.LLVMFloatTypeKind:
            case LLVMTypeKind.LLVMDoubleTypeKind:

                // Perform a signed integer to float cast if needed
                if (IsInteger(elem))
                {
                    elem = LLVM.BuildSIToFP(builder, elem, targetType, "tmpsitofpcast");
                }
                return(LLVM.BuildFPCast(builder, elem, targetType, "tmpfcast"));
            }

            // Unable to perform a meaningful cast
            strtype1 = elem.TypeOf().PrintTypeToString();
            strtype2 = targetType.PrintTypeToString();
            throw LoreException.Create(Visitor.Location).Describe($"Unable to cast element of type '{strtype1}' to '{strtype2}':");
        }