示例#1
0
        private ValueRef CreateDebugType(FunctionCompilerContext functionContext, Type type)
        {
            var size  = LLVM.ABISizeOfType(targetData, type.DefaultType) * 8;
            var align = LLVM.ABIAlignmentOfType(targetData, type.DefaultType) * 8;

            switch (type.TypeReference.MetadataType)
            {
            case MetadataType.Boolean:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "bool", size, align, (uint)DW_ATE.Boolean));

            case MetadataType.SByte:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "sbyte", size, align, (uint)DW_ATE.Signed));

            case MetadataType.Byte:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "byte", size, align, (uint)DW_ATE.Unsigned));

            case MetadataType.Int16:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "short", size, align, (uint)DW_ATE.Signed));

            case MetadataType.UInt16:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "ushort", size, align, (uint)DW_ATE.Unsigned));

            case MetadataType.Int32:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "int", size, align, (uint)DW_ATE.Signed));

            case MetadataType.UInt32:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "uint", size, align, (uint)DW_ATE.Unsigned));

            case MetadataType.Int64:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "long", size, align, (uint)DW_ATE.Signed));

            case MetadataType.UInt64:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "ulong", size, align, (uint)DW_ATE.Unsigned));

            case MetadataType.Single:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "float", size, align, (uint)DW_ATE.Float));

            case MetadataType.Double:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "double", size, align, (uint)DW_ATE.Float));

            case MetadataType.Char:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "char", size, align, (uint)DW_ATE.Unsigned));

            case MetadataType.IntPtr:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "IntPtr", size, align, (uint)DW_ATE.Signed));

            case MetadataType.UIntPtr:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "UIntPtr", size, align, (uint)DW_ATE.Unsigned));

            case MetadataType.Pointer:
                var elementType = GetType(((PointerType)type.TypeReference).ElementType);
                return(LLVM.DIBuilderCreatePointerType(debugBuilder, CreateDebugType(functionContext, elementType), size, align, type.TypeReference.Name));

            default:
                // For now, let's have a fallback since lot of types are not supported yet.
                return(CreateDebugType(functionContext, intPtr));
            }
        }
示例#2
0
        private void ProcessMissingDebugTypes()
        {
            // Process missing debug types.
            // Deferred here to avoid circular issues (when processing fields).
            while (debugClassesToProcess.Count > 0)
            {
                var debugClassToProcess = debugClassesToProcess.Dequeue();
                var @class     = debugClassToProcess.Key;
                var debugClass = debugClassToProcess.Value;
                var type       = @class.Type;

                // Complete members
                if (type.Fields == null)
                {
                    continue;
                }

                var memberTypes = new List <ValueRef>(type.Fields.Count);

                foreach (var field in type.Fields)
                {
                    var fieldType   = CreateDebugType(field.Value.Type);
                    var fieldSize   = LLVM.ABISizeOfType(targetData, field.Value.Type.DefaultTypeLLVM) * 8;
                    var fieldAlign  = LLVM.ABIAlignmentOfType(targetData, field.Value.Type.DefaultTypeLLVM) * 8;
                    var fieldOffset = IsCustomLayout(type.TypeDefinitionCecil) ? (ulong)field.Value.StructIndex * 8 : LLVM.OffsetOfElement(targetData, type.ValueTypeLLVM, (uint)field.Value.StructIndex) * 8;

                    // Add object header (VTable ptr, etc...)
                    if (type.StackType == StackValueType.Object)
                    {
                        fieldOffset += LLVM.OffsetOfElement(targetData, type.ObjectTypeLLVM, (int)ObjectFields.Data) * 8;
                    }

                    memberTypes.Add(LLVM.DIBuilderCreateMemberType(debugBuilder, debugClass, field.Key.Name, ValueRef.Empty, 0, fieldSize, fieldAlign, fieldOffset, 0, fieldType));
                }

                // Update members (mutation)
                // TODO: LLVM.DICompositeTypeSetTypeArray should take a ref, not out.
                var oldDebugClass = debugClass;
                LLVM.DICompositeTypeSetTypeArray(out debugClass, LLVM.DIBuilderGetOrCreateArray(debugBuilder, memberTypes.ToArray()));

                // debugClass being changed, set it again (old value is not valid anymore)
                debugClasses[@class] = debugClass;

                // Same in debugTypeCache (if value type)
                if (debugTypeCache.ContainsKey(@class.Type) && debugTypeCache[@class.Type] == oldDebugClass)
                {
                    debugTypeCache[@class.Type] = debugClass;
                }
            }
        }
示例#3
0
        private ValueRef GetOrCreateDebugClass(Class @class)
        {
            ValueRef debugClass;

            if (debugClasses.TryGetValue(@class, out debugClass))
            {
                return(debugClass);
            }

            var type = @class.Type;

            // Find namespace scope
            var debugNamespace = GetOrCreateDebugNamespace(type.TypeReferenceCecil.Namespace);

            // Create debug version of the class
            var structType = type.StackType == StackValueType.Object ? type.ObjectTypeLLVM : type.ValueTypeLLVM;
            var size       = LLVM.ABISizeOfType(targetData, structType) * 8;
            var align      = LLVM.ABIAlignmentOfType(targetData, structType) * 8;
            var emptyArray = LLVM.DIBuilderGetOrCreateArray(debugBuilder, new ValueRef[0]);

            bool isLocal = type.IsLocal;

            if (isLocal)
            {
                var parentClass      = @class.BaseType;
                var parentDebugClass = parentClass != null?GetOrCreateDebugClass(parentClass) : ValueRef.Empty;

                debugClass = LLVM.DIBuilderCreateClassType(debugBuilder, debugNamespace, type.TypeReferenceCecil.Name, ValueRef.Empty, 0, size, align, 0, 0, parentDebugClass, emptyArray, ValueRef.Empty, ValueRef.Empty, type.TypeReferenceCecil.FullName);
            }
            else
            {
                debugClass = LLVM.DIBuilderCreateForwardDecl(debugBuilder, (int)DW_TAG.class_type, type.TypeReferenceCecil.Name, debugNamespace, ValueRef.Empty, 0, 0, size, align, type.TypeReferenceCecil.FullName);
            }

            debugClasses.Add(@class, debugClass);

            if (isLocal)
            {
                debugClassesToProcess.Enqueue(new KeyValuePair <Class, ValueRef>(@class, debugClass));
            }

            return(debugClass);
        }
