/// <summary>Initializes a new instance of the <see cref="DebugUnionType"/> class.</summary>
        /// <param name="llvmType">Underlying native type this debug type describes</param>
        /// <param name="module">Module to contain the debug metadata for this type</param>
        /// <param name="scope">Scope containing this type</param>
        /// <param name="name">Debug/source name of the type</param>
        /// <param name="file">Source file containing this type</param>
        /// <param name="line">Line number for this type</param>
        /// <param name="debugFlags">Debug flags for this type</param>
        /// <param name="elements">Descriptors for the members of the type</param>
        public DebugUnionType(IStructType llvmType
                              , BitcodeModule module
                              , DIScope scope
                              , string name
                              , DIFile file
                              , uint line
                              , DebugInfoFlags debugFlags
                              , IEnumerable <DebugMemberInfo> elements
                              )
            : base(llvmType)
        {
            llvmType.ValidateNotNull(nameof(llvmType));
            module.ValidateNotNull(nameof(module));
            scope.ValidateNotNull(nameof(scope));
            file.ValidateNotNull(nameof(file));

            if (!llvmType.IsOpaque)
            {
                throw new ArgumentException(Resources.Struct_type_used_as_basis_for_a_union_must_not_have_a_body, nameof(llvmType));
            }

            DIType = module.DIBuilder
                     .CreateReplaceableCompositeType(Tag.UnionType
                                                     , name
                                                     , scope
                                                     , file
                                                     , line
                                                     );
            SetBody(module, scope, file, line, debugFlags, elements);
        }
        /// <summary>Sets the body of the union type</summary>
        /// <param name="module">Module to contain the debug metadata</param>
        /// <param name="scope">Scope containing this type</param>
        /// <param name="file">File for the type</param>
        /// <param name="line">line number for the type</param>
        /// <param name="debugFlags">Flags for the type</param>
        /// <param name="debugElements">Descriptors for each element in the type</param>
        public void SetBody(BitcodeModule module
                            , DIScope scope
                            , DIFile file
                            , uint line
                            , DebugInfoFlags debugFlags
                            , IEnumerable <DebugMemberInfo> debugElements
                            )
        {
            module.ValidateNotNull(nameof(module));
            scope.ValidateNotNull(nameof(scope));
            debugElements.ValidateNotNull(nameof(debugElements));

            if (module.Layout == null)
            {
                throw new ArgumentException(Resources.Module_needs_Layout_to_build_basic_types, nameof(module));
            }

            // Native body is a single element of a type with the largest size
            ulong maxSize = 0UL;

            ITypeRef[] nativeMembers = { null };
            foreach (var elem in debugElements)
            {
                /* ReSharper disable ConditionIsAlwaysTrueOrFalse */
                /* ReSharper disable HeuristicUnreachableCode */
                ulong?bitSize = elem.ExplicitLayout?.BitSize ?? module.Layout?.BitSizeOf(elem.DebugType);
                if (!bitSize.HasValue)
                {
                    throw new ArgumentException(Resources.Cannot_determine_layout_for_element__The_element_must_have_an_explicit_layout_or_the_module_has_a_layout_to_use, nameof(debugElements));
                }

                /* ReSharper enable HeuristicUnreachableCode */
                /* ReSharper enable ConditionIsAlwaysTrueOrFalse */

                if (maxSize >= bitSize.Value)
                {
                    continue;
                }

                maxSize          = bitSize.Value;
                nativeMembers[0] = elem.DebugType;
            }

            var nativeType = ( IStructType )NativeType;

            nativeType.SetBody(false, nativeMembers);

            // Debug info contains details of each member of the union
            DebugMembers = new ReadOnlyCollection <DebugMemberInfo>(debugElements as IList <DebugMemberInfo> ?? debugElements.ToList( ));
            var memberTypes = from memberInfo in DebugMembers
                              select module.DIBuilder.CreateMemberType(scope : DIType
                                                                       , name : memberInfo.Name
                                                                       , file : memberInfo.File
                                                                       , line : memberInfo.Line
                                                                       , bitSize : (memberInfo.ExplicitLayout?.BitSize ?? module.Layout?.BitSizeOf(memberInfo.DebugType)).Value
                                                                       , bitAlign : memberInfo.ExplicitLayout?.BitAlignment ?? 0
                                                                       , bitOffset : 0
                                                                       , debugFlags : memberInfo.DebugInfoFlags
                                                                       , type : memberInfo.DebugType.DIType
                                                                       );

            var concreteType = module.DIBuilder.CreateUnionType(scope: scope
                                                                , name: DIType.Name
                                                                , file: file
                                                                , line: line
                                                                , bitSize: 0  // TODO: find largest sized member
                                                                , bitAlign: 0 // TODO: Find most restrictive alignment
                                                                , debugFlags: debugFlags
                                                                , elements: memberTypes
                                                                );

            DIType = concreteType;
        }
