/// <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); }
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); }
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); }
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); }
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); }