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 ); }
/// <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>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; }
/// <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); }
/// <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) ); }
/// <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); }
/// <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; }
/// <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; }
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); }
/// <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; }
/// <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; }
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; }
/// <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; }