Ejemplo n.º 1
0
 public DebugStructType(IStructType llvmType
                        , BitcodeModule module
                        , DIScope scope
                        , string name
                        , DIFile file
                        , uint line
                        , DebugInfoFlags debugFlags
                        , DIType derivedFrom
                        , IEnumerable <DIType> elements
                        , uint bitAlignment = 0
                        )
     : base(llvmType)
 {
     module.ValidateNotNull(nameof(module));
     DIType = module.DIBuilder
              .CreateStructType(scope
                                , name
                                , file
                                , line
                                , module.Layout.BitSizeOf(llvmType)
                                , bitAlignment
                                , debugFlags
                                , derivedFrom
                                , elements
                                );
 }
Ejemplo n.º 2
0
        /// <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);
        }
Ejemplo n.º 3
0
        /// <summary>Set the body of a type</summary>
        /// <param name="packed">Flag to indicate if the body elements are packed (e.g. no padding)</param>
        /// <param name="module">Module to contain the debug metadata for the type</param>
        /// <param name="scope">Scope containing this type</param>
        /// <param name="file">File containing the type</param>
        /// <param name="line">Line in <paramref name="file"/> for this type</param>
        /// <param name="debugFlags">Debug flags for this type</param>
        /// <param name="nativeElements">LLVM type of each element</param>
        /// <param name="debugElements">Descriptors for each element in the type</param>
        /// <param name="derivedFrom">Base type, if any for this type</param>
        /// <param name="bitSize">Total bit sice for this type or <see langword="null"/> to use default for target</param>
        /// <param name="bitAlignment">Alignment of the type in bits, 0 indicates default for taret</param>
        public void SetBody(bool packed
                            , BitcodeModule module
                            , DIScope scope
                            , DIFile file
                            , uint line
                            , DebugInfoFlags debugFlags
                            , IEnumerable <ITypeRef> nativeElements
                            , IEnumerable <DebugMemberInfo> debugElements
                            , DIType derivedFrom = null
                            , uint?bitSize       = null
                            , uint bitAlignment  = 0
                            )
        {
            DebugMembers = new ReadOnlyCollection <DebugMemberInfo>(debugElements as IList <DebugMemberInfo> ?? debugElements.ToList( ));
            SetBody(packed, nativeElements.ToArray());
            var memberTypes = from memberInfo in DebugMembers
                              select CreateMemberType(module, memberInfo);

            var concreteType = module.DIBuilder.CreateStructType(scope: scope
                                                                 , name: DIType.Name
                                                                 , file: file
                                                                 , line: line
                                                                 , bitSize: bitSize ?? module.Layout.BitSizeOf(NativeType)
                                                                 , bitAlign: bitAlignment
                                                                 , debugFlags: debugFlags
                                                                 , derivedFrom: derivedFrom
                                                                 , elements: memberTypes
                                                                 );

            DIType = concreteType;
        }
Ejemplo n.º 4
0
        /// <summary>Set the body of a type</summary>
        /// <param name="packed">Flag to indicate if the body elements are packed (e.g. no padding)</param>
        /// <param name="module">Module to contain the debug metadata for the type</param>
        /// <param name="scope">Scope containing this type</param>
        /// <param name="file">File containing the type</param>
        /// <param name="line">Line in <paramref name="file"/> for this type</param>
        /// <param name="debugFlags">Debug flags for this type</param>
        /// <param name="debugElements">Descriptors for all the elements in the type</param>
        public void SetBody(bool packed
                            , BitcodeModule module
                            , DIScope scope
                            , DIFile file
                            , uint line
                            , DebugInfoFlags debugFlags
                            , IEnumerable <DebugMemberInfo> debugElements
                            )
        {
            var debugMembersArray = debugElements as IList <DebugMemberInfo> ?? debugElements.ToList();
            var nativeElements    = debugMembersArray.Select(e => e.DebugType.NativeType);

            SetBody(packed, module, scope, file, line, debugFlags, nativeElements, debugMembersArray);
        }
