/// <summary> /// Defines the data layout of this type as an LLVM type. /// </summary> /// <param name="Module">The module to define the type in.</param> /// <returns>An LLVM type ref for this type's data layout.</returns> public LLVMTypeRef DefineLayout(LLVMModuleBuilder Module) { if (IsRuntimeImplementedDelegate) { return(DelegateBlock.MethodTypeLayout); } if (this.GetIsEnum()) { return(Module.Declare(this.GetParent())); } bool isStruct = this.GetIsValueType(); if (isStruct && IsSingleValue) { return(Module.Declare(declaredInstanceFields[0].FieldType)); } int offset = isStruct ? 0 : 1; var elementTypes = new LLVMTypeRef[offset + declaredInstanceFields.Count]; if (!isStruct) { var baseType = this.GetParent(); if (baseType == null) { // Type is a root type. Embed a pointer to its vtable. elementTypes[0] = Module.Declare( PrimitiveTypes.UInt8.MakePointerType( PointerKind.TransientPointer)); } else { // Type is not a root type. Embed its base type. elementTypes[0] = Module.DeclareDataLayout((LLVMType)baseType); } } for (int i = 0; i < elementTypes.Length - offset; i++) { elementTypes[i + offset] = Module.Declare( declaredInstanceFields[i].FieldType); } return(StructType(elementTypes, false)); }
private static LLVMValueRef DeclareCxaVoidPointerRtti( LLVMModuleBuilder ModuleBuilder, LLVMModuleRef LLVMModule) { var type = PrimitiveTypes.Void.MakePointerType(PointerKind.TransientPointer); var result = ModuleBuilder.DeclareGlobal(ModuleBuilder.Declare(type), "_ZTIPv"); result.SetGlobalConstant(true); return(result); }
/// <summary> /// Writes this method definitions to the given module. /// </summary> /// <param name="Module">The module to populate.</param> public void Emit(LLVMModuleBuilder Module) { if (this.GetRecursiveGenericParameters().Any <IType>()) { throw new NotSupportedException("LLVM methods do not support generic parameters"); } if (!DeclaringType.GetIsInterface() && !this.GetIsAbstract()) { var func = Module.Declare(this); func.SetLinkage(Linkage); var methodBody = this.body; if (methodBody == null && this.HasAttribute( PrimitiveAttributes.Instance.RuntimeImplementedAttribute.AttributeType)) { // Auto-implement runtime-implemented methods here. methodBody = (CodeBlock)AutoImplement().Emit(codeGenerator); } if (methodBody != null) { // Generate the method body. var bodyBuilder = new FunctionBodyBuilder(Module, func); var entryPointBuilder = bodyBuilder.AppendBasicBlock("entry"); entryPointBuilder = codeGenerator.Prologue.Emit(entryPointBuilder); var codeGen = methodBody.Emit(entryPointBuilder); BuildUnreachable(codeGen.BasicBlock.Builder); } } foreach (var iface in allInterfaceImpls.Value) { Module.GetInterfaceStub(iface).Implement(ParentType, this); } }