diff options
| -rw-r--r-- | src/analyze.cpp | 15 | ||||
| -rw-r--r-- | src/codegen.cpp | 46 | ||||
| -rw-r--r-- | src/semantic_info.hpp | 14 | ||||
| -rw-r--r-- | src/zig_llvm.cpp | 115 | ||||
| -rw-r--r-- | src/zig_llvm.hpp | 46 |
5 files changed, 198 insertions, 38 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp index acb57ab214..268f164c3e 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -81,7 +81,7 @@ static void resolve_type(CodeGen *g, AstNode *node) { entry->type_ref = LLVMPointerType(child_type_node->entry->type_ref, 0); buf_resize(&entry->name, 0); buf_appendf(&entry->name, "*%s %s", const_or_mut_str, buf_ptr(&child_type_node->entry->name)); - entry->di_type = g->dbuilder->createPointerType(child_type_node->entry->di_type, + entry->di_type = LLVMZigCreateDebugPointerType(g->dbuilder, child_type_node->entry->di_type, g->pointer_size_bytes * 8, g->pointer_size_bytes * 8, buf_ptr(&entry->name)); g->type_table.put(&entry->name, entry); type_node->entry = entry; @@ -431,7 +431,8 @@ static void define_primitive_types(CodeGen *g) { entry->id = TypeIdU8; entry->type_ref = LLVMInt8Type(); buf_init_from_str(&entry->name, "u8"); - entry->di_type = g->dbuilder->createBasicType(buf_ptr(&entry->name), 8, 8, llvm::dwarf::DW_ATE_unsigned); + entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), 8, 8, + LLVMZigEncoding_DW_ATE_unsigned()); g->type_table.put(&entry->name, entry); } { @@ -439,8 +440,8 @@ static void define_primitive_types(CodeGen *g) { entry->id = TypeIdI32; entry->type_ref = LLVMInt32Type(); buf_init_from_str(&entry->name, "i32"); - entry->di_type = g->dbuilder->createBasicType(buf_ptr(&entry->name), 32, 32, - llvm::dwarf::DW_ATE_signed); + entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), 32, 32, + LLVMZigEncoding_DW_ATE_signed()); g->type_table.put(&entry->name, entry); } { @@ -448,8 +449,8 @@ static void define_primitive_types(CodeGen *g) { entry->id = TypeIdVoid; entry->type_ref = LLVMVoidType(); buf_init_from_str(&entry->name, "void"); - entry->di_type = g->dbuilder->createBasicType(buf_ptr(&entry->name), 0, 0, - llvm::dwarf::DW_ATE_unsigned); + entry->di_type = LLVMZigCreateDebugBasicType(g->dbuilder, buf_ptr(&entry->name), 0, 0, + LLVMZigEncoding_DW_ATE_unsigned()); g->type_table.put(&entry->name, entry); // invalid types are void @@ -501,7 +502,7 @@ void semantic_analyze(CodeGen *g) { g->pointer_size_bytes = LLVMPointerSize(g->target_data_ref); g->builder = LLVMCreateBuilder(); - g->dbuilder = new llvm::DIBuilder(*llvm::unwrap(g->module), true); + g->dbuilder = LLVMZigCreateDIBuilder(g->module, true); define_primitive_types(g); diff --git a/src/codegen.cpp b/src/codegen.cpp index 572769817a..db1678f6e5 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -70,7 +70,7 @@ static LLVMTypeRef to_llvm_type(AstNode *type_node) { return type_node->codegen_node->data.type_node.entry->type_ref; } -static llvm::DIType *to_llvm_debug_type(AstNode *type_node) { +static LLVMZigDIType *to_llvm_debug_type(AstNode *type_node) { assert(type_node->type == NodeTypeType); assert(type_node->codegen_node); assert(type_node->codegen_node->data.type_node.entry); @@ -86,9 +86,7 @@ static bool type_is_unreachable(AstNode *type_node) { } static void add_debug_source_node(CodeGen *g, AstNode *node) { - llvm::unwrap(g->builder)->SetCurrentDebugLocation(llvm::DebugLoc::get( - node->line + 1, node->column + 1, - g->block_scopes.last())); + LLVMZigSetCurrentDebugLocation(g->builder, node->line + 1, node->column + 1, g->block_scopes.last()); } static LLVMValueRef find_or_create_string(CodeGen *g, Buf *str) { @@ -441,9 +439,9 @@ static LLVMValueRef gen_expr(CodeGen *g, AstNode *node) { static void gen_block(CodeGen *g, AstNode *block_node, bool add_implicit_return) { assert(block_node->type == NodeTypeBlock); - llvm::DILexicalBlock *di_block = g->dbuilder->createLexicalBlock(g->block_scopes.last(), + LLVMZigDILexicalBlock *di_block = LLVMZigCreateLexicalBlock(g->dbuilder, g->block_scopes.last(), g->di_file, block_node->line + 1, block_node->column + 1); - g->block_scopes.append(di_block); + g->block_scopes.append(LLVMZigLexicalBlockToScope(di_block)); add_debug_source_node(g, block_node); @@ -459,22 +457,27 @@ static void gen_block(CodeGen *g, AstNode *block_node, bool add_implicit_return) g->block_scopes.pop(); } -static llvm::DISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnProto *fn_proto, - llvm::DIFile *di_file) +static LLVMZigDISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnProto *fn_proto, + LLVMZigDIFile *di_file) { llvm::SmallVector<llvm::Metadata *, 8> types; - llvm::DIType *return_type = to_llvm_debug_type(fn_proto->return_type); + llvm::DIType *return_type = reinterpret_cast<llvm::DIType*>(to_llvm_debug_type(fn_proto->return_type)); types.push_back(return_type); for (int i = 0; i < fn_proto->params.length; i += 1) { AstNode *param_node = fn_proto->params.at(i); assert(param_node->type == NodeTypeParamDecl); - llvm::DIType *param_type = to_llvm_debug_type(param_node->data.param_decl.type); + llvm::DIType *param_type = reinterpret_cast<llvm::DIType*>(to_llvm_debug_type(param_node->data.param_decl.type)); types.push_back(param_type); } - return g->dbuilder->createSubroutineType(di_file, g->dbuilder->getOrCreateTypeArray(types)); + llvm::DIBuilder *dibuilder = reinterpret_cast<llvm::DIBuilder*>(g->dbuilder); + + llvm::DISubroutineType *result = dibuilder->createSubroutineType( + reinterpret_cast<llvm::DIFile*>(di_file), + dibuilder->getOrCreateTypeArray(types)); + return reinterpret_cast<LLVMZigDISubroutineType*>(result); } void code_gen(CodeGen *g) { @@ -484,14 +487,14 @@ void code_gen(CodeGen *g) { bool is_optimized = g->build_type == CodeGenBuildTypeRelease; const char *flags = ""; unsigned runtime_version = 0; - g->compile_unit = g->dbuilder->createCompileUnit(llvm::dwarf::DW_LANG_C99, + g->compile_unit = LLVMZigCreateCompileUnit(g->dbuilder, LLVMZigLang_DW_LANG_C99(), buf_ptr(&g->in_file), buf_ptr(&g->in_dir), buf_ptr(producer), is_optimized, flags, runtime_version, - "", llvm::DIBuilder::FullDebug, 0, !g->strip_debug_symbols); + "", 0, !g->strip_debug_symbols); - g->block_scopes.append(g->compile_unit); + g->block_scopes.append(LLVMZigCompileUnitToScope(g->compile_unit)); - g->di_file = g->dbuilder->createFile(g->compile_unit->getFilename(), g->compile_unit->getDirectory()); + g->di_file = LLVMZigCreateFile(g->dbuilder, buf_ptr(&g->in_file), buf_ptr(&g->in_dir)); // Generate function prototypes @@ -543,18 +546,17 @@ void code_gen(CodeGen *g) { AstNodeFnProto *fn_proto = &proto_node->data.fn_proto; // Add debug info. - llvm::DIScope *fn_scope = g->di_file; + LLVMZigDIScope *fn_scope = LLVMZigFileToScope(g->di_file); unsigned line_number = fn_def_node->line + 1; unsigned scope_line = line_number; bool is_definition = true; unsigned flags = 0; - llvm::Function *unwrapped_function = reinterpret_cast<llvm::Function*>(llvm::unwrap(fn)); - llvm::DISubprogram *subprogram = g->dbuilder->createFunction( + LLVMZigDISubprogram *subprogram = LLVMZigCreateFunction(g->dbuilder, fn_scope, buf_ptr(&fn_proto->name), "", g->di_file, line_number, create_di_function_type(g, fn_proto, g->di_file), fn_table_entry->internal_linkage, - is_definition, scope_line, flags, is_optimized, unwrapped_function); + is_definition, scope_line, flags, is_optimized, fn); - g->block_scopes.append(subprogram); + g->block_scopes.append(LLVMZigSubprogramToScope(subprogram)); LLVMBasicBlockRef entry_block = LLVMAppendBasicBlock(fn, "entry"); LLVMPositionBuilderAtEnd(g->builder, entry_block); @@ -573,7 +575,7 @@ void code_gen(CodeGen *g) { } assert(!g->errors.length); - g->dbuilder->finalize(); + LLVMZigDIBuilderFinalize(g->dbuilder); LLVMDumpModule(g->module); @@ -897,5 +899,3 @@ void code_gen_link(CodeGen *g, const char *out_file) { generate_h_file(g); } } - - diff --git a/src/semantic_info.hpp b/src/semantic_info.hpp index be9e419558..70b5bc1000 100644 --- a/src/semantic_info.hpp +++ b/src/semantic_info.hpp @@ -10,9 +10,7 @@ #include "codegen.hpp" #include "hash_map.hpp" - -#include <llvm/IR/DIBuilder.h> -#include <llvm/IR/DiagnosticInfo.h> +#include "zig_llvm.hpp" struct FnTableEntry { LLVMValueRef fn_value; @@ -35,7 +33,7 @@ enum TypeId { struct TypeTableEntry { TypeId id; LLVMTypeRef type_ref; - llvm::DIType *di_type; + LLVMZigDIType *di_type; TypeTableEntry *pointer_child; bool pointer_is_const; @@ -50,8 +48,8 @@ struct CodeGen { AstNode *root; ZigList<ErrorMsg> errors; LLVMBuilderRef builder; - llvm::DIBuilder *dbuilder; - llvm::DICompileUnit *compile_unit; + LLVMZigDIBuilder *dbuilder; + LLVMZigDICompileUnit *compile_unit; HashMap<Buf *, FnTableEntry *, buf_hash, buf_eql_buf> fn_table; HashMap<Buf *, LLVMValueRef, buf_hash, buf_eql_buf> str_table; HashMap<Buf *, TypeTableEntry *, buf_hash, buf_eql_buf> type_table; @@ -66,8 +64,8 @@ struct CodeGen { bool is_native_target; Buf in_file; Buf in_dir; - ZigList<llvm::DIScope *> block_scopes; - llvm::DIFile *di_file; + ZigList<LLVMZigDIScope *> block_scopes; + LLVMZigDIFile *di_file; ZigList<FnTableEntry *> fn_defs; Buf *out_name; OutType out_type; diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 78f4d81544..42b6f5c0f8 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -7,6 +7,13 @@ #include "zig_llvm.hpp" +/* + * The point of this file is to contain all the LLVM C++ API interaction so that: + * 1. The compile time of other files is kept under control. + * 2. Provide a C interface to the LLVM functions we need for self-hosting purposes. + * 3. Prevent C++ from infecting the rest of the project. + */ + #include <llvm/InitializePasses.h> #include <llvm/PassRegistry.h> #include <llvm/MC/SubtargetFeature.h> @@ -18,6 +25,8 @@ #include <llvm/IR/Verifier.h> #include <llvm/IR/Instructions.h> #include <llvm/IR/IRBuilder.h> +#include <llvm/IR/DIBuilder.h> +#include <llvm/IR/DiagnosticInfo.h> #include <llvm/Analysis/TargetLibraryInfo.h> #include <llvm/Analysis/TargetTransformInfo.h> #include <llvm/Transforms/IPO.h> @@ -122,3 +131,109 @@ LLVMValueRef LLVMZigBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *A call_inst->setCallingConv(CC); return wrap(unwrap(B)->Insert(call_inst)); } + +LLVMZigDIType *LLVMZigCreateDebugPointerType(LLVMZigDIBuilder *dibuilder, LLVMZigDIType *pointee_type, + uint64_t size_in_bits, uint64_t align_in_bits, const char *name) +{ + DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createPointerType( + reinterpret_cast<DIType*>(pointee_type), size_in_bits, align_in_bits, name); + return reinterpret_cast<LLVMZigDIType*>(di_type); +} + +LLVMZigDIType *LLVMZigCreateDebugBasicType(LLVMZigDIBuilder *dibuilder, const char *name, + uint64_t size_in_bits, uint64_t align_in_bits, unsigned encoding) +{ + DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createBasicType( + name, size_in_bits, align_in_bits, encoding); + return reinterpret_cast<LLVMZigDIType*>(di_type); +} + +unsigned LLVMZigEncoding_DW_ATE_unsigned(void) { + return dwarf::DW_ATE_unsigned; +} + +unsigned LLVMZigEncoding_DW_ATE_signed(void) { + return dwarf::DW_ATE_signed; +} + +unsigned LLVMZigLang_DW_LANG_C99(void) { + return dwarf::DW_LANG_C99; +} + +LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) { + DIBuilder *di_builder = new DIBuilder(*llvm::unwrap(module), allow_unresolved); + return reinterpret_cast<LLVMZigDIBuilder *>(di_builder); +} + +void LLVMZigSetCurrentDebugLocation(LLVMBuilderRef builder, int line, int column, LLVMZigDIScope *scope) { + unwrap(builder)->SetCurrentDebugLocation(llvm::DebugLoc::get( + line, column, reinterpret_cast<DIScope*>(scope))); +} + + +LLVMZigDILexicalBlock *LLVMZigCreateLexicalBlock(LLVMZigDIBuilder *dbuilder, LLVMZigDIScope *scope, + LLVMZigDIFile *file, unsigned line, unsigned col) +{ + DILexicalBlock *result = reinterpret_cast<DIBuilder*>(dbuilder)->createLexicalBlock( + reinterpret_cast<DIScope*>(scope), + reinterpret_cast<DIFile*>(file), + line, + col); + return reinterpret_cast<LLVMZigDILexicalBlock*>(result); +} + +LLVMZigDIScope *LLVMZigLexicalBlockToScope(LLVMZigDILexicalBlock *lexical_block) { + DIScope *scope = reinterpret_cast<DILexicalBlock*>(lexical_block); + return reinterpret_cast<LLVMZigDIScope*>(scope); +} + +LLVMZigDIScope *LLVMZigCompileUnitToScope(LLVMZigDICompileUnit *compile_unit) { + DIScope *scope = reinterpret_cast<DICompileUnit*>(compile_unit); + return reinterpret_cast<LLVMZigDIScope*>(scope); +} + +LLVMZigDIScope *LLVMZigFileToScope(LLVMZigDIFile *difile) { + DIScope *scope = reinterpret_cast<DIFile*>(difile); + return reinterpret_cast<LLVMZigDIScope*>(scope); +} + +LLVMZigDIScope *LLVMZigSubprogramToScope(LLVMZigDISubprogram *subprogram) { + DIScope *scope = reinterpret_cast<DISubprogram*>(subprogram); + return reinterpret_cast<LLVMZigDIScope*>(scope); +} + +LLVMZigDICompileUnit *LLVMZigCreateCompileUnit(LLVMZigDIBuilder *dibuilder, + unsigned lang, const char *file, const char *dir, const char *producer, + bool is_optimized, const char *flags, unsigned runtime_version, const char *split_name, + uint64_t dwo_id, bool emit_debug_info) +{ + DICompileUnit *result = reinterpret_cast<DIBuilder*>(dibuilder)->createCompileUnit( + lang, file, dir, producer, is_optimized, flags, runtime_version, split_name, + DIBuilder::FullDebug, dwo_id, emit_debug_info); + return reinterpret_cast<LLVMZigDICompileUnit*>(result); +} + +LLVMZigDIFile *LLVMZigCreateFile(LLVMZigDIBuilder *dibuilder, const char *filename, const char *directory) { + DIFile *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFile(filename, directory); + return reinterpret_cast<LLVMZigDIFile*>(result); +} + +LLVMZigDISubprogram *LLVMZigCreateFunction(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope, + const char *name, const char *linkage_name, LLVMZigDIFile *file, unsigned lineno, + LLVMZigDISubroutineType *ty, bool is_local_to_unit, bool is_definition, unsigned scope_line, + unsigned flags, bool is_optimized, LLVMValueRef function) +{ + llvm::Function *unwrapped_function = reinterpret_cast<llvm::Function*>(unwrap(function)); + DISubprogram *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFunction( + reinterpret_cast<DIScope*>(scope), + name, linkage_name, + reinterpret_cast<DIFile*>(file), + lineno, + reinterpret_cast<DISubroutineType*>(ty), + is_local_to_unit, is_definition, scope_line, flags, is_optimized, unwrapped_function); + return reinterpret_cast<LLVMZigDISubprogram*>(result); +} + +void LLVMZigDIBuilderFinalize(LLVMZigDIBuilder *dibuilder) { + reinterpret_cast<DIBuilder*>(dibuilder)->finalize(); +} diff --git a/src/zig_llvm.hpp b/src/zig_llvm.hpp index e67be49625..f084bf0712 100644 --- a/src/zig_llvm.hpp +++ b/src/zig_llvm.hpp @@ -14,6 +14,15 @@ #include <llvm-c/Initialization.h> #include <llvm-c/TargetMachine.h> +struct LLVMZigDIType; +struct LLVMZigDIBuilder; +struct LLVMZigDICompileUnit; +struct LLVMZigDIScope; +struct LLVMZigDIFile; +struct LLVMZigDILexicalBlock; +struct LLVMZigDISubprogram; +struct LLVMZigDISubroutineType; + void LLVMZigInitializeLoopStrengthReducePass(LLVMPassRegistryRef R); void LLVMZigInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R); void LLVMZigInitializeUnreachableBlockElimPass(LLVMPassRegistryRef R); @@ -26,4 +35,41 @@ void LLVMZigOptimizeModule(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef LLVMValueRef LLVMZigBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, unsigned CC, const char *Name); + +LLVMZigDIType *LLVMZigCreateDebugPointerType(LLVMZigDIBuilder *dibuilder, LLVMZigDIType *pointee_type, + uint64_t size_in_bits, uint64_t align_in_bits, const char *name); + +LLVMZigDIType *LLVMZigCreateDebugBasicType(LLVMZigDIBuilder *dibuilder, const char *name, + uint64_t size_in_bits, uint64_t align_in_bits, unsigned encoding); + +unsigned LLVMZigEncoding_DW_ATE_unsigned(void); +unsigned LLVMZigEncoding_DW_ATE_signed(void); +unsigned LLVMZigLang_DW_LANG_C99(void); + +LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved); + +void LLVMZigSetCurrentDebugLocation(LLVMBuilderRef builder, int line, int column, LLVMZigDIScope *scope); + +LLVMZigDIScope *LLVMZigLexicalBlockToScope(LLVMZigDILexicalBlock *lexical_block); +LLVMZigDIScope *LLVMZigCompileUnitToScope(LLVMZigDICompileUnit *compile_unit); +LLVMZigDIScope *LLVMZigFileToScope(LLVMZigDIFile *difile); +LLVMZigDIScope *LLVMZigSubprogramToScope(LLVMZigDISubprogram *subprogram); + +LLVMZigDILexicalBlock *LLVMZigCreateLexicalBlock(LLVMZigDIBuilder *dbuilder, LLVMZigDIScope *scope, + LLVMZigDIFile *file, unsigned line, unsigned col); + +LLVMZigDICompileUnit *LLVMZigCreateCompileUnit(LLVMZigDIBuilder *dibuilder, + unsigned lang, const char *file, const char *dir, const char *producer, + bool is_optimized, const char *flags, unsigned runtime_version, const char *split_name, + uint64_t dwo_id, bool emit_debug_info); + +LLVMZigDIFile *LLVMZigCreateFile(LLVMZigDIBuilder *dibuilder, const char *filename, const char *directory); + +LLVMZigDISubprogram *LLVMZigCreateFunction(LLVMZigDIBuilder *dibuilder, LLVMZigDIScope *scope, + const char *name, const char *linkage_name, LLVMZigDIFile *file, unsigned lineno, + LLVMZigDISubroutineType *ty, bool is_local_to_unit, bool is_definition, unsigned scope_line, + unsigned flags, bool is_optimized, LLVMValueRef function); + +void LLVMZigDIBuilderFinalize(LLVMZigDIBuilder *dibuilder); + #endif |