Ejemplo n.º 5
0
 /// <summary>Initializes a new instance of the <see cref="DebugFunctionType"/> class.</summary>
 /// <param name="llvmType">Native LLVM function signature</param>
 /// <param name="module"><see cref="BitcodeModule"/> to use when construction debug information</param>
 /// <param name="debugFlags"><see cref="DebugInfoFlags"/> for this signature</param>
 /// <param name="retType">Return type for the function</param>
 /// <param name="argTypes">Potentially empty set of argument types for the signature</param>
 public DebugFunctionType(IFunctionType llvmType
                          , BitcodeModule module
                          , DebugInfoFlags debugFlags
                          , DebugType <ITypeRef, DIType> retType
                          , params DebugType <ITypeRef, DIType>[] argTypes
                          )
     : base(llvmType.ValidateNotNull(nameof(llvmType)))
 {
     DIType = module.ValidateNotNull(nameof(module))
              .DIBuilder
              .CreateSubroutineType(debugFlags
                                    , retType.ValidateNotNull(nameof(retType)).DIType
                                    , argTypes.Select(t => t.DIType)
                                    );
 }
Ejemplo n.º 6
0
        /// <summary>Creates a Function definition with Debug information</summary>
        /// <param name="scope">Containing scope for the function</param>
        /// <param name="name">Name of the function in source language form</param>
        /// <param name="linkageName">Mangled linker visible name of the function (may be same as <paramref name="name"/> if mangling not required by source language</param>
        /// <param name="file">File containing the function definition</param>
        /// <param name="line">Line number of the function definition</param>
        /// <param name="signature">LLVM Function type for the signature of the function</param>
        /// <param name="isLocalToUnit">Flag to indicate if this function is local to the compilation unit</param>
        /// <param name="isDefinition">Flag to indicate if this is a definition</param>
        /// <param name="scopeLine">First line of the function's outermost scope, this may not be the same as the first line of the function definition due to source formatting</param>
        /// <param name="debugFlags">Additional flags describing this function</param>
        /// <param name="isOptimized">Flag to indicate if this function is optimized</param>
        /// <param name="tParam">Parameter Metadata node</param>
        /// <param name="decl">Declaration Metadata node</param>
        /// <returns>Function described by the arguments</returns>
        public Function CreateFunction(DIScope scope
                                       , string name
                                       , string linkageName
                                       , DIFile file
                                       , uint line
                                       , DebugFunctionType signature
                                       , bool isLocalToUnit
                                       , bool isDefinition
                                       , uint scopeLine
                                       , DebugInfoFlags debugFlags
                                       , bool isOptimized
                                       , [CanBeNull] MDNode tParam = null
                                       , [CanBeNull] MDNode decl   = null
                                       )
        {
            ValidateHandle( );
            scope.ValidateNotNull(nameof(scope));
            name.ValidateNotNullOrWhiteSpace(nameof(name));
            signature.ValidateNotNull(nameof(signature));
            if (signature.DIType == null)
            {
                throw new ArgumentException("Signature requires debug type information", nameof(signature));
            }

            var func        = AddFunction(linkageName ?? name, signature);
            var diSignature = signature.DIType;
            var diFunc      = DIBuilder.CreateFunction(scope: scope
                                                       , name: name
                                                       , mangledName: linkageName
                                                       , file: file
                                                       , line: line
                                                       , signatureType: diSignature
                                                       , isLocalToUnit: isLocalToUnit
                                                       , isDefinition: isDefinition
                                                       , scopeLine: scopeLine
                                                       , debugFlags: debugFlags
                                                       , isOptimized: isOptimized
                                                       , function: func
                                                       , typeParameter: tParam
                                                       , declaration: decl
                                                       );

            Debug.Assert(diFunc.Describes(func), "Expected to get a debug function that describes the provided function");
            func.DISubProgram = diFunc;
            return(func);
        }