Exemple #3
0
        /// <summary>Sets the body of the union type</summary>
        /// <param name="module">Module to contain the debug metadata</param>
        /// <param name="scope">Scope containing this type</param>
        /// <param name="file">File for the type</param>
        /// <param name="line">line number for the type</param>
        /// <param name="debugFlags">Flags for the type</param>
        /// <param name="debugElements">Dexcriptors for each element in the type</param>
        public void SetBody(BitcodeModule module
                            , DIScope scope
                            , DIFile file
                            , uint line
                            , DebugInfoFlags debugFlags
                            , IEnumerable <DebugMemberInfo> debugElements
                            )
        {
            module.ValidateNotNull(nameof(module));
            scope.ValidateNotNull(nameof(scope));
            debugElements.ValidateNotNull(nameof(debugElements));

            if (module.Layout == null)
            {
                throw new ArgumentException("Module needs Layout to build basic types", nameof(module));
            }

            // Native body is a single element of a type with the largest size
            ulong maxSize = 0UL;

            ITypeRef[] nativeMembers = { null };
            foreach (var elem in debugElements)
            {
                var bitSize = elem.ExplicitLayout?.BitSize ?? module.Layout?.BitSizeOf(elem.DebugType);
                if (!bitSize.HasValue)
                {
                    throw new ArgumentException("Cannot determine layout for element; The element must have an explicit layout or the module has a layout to use", nameof(debugElements));
                }

                if (maxSize < bitSize.Value)
                {
                    maxSize          = bitSize.Value;
                    nativeMembers[0] = elem.DebugType;
                }
            }

            var nativeType = ( IStructType )NativeType;

            nativeType.SetBody(false, nativeMembers);

            // Debug info contains details of each member of the union
            DebugMembers = new ReadOnlyCollection <DebugMemberInfo>(debugElements as IList <DebugMemberInfo> ?? debugElements.ToList( ));
            var memberTypes = from memberInfo in DebugMembers
                              select module.DIBuilder.CreateMemberType(scope : DIType
                                                                       , name : memberInfo.Name
                                                                       , file : memberInfo.File
                                                                       , line : memberInfo.Line
                                                                       , bitSize : (memberInfo.ExplicitLayout?.BitSize ?? module.Layout?.BitSizeOf(memberInfo.DebugType)).Value
                                                                       , bitAlign : memberInfo.ExplicitLayout?.BitAlignment ?? 0
                                                                       , bitOffset : 0
                                                                       , debugFlags : memberInfo.DebugInfoFlags
                                                                       , type : memberInfo.DebugType.DIType
                                                                       );

            var concreteType = module.DIBuilder.CreateUnionType(scope: scope
                                                                , name: DIType.Name
                                                                , file: file
                                                                , line: line
                                                                , bitSize: 0  // TODO: find largest sized member
                                                                , bitAlign: 0 // TODO: Find most restrictive alignment
                                                                , debugFlags: debugFlags
                                                                , elements: memberTypes
                                                                );

            DIType = concreteType;
        }