internal EmittingContext(LLVMModuleRef pModule, LLVMPassManagerRef pPass, bool pEmitDebug) { CurrentModule = pModule; _passManager = pPass; _context = LLVM.GetGlobalContext(); _deferredStatements = new Stack <List <Syntax.SyntaxNode> >(); Builder = LLVM.CreateBuilder(); _emitDebug = pEmitDebug; Locals = new ScopeCache <LocalDefinition>(); AccessStack = new AccessStack <MemberAccess>(); BreakLocations = new AccessStack <LLVMValueRef>(1); if (_emitDebug) { _debugLocations = new Stack <LLVMMetadataRef>(); _debugInfo = Utils.LlvmPInvokes.LLVMCreateDIBuilder(CurrentModule); _debugFile = Utils.LlvmPInvokes.LLVMDIBuilderCreateFile(_debugInfo, "debug", 5, ".", 1); //Set debug version var version = LLVM.MDNode(new LLVMValueRef[] { GetInt(1), //Error on mismatch LLVM.MDString("Debug Info Version", 18), //Constant string. Cannot change. GetInt(3) }); //Debug version LLVM.AddNamedMetadataOperand(CurrentModule, "llvm.module.flags", version); } }
internal static DebugType GetLLVMDebugType(LLVMDIBuilderRef pBuilder, LLVMMetadataRef pScope, LLVMMetadataRef pFile, SmallType pType) { DebugType t = default; if (!_debugMappings.ContainsKey(pType)) { if (pType.IsArray) { var elementType = GetLLVMDebugType(pBuilder, pScope, pFile, pType.GetElementType()); var value = LLVM.DIBuilderCreateArrayType(pBuilder, elementType.Size, 0, elementType.Value, default); t = new DebugType(elementType.Size + _pointerSize, value); } else if (pType.IsTuple || pType.IsStruct || pType.IsTrait) { ulong size = 0; ulong offset = 0; LLVMMetadataRef type = default; foreach (var f in pType.GetFields()) { var memberType = GetLLVMDebugType(pBuilder, pScope, pFile, f.Type); type = LLVM.DIBuilderCreateMemberType(pBuilder, pScope, f.Name, pFile, 0, memberType.Size, 0, offset, 0, memberType.Value); offset += memberType.Size; } var value = LLVM.DIBuilderCreateStructType(pBuilder, pScope, pType.Name, pFile, 0, 0, 0, 0, default, type);
/// <summary>Create an <see cref="MDNode"/> from a string</summary> /// <param name="value">String value</param> /// <returns>New node with the string as the first element of the <see cref="MDNode.Operands"/> property (as an MDString)</returns> public MDNode CreateMDNode(string value) { ValidateHandle( ); var elements = new LLVMMetadataRef[] { LLVMMDString2(Context.ContextHandle, value, ( uint )(value?.Length ?? 0)) }; var hNode = LLVMMDNode2(Context.ContextHandle, out elements[0], ( uint )elements.Length); return(MDNode.FromHandle <MDNode>(hNode)); }
public void CreateDebugLocation() { string fileName = Path.GetFileName("DIBuilder.c"); string directory = Path.GetDirectoryName("."); LLVMModuleRef module = LLVMModuleRef.CreateWithName("netscripten"); module.Target = "asmjs-unknown-emscripten"; var dIBuilder = module.CreateDIBuilder(); var builder = module.Context.CreateBuilder(); LLVMMetadataRef fileMetadata = dIBuilder.CreateFile(fileName, directory); LLVMMetadataRef compileUnitMetadata = dIBuilder.CreateCompileUnit( LLVMDWARFSourceLanguage.LLVMDWARFSourceLanguageC, fileMetadata, "ILC", 0 /* Optimized */, String.Empty, 1, String.Empty, LLVMDWARFEmissionKind.LLVMDWARFEmissionFull, 0, 0, 0); module.AddNamedMetadataOperand("llvm.dbg.cu", compileUnitMetadata); LLVMMetadataRef functionMetaType = dIBuilder.CreateSubroutineType(fileMetadata, ReadOnlySpan <LLVMMetadataRef> .Empty, LLVMDIFlags.LLVMDIFlagZero); uint lineNumber = 1; var debugFunction = dIBuilder.CreateFunction(fileMetadata, "CreateDebugLocation", "CreateDebugLocation", fileMetadata, lineNumber, functionMetaType, 1, 1, lineNumber, 0, 0); LLVMMetadataRef currentLine = module.Context.CreateDebugLocation(lineNumber, 0, debugFunction, default(LLVMMetadataRef)); LLVMTypeRef[] FooParamTys = { LLVMTypeRef.Int64, LLVMTypeRef.Int64, }; LLVMTypeRef FooFuncTy = LLVMTypeRef.CreateFunction(LLVMTypeRef.Int64, FooParamTys); LLVMValueRef FooFunction = module.AddFunction("foo", FooFuncTy); var funcBlock = module.Context.AppendBasicBlock(FooFunction, "foo"); builder.PositionAtEnd(funcBlock); builder.BuildRet(LLVMValueRef.CreateConstInt(LLVMTypeRef.Int64, 0)); builder.CurrentDebugLocation = module.Context.MetadataAsValue(currentLine); var dwarfVersion = LLVMValueRef.CreateMDNode(new[] { LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 2), module.Context.GetMDString("Dwarf Version", 13), LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 4) }); var dwarfSchemaVersion = LLVMValueRef.CreateMDNode(new[] { LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 2), module.Context.GetMDString("Debug Info Version", 18), LLVMValueRef.CreateConstInt(LLVMTypeRef.Int32, 3) }); module.AddNamedMetadataOperand("llvm.module.flags", dwarfVersion); module.AddNamedMetadataOperand("llvm.module.flags", dwarfSchemaVersion); dIBuilder.DIBuilderFinalize(); module.TryVerify(LLVMVerifierFailureAction.LLVMPrintMessageAction, out string message); Assert.AreEqual("", message); }
private protected LlvmMetadata(LLVMMetadataRef handle) { if (handle == default) { throw new ArgumentNullException(nameof(handle)); } MetadataHandle = handle; }
// ideally this would be protected + internal but C# // doesn't have any syntax to allow such a thing so it // is internal and internal code should ensure it is // only ever used by derived type constructors internal /*protected*/ LlvmMetadata(LLVMMetadataRef handle) { if (handle == LLVMMetadataRef.Zero) { throw new ArgumentNullException(nameof(handle)); } MetadataHandle = handle; }
internal static T FromHandle <T>(Context context, LLVMMetadataRef handle) where T : LlvmMetadata { if (handle == default) { return(null); } return(( T )context.GetNodeFor(handle, StaticFactory)); }
public void EmitDebugLocation(Syntax.SyntaxNode pNode) { if (!_emitDebug) { return; } LLVMMetadataRef loc = GetCurrentDebugScope(); LLVMMetadataRef currentLine = Utils.LlvmPInvokes.LLVMDIBuilderCreateDebugLocation(_context, (uint)pNode.Span.Line, (uint)pNode.Span.Column, loc, default);
internal static T FromHandle <T>(LLVMMetadataRef handle) where T : MDNode { if (handle.Pointer.IsNull( )) { return(null); } var context = Context.GetContextFor(handle); return(FromHandle <T>(context, handle)); }
internal static T FromHandle <T>(LLVMMetadataRef handle) where T : MDNode { if (handle == default) { return(null); } var context = handle.Context; return(FromHandle <T>(context, handle)); }
internal static Context GetContextFor(LLVMMetadataRef handle) { if (handle == LLVMMetadataRef.Zero) { return(null); } var hContext = NativeMethods.GetNodeContext(handle); Debug.Assert(hContext.Pointer != IntPtr.Zero); return(GetContextFor(hContext)); }
internal LlvmMetadata GetNodeFor(LLVMMetadataRef handle, Func <LLVMMetadataRef, LlvmMetadata> staticFactory) { if (handle == LLVMMetadataRef.Zero) { throw new ArgumentNullException(nameof(handle)); } if (MetadataCache.TryGetValue(handle, out LlvmMetadata retVal)) { return(retVal); } retVal = staticFactory(handle); MetadataCache.Add(handle, retVal); return(retVal); }
internal DIImportedEntity(LLVMMetadataRef handle) : base(handle) { }
internal DITemplateTypeParameter(LLVMMetadataRef handle) : base(handle) { }
/* TODO: non-operand properties * // pretty much all of the LLVM DIExpression implementation. * // most of the focus is on a sequence of expression operands */ internal DIExpression(LLVMMetadataRef handle) : base(handle) { }
internal DIScope(LLVMMetadataRef handle) : base(handle) { }
internal DIEnumerator(LLVMMetadataRef handle) : base(handle) { }
/// <summary>Initializes a new instance of the <see cref="DIDerivedType"/> class from an <see cref="LLVMMetadataRef"/></summary> /// <param name="handle">Handle to wrap</param> internal DIDerivedType(LLVMMetadataRef handle) : base(handle) { }
/* TODO: non-operand property * unsigned Discriminator { get; } */ internal DILexicalBlockFile(LLVMMetadataRef handle) : base(handle) { }
internal DILocation(LLVMMetadataRef handle) : base(handle) { }
private static extern LLVMMDOperandRef LLVMMDNodeGetOperand(LLVMMetadataRef /*MDNode*/ node, UInt32 index);
internal MDTuple(LLVMMetadataRef handle) : base(handle) { }
private static extern UInt32 LLVMMDNodeGetNumOperands(LLVMMetadataRef /*MDNode*/ node);
internal DINamespace(LLVMMetadataRef handle) : base(handle) { }
/// <summary>Initializes a new instance of the <see cref="DICompositeType"/> class from an LLVM-C API Metadata handle</summary> /// <param name="handle">LLVM handle to wrap</param> internal DICompositeType(LLVMMetadataRef handle) : base(handle) { }
internal ConstantAsMetadata(LLVMMetadataRef handle) : base(handle) { }
internal DIVariable(LLVMMetadataRef handle) : base(handle) { }
internal DIMacroFile(LLVMMetadataRef handle) : base(handle) { }
/// <summary>Initializes a new instance of the <see cref="DIBasicType"/> class.</summary> /// <param name="handle"><see cref="LLVMMetadataRef"/> for a DIBasicType to wrap</param> internal DIBasicType(LLVMMetadataRef handle) : base(handle) { }
internal DIModule(LLVMMetadataRef handle) : base(handle) { }