Ejemplo n.º 7
0
 /// <summary>Initializes a new instance of the <see cref="DebugMemberInfo"/> class.</summary>
 /// <param name="index">Member index</param>
 /// <param name="name">Member name</param>
 /// <param name="file">File containing the declaration of the member</param>
 /// <param name="line">Line number containing the member</param>
 /// <param name="debugType">Debug type for the member</param>
 /// <param name="debugInfoFlags">Flags for the member</param>
 /// <param name="explicitLayout">Explicit layout information for this member, if any</param>
 public DebugMemberInfo(uint index
                        , string name
                        , DIFile?file
                        , uint line
                        , IDebugType <ITypeRef, DIType> debugType
                        , DebugInfoFlags debugInfoFlags    = DebugInfoFlags.None
                        , DebugMemberLayout?explicitLayout = null
                        )
 {
     Index          = index;
     Name           = name;
     File           = file;
     Line           = line;
     DebugType      = debugType;
     DebugInfoFlags = debugInfoFlags;
     ExplicitLayout = explicitLayout;
 }
Ejemplo n.º 8
0
        /// <summary>Initializes a new instance of the <see cref="DebugStructType"/> class.</summary>
        /// <param name="module">Module to contain the debug meta data</param>
        /// <param name="nativeName">Name of the type in LLVM IR</param>
        /// <param name="scope">Debug scope for the structure</param>
        /// <param name="name">Source/debug name of the struct</param>
        /// <param name="file">File containing the definition of this type</param>
        /// <param name="line">line number this type is defined at</param>
        /// <param name="debugFlags">debug flags for this type</param>
        /// <param name="debugElements">Description of all the members of this structure</param>
        /// <param name="derivedFrom">Base type, if any for this type</param>
        /// <param name="packed">Indicates if this type is packed or not</param>
        /// <param name="bitSize">Total bit size for this type or <see langword="null"/> to use default for target</param>
        /// <param name="bitAlignment">Alignment of the type in bits, 0 indicates default for target</param>
        public DebugStructType(BitcodeModule module
                               , string nativeName
                               , DIScope scope
                               , string name
                               , DIFile file
                               , uint line
                               , DebugInfoFlags debugFlags
                               , IEnumerable <DebugMemberInfo> debugElements
                               , DIType derivedFrom = null
                               , bool packed        = false
                               , uint?bitSize       = null
                               , uint bitAlignment  = 0
                               )
        {
            module.ValidateNotNull(nameof(module));
            DebugMembers = new ReadOnlyCollection <DebugMemberInfo>(debugElements as IList <DebugMemberInfo> ?? debugElements.ToList( ));

            NativeType = module.Context.CreateStructType(nativeName, packed, debugElements.Select(e => e.DebugType).ToArray( ));

            // create a temp opaque type to act as scope for members
            // this is RAUW with the full struct once it is defined
            DIType = module.DIBuilder.CreateReplaceableCompositeType(Tag.StructureType
                                                                     , name
                                                                     , scope
                                                                     , file
                                                                     , line
                                                                     );

            var memberTypes = from memberInfo in DebugMembers
                              select CreateMemberType(module, memberInfo);

            var concreteType = module.DIBuilder.CreateStructType(scope: scope
                                                                 , name: name
                                                                 , file: file
                                                                 , line: line
                                                                 , bitSize: bitSize ?? module.Layout.BitSizeOf(NativeType)
                                                                 , bitAlign: bitAlignment
                                                                 , debugFlags: debugFlags
                                                                 , derivedFrom: derivedFrom
                                                                 , elements: memberTypes
                                                                 );

            // assignment performs RAUW
            DIType = concreteType;
        }
