コード例 #1
0
        /// <summary>
        /// Creates the System.String::get_Chars(int32) function.
        /// </summary>
        /// <param name="builder">The builder.</param>
        private void createStringGetCharsFunction(BuilderRef builder)
        {
            const string funcName = "System_Char_System_String_get_Chars_System_Int32";

            // Create function and set linkage.
            TypeRef  type = LLVM.FunctionType(TypeHelper.Int8, new TypeRef[] { TypeHelper.String, TypeHelper.Int32 }, false);
            ValueRef func = LLVM.AddFunction(mCompiler.Module, funcName, type);

            LLVM.SetLinkage(func, Linkage.LinkOnceAnyLinkage);
            LLVM.AddAttributeAtIndex(func, (uint)LLVM.AttributeFunctionIndex, LLVM.CreateEnumAttribute(mCompiler.ModuleContext, LLVM.GetEnumAttributeKindForName("alwaysinline", 12), 1));

            // Arguments.
            ValueRef str   = LLVM.GetParam(func, 0);
            ValueRef index = LLVM.GetParam(func, 1);

            // Create function body.
            BasicBlockRef entry = LLVM.AppendBasicBlock(func, string.Empty);

            LLVM.PositionBuilderAtEnd(builder, entry);
            ValueRef ch        = LLVM.BuildGEP(builder, str, new ValueRef[] { index }, "charptr");
            ValueRef returnVal = LLVM.BuildLoad(builder, ch, "character");

            LLVM.BuildRet(builder, returnVal);

            mCompiler.Lookup.AddFunction(funcName, func);
        }
コード例 #2
0
        private LLVMValueRef DeclareLocal(IMethod method)
        {
            var funType = GetFunctionPrototype(method);
            var result  = LLVM.AddFunction(Module, Mangler.Mangle(method, true), funType);

            result.SetLinkage(GetLinkageForLocal(method));
            if (!method.IsStatic)
            {
                LLVM.AddAttributeAtIndex(result, (LLVMAttributeIndex)1, CreateEnumAttribute("nonnull"));
            }
            return(result);
        }
コード例 #3
0
        public LLVMValueRef EmitMethodHeader(string pName, Syntax.MethodSyntax pMethod, out string pNewName)
        {
            //Get method return type
            LLVMTypeRef ret;

            if (pMethod.ReturnValues.Count == 0)
            {
                ret = LLVMTypeRef.VoidType();
            }
            else if (pMethod.ReturnValues.Count == 1)
            {
                ret = SmallTypeCache.GetLLVMType(pMethod.Type, this);
            }
            else
            {
                LLVMTypeRef[] types = new LLVMTypeRef[pMethod.ReturnValues.Count];
                for (int i = 0; i < types.Length; i++)
                {
                    types[i] = SmallTypeCache.GetLLVMType(pMethod.ReturnValues[i].Type, this);
                }
                ret = LLVM.StructType(types, false);
                Cache.SetLLVMType(pMethod.Type.Name, ret);
            }

            //If we are emitting a struct method we need to add "self" as a parameter
            SmallType[]   originalTypes = new SmallType[pMethod.Parameters.Count];
            LLVMTypeRef[] parmTypes     = null;
            int           start         = 0;

            if (CurrentStruct != null)
            {
                parmTypes    = new LLVMTypeRef[pMethod.Parameters.Count + 1];
                parmTypes[0] = LLVMTypeRef.PointerType(SmallTypeCache.GetLLVMType(CurrentStruct, this), 0);
                start        = 1;
            }
            else
            {
                parmTypes = new LLVMTypeRef[pMethod.Parameters.Count];
            }

            //Get parameter types
            for (int i = 0; i < pMethod.Parameters.Count; i++)
            {
                var parmType = pMethod.Parameters[i].Type;
                if (parmType.IsGenericParameter)
                {
                    originalTypes[i] = TypeMappings[parmType.Name];
                }
                else
                {
                    originalTypes[i] = parmType;
                }

                //For calling external methods with strings, we only want to pass the character array
                if (pMethod.External && parmType == SmallTypeCache.String)
                {
                    parmType = parmType.GetElementType();
                }

                parmTypes[start + i] = SmallTypeCache.GetLLVMType(parmType, this);
                if (pMethod.Parameters[i].Type.IsStruct || pMethod.Parameters[i].Type.IsArray)
                {
                    parmTypes[start + i] = LLVMTypeRef.PointerType(parmTypes[start + i], 0);
                }
            }

            var result = Cache.FindMethod(out MethodDefinition pDefinition, null, CurrentStruct, pName, originalTypes);

            Debug.Assert(result == Compiler.FindResult.Found);
            pNewName = pDefinition.MangledName;

            //Method header
            var func = LLVM.GetNamedFunction(CurrentModule, pNewName);

            if (func.Pointer == IntPtr.Zero)
            {
                func = LLVM.AddFunction(CurrentModule, pNewName, LLVM.FunctionType(ret, parmTypes, false));
                LLVM.SetLinkage(func, LLVMLinkage.LLVMExternalLinkage);
            }

            if (pMethod.External)
            {
                //Create attribute so we can find it later when executing
                var attribute = LLVM.CreateStringAttribute(_context, "external", 8, pMethod.Annotation.Value, (uint)pMethod.Annotation.Value.Length);
                LLVM.AddAttributeAtIndex(func, LLVMAttributeIndex.LLVMAttributeFunctionIndex, attribute);
            }

            return(func);
        }
コード例 #4
0
        public static void AddFunctionParamAttribute(this LLVMValueRef self, LLVMContextRef context, int param, LLVMAttributeKind kind, uint value = 0)
        {
            var att = LLVM.CreateEnumAttribute(context, kind.ToUInt(), value);

            LLVM.AddAttributeAtIndex(self, (LLVMAttributeIndex)(param + 1), att);
        }
コード例 #5
0
        public static void AddFunctionReturnAttribute(this LLVMValueRef self, LLVMContextRef context, LLVMAttributeKind kind, uint value = 0)
        {
            var att = LLVM.CreateEnumAttribute(context, kind.ToUInt(), value);

            LLVM.AddAttributeAtIndex(self, LLVMAttributeIndex.LLVMAttributeReturnIndex, att);
        }