Example #1
0
 private LLVMBasicBlockRef WriteReturnBlock(
     LLVMType Type,
     LLVMMethod Implementation,
     LLVMModuleBuilder Module)
 {
     return(WriteReturnBlock(Type.Name.ToString(), Module.DeclareVirtual(Implementation)));
 }
Example #2
0
 /// <summary>
 /// Writes this type's definitions to the given module.
 /// </summary>
 /// <param name="Module">The module to populate.</param>
 public void Emit(LLVMModuleBuilder Module)
 {
     foreach (var accessors in declaredAccessors)
     {
         accessors.Emit(Module);
     }
 }
Example #3
0
        private static LLVMValueRef DeclareGxxPersonalityV0(
            LLVMModuleBuilder ModuleBuilder, LLVMModuleRef LLVMModule)
        {
            var funcType = FunctionType(Int32Type(), new LLVMTypeRef[] { }, true);
            var result   = AddFunction(LLVMModule, "__gxx_personality_v0", funcType);

            return(result);
        }
Example #4
0
        public LLVMModuleRef ToModule()
        {
            var module        = ModuleCreateWithName(Name.ToString());
            var moduleBuilder = new LLVMModuleBuilder(this, module);

            rootNamespace.Emit(moduleBuilder);
            moduleBuilder.EmitStubs();
            return(module);
        }
Example #5
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);
        }
Example #6
0
 private static LLVMValueRef DeclareFromSignature(
     IMethod Signature,
     LLVMModuleBuilder ModuleBuilder,
     LLVMModuleRef LLVMModule)
 {
     return(AddFunction(
                LLVMModule,
                Signature.Name.ToString(),
                ModuleBuilder.DeclarePrototype(Signature)));
 }
Example #7
0
 /// <summary>
 /// Writes this namespace's definitions to the given module.
 /// </summary>
 /// <param name="Module">The module to populate.</param>
 public void Emit(LLVMModuleBuilder Module)
 {
     for (int i = 0; i < declaredNamespaces.Count; i++)
     {
         declaredNamespaces[i].Emit(Module);
     }
     for (int i = 0; i < declaredTypes.Count; i++)
     {
         declaredTypes[i].Emit(Module);
     }
 }
Example #8
0
        /// <summary>
        /// Defines the vtable for this type.
        /// </summary>
        /// <param name="Module">The module to define the vtable in.</param>
        /// <returns>An LLVM global for this type's vtable.</returns>
        public VTableInstance DefineVTable(LLVMModuleBuilder Module)
        {
            var allEntries = new List <LLVMMethod>();

            GetAllVTableEntries(allEntries);
            return(new VTableInstance(
                       DefineVTableGlobal(
                           Module,
                           this,
                           GetVTableEntryImpls(Module, allEntries)), allEntries));
        }
Example #9
0
 /// <summary>
 /// Writes this type's definitions to the given module.
 /// </summary>
 /// <param name="Module">The module to populate.</param>
 public void Emit(LLVMModuleBuilder Module)
 {
     foreach (var method in declaredMethods)
     {
         method.Emit(Module);
     }
     foreach (var property in declaredProperties)
     {
         property.Emit(Module);
     }
 }
Example #10
0
        private LLVMValueRef[] GetVTableEntryImpls(
            LLVMModuleBuilder Module,
            List <LLVMMethod> AllEntries)
        {
            var allImpls = new LLVMValueRef[AllEntries.Count];

            for (int i = 0; i < allImpls.Length; i++)
            {
                allImpls[i] = ConstBitCast(
                    Module.DeclareVirtual(AllEntries[i].GetImplementation(this) ?? AllEntries[i]),
                    PointerType(Int8Type(), 0));
            }
            return(allImpls);
        }
Example #11
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));
        }
Example #12
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);
            }
        }
Example #13
0
        /// <summary>
        /// Defines the global variable that backs a vtable.
        /// </summary>
        /// <param name="Module">The module to declare the global in.</param>
        /// <param name="Type">The type that owns the vtable.</param>
        /// <param name="VTableEntryImpls">
        /// The list of virtual function pointers in the vtable.
        /// </param>
        /// <returns>A vtable global variable.</returns>
        public static LLVMValueRef DefineVTableGlobal(
            LLVMModuleBuilder Module,
            IType Type,
            LLVMValueRef[] VTableEntryImpls)
        {
            var fields = new LLVMValueRef[3];

            fields[0] = ConstInt(Int64Type(), Module.GetTypeId(Type), false);
            fields[1] = ConstInt(Int64Type(), Module.GetTypeIndex(Type), false);
            fields[2] = ConstArray(
                PointerType(Int8Type(), 0),
                VTableEntryImpls);
            var vtableContents = ConstStruct(fields, false);
            var vtable         = Module.DeclareGlobal(
                vtableContents.TypeOf(),
                Type.FullName.ToString() + ".vtable");

            vtable.SetGlobalConstant(true);
            vtable.SetLinkage(LLVMLinkage.LLVMInternalLinkage);
            vtable.SetInitializer(vtableContents);
            return(vtable);
        }
Example #14
0
        /// <summary>
        /// Defines this stub's body.
        /// </summary>
        /// <param name="Module">The module that defines the stub.</param>
        public void Emit(LLVMModuleBuilder Module)
        {
            var entryBlock = AppendBasicBlock(Function, "entry");

            var defaultBlock = AppendBasicBlock(Function, "unknown_type");
            var builder      = CreateBuilder();

            PositionBuilderAtEnd(builder, defaultBlock);
            BuildUnreachable(builder);
            DisposeBuilder(builder);

            builder = CreateBuilder();
            PositionBuilderAtEnd(builder, entryBlock);
            var switchInstr = BuildSwitch(builder, GetParam(Function, 0), defaultBlock, (uint)impls.Count);

            foreach (var pair in impls)
            {
                switchInstr.AddCase(
                    ConstInt(Int64Type(), (ulong)Module.GetTypeIndex(pair.Key), false),
                    WriteReturnBlock(pair.Key, pair.Value, Module));
            }
            DisposeBuilder(builder);
        }
Example #15
0
 private static LLVMValueRef DeclareCxaEndCatch(
     LLVMModuleBuilder ModuleBuilder, LLVMModuleRef LLVMModule)
 {
     return(DeclareFromSignature(CxaEndCatchSignature, ModuleBuilder, LLVMModule));
 }
Example #16
0
 private static LLVMValueRef DeclareCxaAllocateException(
     LLVMModuleBuilder ModuleBuilder, LLVMModuleRef LLVMModule)
 {
     return(DeclareFromSignature(CxaAllocateExceptionSignature, ModuleBuilder, LLVMModule));
 }
Example #17
0
 /// <summary>
 /// Declares this intrinsic in the given module.
 /// </summary>
 /// <param name="ModuleBuilder">The module builder for the module to declare the intrinsic in.</param>
 /// <param name="LLVMModule">The module to declare the intrinsic in.</param>
 /// <returns>The intrinsic's declaration.</returns>
 public LLVMValueRef Declare(LLVMModuleBuilder ModuleBuilder, LLVMModuleRef LLVMModule)
 {
     return(declareIntrinsic(ModuleBuilder, LLVMModule));
 }
Example #18
0
 private static LLVMValueRef DeclareCxaRethrow(
     LLVMModuleBuilder ModuleBuilder, LLVMModuleRef LLVMModule)
 {
     return(DeclareFromSignature(CxaRethrowSignature, ModuleBuilder, LLVMModule));
 }