Exemplo n.º 1
0
        /// <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));
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        /// <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);
            }
        }