private Type EnsureStructRecursive(StructNode structNode, HashSet <StructNode> closedSet) { // Check if struct has already been created Type?llvmStructType = Context.LookupStructType(structNode.Name); if (llvmStructType != null) { return(llvmStructType.Value); } // Add this node to closed set to avoid cycles if (closedSet.Contains(structNode)) { throw new InvalidOperationException($"Cyclic struct member detected: {structNode.Name}"); } closedSet.Add(structNode); // Head recursion is necessary to resolve non-forward-declared struct types Type[] memberTypes = new Type[structNode.Members.Count]; for (int i = 0, ilen = structNode.Members.Count; i < ilen; ++i) { DeclarationNode member = structNode.Members[i]; IType tp = ((TypeSpecifierNode)member.Type).Type; Type? llvmTp = LookupType(tp); if (llvmTp != null) { memberTypes[i] = llvmTp.Value; } else if (tp is StructType structType) { memberTypes[i] = EnsureStructRecursive(structType.Struct, closedSet); } else { throw new InvalidOperationException("Unable to ensure type recursively"); } } // Actually create the LLVM type here Type newStructType = Context.CreateStruct(structNode.Name, memberTypes); ulong sizeInBits = TargetDataLayout.SizeOfTypeInBits(newStructType); uint alignInBits = TargetDataLayout.PreferredAlignmentOfType(newStructType); List <Metadata> diMemberTypes = structNode.Members.ConvertAll(d => LookupDiType(((TypeSpecifierNode)d.Type).Type) !.Value); // TODO: resolve declaration file and line DiBuilder.CreateStruct(structNode.Name, DiFile, 0, sizeInBits, alignInBits, diMemberTypes.ToArray()); return(newStructType); }
public void TestBuild_VerifyDependendencyObjectsAreNotNull() { var serviceCollection = new ServiceCollection(); var configuration = new Mock <IConfiguration>(); configuration.Setup(config => config.GetSection("Database").GetSection("Connection").Value).Returns("DummyConnection"); DiBuilder.Build(serviceCollection, configuration.Object); var sp = serviceCollection.BuildServiceProvider(); var result = sp.GetService <ITaskRepository>(); Assert.NotNull(result); var dbContext = sp.GetService <ProjectManagerDbContext>(); Assert.NotNull(dbContext); }
public CodeGeneratorContext(Context context, SemanticModule semanticModule, SemanticContext semanticContext, string fileName, string dirName, string targetTriple, bool optimized, bool debugInfo, bool columnInfo) { Context = context; SemanticModule = semanticModule; SemanticContext = semanticContext; Module = context.CreateModule(fileName); Module.SetTarget(targetTriple); // Debug compile unit is always emitted even if debug info is not requested // This provides a standardized way to export enums in the module Module.AddModuleFlag(LLVMModuleFlagBehavior.LLVMModuleFlagBehaviorWarning, "Debug Info Version", Context.DebugMetadataVersion); if (targetTriple.Contains("-msvc")) { Module.AddModuleFlag(LLVMModuleFlagBehavior.LLVMModuleFlagBehaviorWarning, "CodeView", Metadata.FromValue(Value.ConstInt(Context.Int32Type, 1, false))); } DiFile = DiBuilder.CreateFile(fileName, dirName); // Just say that MonC is C89; hopefully debuggers won't care Metadata diCompileUnit = DiBuilder.CreateCompileUnit(LLVMDWARFSourceLanguage.LLVMDWARFSourceLanguageC89, DiFile, "MonC", optimized, "", 0, "", LLVMDWARFEmissionKind.LLVMDWARFEmissionFull, 0, false, false); DiModule = DiBuilder.CreateModule(diCompileUnit, fileName, "", "", ""); DebugInfo = debugInfo; ColumnInfo = columnInfo && debugInfo; // IR-independent manager to generate struct type layouts StructLayoutManager.Setup(new StructLayoutGenerator(new IndexTypeSizeManager())); // Struct sizes need to be resolved for debug info (which is target-dependent) Target target = Target.FromTriple(targetTriple); TargetMachine machine = target.CreateTargetMachine(targetTriple, "", "", LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault, LLVMRelocMode.LLVMRelocDefault, LLVMCodeModel.LLVMCodeModelDefault); TargetDataLayout = machine.CreateTargetDataLayout(); }
protected virtual void BuildOtherLayerServices(IServiceCollection services) { DiBuilder.Build(services, Configuration); }