Ejemplo n.º 9
0
        public DebugUnionType(IStructType llvmType
                              , NativeModule module
                              , DIScope scope
                              , string name
                              , DIFile file
                              , uint line
                              , DebugInfoFlags debugFlags
                              , IEnumerable <DebugMemberInfo> elements
                              )
            : base(llvmType)
        {
            if (llvmType == null)
            {
                throw new ArgumentNullException(nameof(llvmType));
            }

            if (module == null)
            {
                throw new ArgumentNullException(nameof(module));
            }

            if (scope == null)
            {
                throw new ArgumentNullException(nameof(scope));
            }

            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }

            if (!llvmType.IsOpaque)
            {
                throw new ArgumentException("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);
        }
Ejemplo n.º 10
0
        /// <summary>Initializes a new instance of the <see cref="DebugStructType"/> class.</summary>
        /// <param name="module">Module to contain the debug meta data</param>
        /// <param name="nativeName">Name of the type in LLVM IR (use <see cref="string.Empty"/> for anonymous types)</param>
        /// <param name="scope">Debug scope for the structure</param>
        /// <param name="sourceName">Source/debug name of the struct (use <see cref="string.Empty"/> for anonymous types)</param>
        /// <param name="file">File containing the definition of this type</param>
        /// <param name="line">line number this type is defined at</param>
        /// <param name="debugFlags">debug flags for this type</param>
        /// <param name="members">Description of all the members of this structure</param>
        /// <param name="derivedFrom">Base type, if any for this type</param>
        /// <param name="packed">Indicates if this type is packed or not</param>
        /// <param name="bitSize">Total bit size for this type or <see langword="null"/> to use default for target</param>
        /// <param name="bitAlignment">Alignment of the type in bits, 0 indicates default for target</param>
        public DebugStructType(BitcodeModule module
                               , string nativeName
                               , DIScope?scope
                               , string sourceName
                               , DIFile?file
                               , uint line
                               , DebugInfoFlags debugFlags
                               , IEnumerable <DebugMemberInfo> members
                               , DIType?derivedFrom = null
                               , bool packed        = false
                               , uint?bitSize       = null
                               , uint bitAlignment  = 0
                               )
            : base(module.ValidateNotNull(nameof(module))
                   .Context.CreateStructType(nativeName, packed, members.Select(e => e.DebugType).ToArray( ))
                   , module.DIBuilder.CreateReplaceableCompositeType(Tag.StructureType
                                                                     , sourceName
                                                                     , scope
                                                                     , file
                                                                     , line
                                                                     )
                   )
        {
            DebugMembers = new ReadOnlyCollection <DebugMemberInfo>(members as IList <DebugMemberInfo> ?? members.ToList( ));

            var memberTypes = from memberInfo in DebugMembers
                              select CreateMemberType(module, memberInfo);

            var concreteType = module.DIBuilder.CreateStructType(scope: scope
                                                                 , name: sourceName
                                                                 , file: file
                                                                 , line: line
                                                                 , bitSize: bitSize ?? module.Layout.BitSizeOf(NativeType)
                                                                 , bitAlign: bitAlignment
                                                                 , debugFlags: debugFlags
                                                                 , derivedFrom: derivedFrom
                                                                 , elements: memberTypes
                                                                 );

            // assignment performs RAUW
            DIType = concreteType;
        }
Ejemplo n.º 11
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">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;
        }
Ejemplo n.º 12
0
        public void SetBody(NativeModule module
                            , DIScope scope
                            , DIFile diFile
                            , uint line
                            , DebugInfoFlags debugFlags
                            , IEnumerable <DebugMemberInfo> debugElements
                            )
        {
            if (module == null)
            {
                throw new ArgumentNullException(nameof(module));
            }

            if (scope == null)
            {
                throw new ArgumentNullException(nameof(scope));
            }

            if (debugElements == null)
            {
                throw new ArgumentNullException(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: diFile
                                                                , line: line
                                                                , bitSize: 0  // TODO: find largest sized member
                                                                , bitAlign: 0 // TODO: Find most restrictive alignment
                                                                , debugFlags: debugFlags
                                                                , elements: memberTypes
                                                                );

            DIType = concreteType;
        }
Ejemplo n.º 13
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">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));
            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)
            {
                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));
                }

                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 CreateMemberType(module, memberInfo)
                               ).ToList <DIDerivedType>();

            var(unionBitSize, unionAlign)
                = memberTypes.Aggregate((MaxSize: 0ul, MaxAlign: 0ul)
                                        , (a, d) => (Math.Max(a.MaxSize, d.BitSize), Math.Max(a.MaxAlign, d.BitAlignment))
                                        );
            var concreteType = module.DIBuilder.CreateUnionType(scope: scope
                                                                , name: DIType !.Name // not null via construction
                                                                , file: file
                                                                , line: line
                                                                , bitSize: checked ((uint)unionBitSize)
                                                                , bitAlign: checked ((uint)unionAlign)
                                                                , debugFlags: debugFlags
                                                                , elements: memberTypes
                                                                );

            DIType = concreteType;
        }