示例#4
0
        private ValueRef CreateDebugType(Type type)
        {
            ValueRef result;

            if (debugTypeCache.TryGetValue(type, out result))
            {
                return(result);
            }

            ulong size  = 0;
            ulong align = 0;

            switch (type.TypeReferenceCecil.MetadataType)
            {
            case MetadataType.Boolean:
            case MetadataType.SByte:
            case MetadataType.Byte:
            case MetadataType.Int16:
            case MetadataType.UInt16:
            case MetadataType.Int32:
            case MetadataType.UInt32:
            case MetadataType.Int64:
            case MetadataType.UInt64:
            case MetadataType.Single:
            case MetadataType.Double:
            case MetadataType.Char:
            case MetadataType.IntPtr:
            case MetadataType.UIntPtr:
            case MetadataType.Pointer:
            case MetadataType.ByReference:
                size  = LLVM.ABISizeOfType(targetData, type.DefaultTypeLLVM) * 8;
                align = LLVM.ABIAlignmentOfType(targetData, type.DefaultTypeLLVM) * 8;
                break;

            default:
                break;
            }

            switch (type.TypeReferenceCecil.MetadataType)
            {
            case MetadataType.Boolean:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "bool", size, align, (uint)DW_ATE.Boolean));

            case MetadataType.SByte:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "sbyte", size, align, (uint)DW_ATE.Signed));

            case MetadataType.Byte:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "byte", size, align, (uint)DW_ATE.Unsigned));

            case MetadataType.Int16:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "short", size, align, (uint)DW_ATE.Signed));

            case MetadataType.UInt16:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "ushort", size, align, (uint)DW_ATE.Unsigned));

            case MetadataType.Int32:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "int", size, align, (uint)DW_ATE.Signed));

            case MetadataType.UInt32:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "uint", size, align, (uint)DW_ATE.Unsigned));

            case MetadataType.Int64:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "long", size, align, (uint)DW_ATE.Signed));

            case MetadataType.UInt64:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "ulong", size, align, (uint)DW_ATE.Unsigned));

            case MetadataType.Single:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "float", size, align, (uint)DW_ATE.Float));

            case MetadataType.Double:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "double", size, align, (uint)DW_ATE.Float));

            case MetadataType.Char:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "char", size, align, (uint)DW_ATE.Unsigned));

            case MetadataType.IntPtr:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "IntPtr", size, align, (uint)DW_ATE.Signed));

            case MetadataType.UIntPtr:
                return(LLVM.DIBuilderCreateBasicType(debugBuilder, "UIntPtr", size, align, (uint)DW_ATE.Unsigned));

            case MetadataType.ByReference:
            {
                var elementType = GetType(((ByReferenceType)type.TypeReferenceCecil).ElementType, TypeState.TypeComplete);
                return(LLVM.DIBuilderCreatePointerType(debugBuilder, CreateDebugType(elementType), size, align, type.TypeReferenceCecil.Name));
            }

            case MetadataType.Pointer:
            {
                var elementType = GetType(((PointerType)type.TypeReferenceCecil).ElementType, TypeState.TypeComplete);
                return(LLVM.DIBuilderCreatePointerType(debugBuilder, CreateDebugType(elementType), size, align, type.TypeReferenceCecil.Name));
            }

            case MetadataType.Array:
            case MetadataType.String:
            case MetadataType.TypedByReference:
            case MetadataType.GenericInstance:
            case MetadataType.ValueType:
            case MetadataType.Class:
            case MetadataType.Object:
            {
                var typeDefinition = GetMethodTypeDefinition(type.TypeReferenceCecil);
                if (typeDefinition.IsEnum)
                {
                    var enumDebugType = CreateDebugType(GetType(typeDefinition.GetEnumUnderlyingType(), TypeState.StackComplete));
                    debugTypeCache.Add(type, enumDebugType);

                    return(enumDebugType);
                }

                var debugClass = GetOrCreateDebugClass(GetClass(type));

                // Try again from cache, it might have been done through recursion already
                if (debugTypeCache.TryGetValue(type, out result))
                {
                    return(result);
                }

                if (!typeDefinition.IsValueType)
                {
                    size  = LLVM.ABISizeOfType(targetData, type.DefaultTypeLLVM) * 8;
                    align = LLVM.ABIAlignmentOfType(targetData, type.DefaultTypeLLVM) * 8;

                    debugClass = LLVM.DIBuilderCreatePointerType(debugBuilder, debugClass, size, align, string.Empty);
                }

                debugTypeCache.Add(type, debugClass);

                return(debugClass);
            }

            default:
                // For now, let's have a fallback since lot of types are not supported yet.
                return(CreateDebugType(intPtr));
            }
        }
示例#5
0
 public uint ABIAlignmentOfType(Type ty) => LLVM.ABIAlignmentOfType(this.Unwrap(), ty.Unwrap());
示例#6
0
 public static uint AlignmentOfType(this LLVMTargetDataRef self, LLVMTypeRef type)
 {
     return(LLVM.ABIAlignmentOfType(self, type));
 }