diff --git a/src/codegen.cpp b/src/codegen.cpp index db1678f6e5..56f1fcabda 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -15,13 +15,7 @@ #include "semantic_info.hpp" #include - -#include -#include -#include -#include -#include -#include +#include CodeGen *create_codegen(AstNode *root, Buf *in_full_path) { CodeGen *g = allocate(1); @@ -460,24 +454,16 @@ static void gen_block(CodeGen *g, AstNode *block_node, bool add_implicit_return) static LLVMZigDISubroutineType *create_di_function_type(CodeGen *g, AstNodeFnProto *fn_proto, LLVMZigDIFile *di_file) { - llvm::SmallVector types; - - llvm::DIType *return_type = reinterpret_cast(to_llvm_debug_type(fn_proto->return_type)); - types.push_back(return_type); - + LLVMZigDIType **types = allocate(1 + fn_proto->params.length); + types[0] = to_llvm_debug_type(fn_proto->return_type); + int types_len = fn_proto->params.length + 1; 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 = reinterpret_cast(to_llvm_debug_type(param_node->data.param_decl.type)); - types.push_back(param_type); + LLVMZigDIType *param_type = to_llvm_debug_type(param_node->data.param_decl.type); + types[i + 1] = param_type; } - - llvm::DIBuilder *dibuilder = reinterpret_cast(g->dbuilder); - - llvm::DISubroutineType *result = dibuilder->createSubroutineType( - reinterpret_cast(di_file), - dibuilder->getOrCreateTypeArray(types)); - return reinterpret_cast(result); + return LLVMZigCreateSubroutineType(g->dbuilder, di_file, types, types_len, 0); } void code_gen(CodeGen *g) { @@ -596,122 +582,6 @@ ZigList *codegen_error_messages(CodeGen *g) { return &g->errors; } -enum FloatAbi { - FloatAbiHard, - FloatAbiSoft, - FloatAbiSoftFp, -}; - - -static int get_arm_sub_arch_version(const llvm::Triple &triple) { - return llvm::ARMTargetParser::parseArchVersion(triple.getArchName()); -} - -static FloatAbi get_float_abi(const llvm::Triple &triple) { - switch (triple.getOS()) { - case llvm::Triple::Darwin: - case llvm::Triple::MacOSX: - case llvm::Triple::IOS: - if (get_arm_sub_arch_version(triple) == 6 || - get_arm_sub_arch_version(triple) == 7) - { - return FloatAbiSoftFp; - } else { - return FloatAbiSoft; - } - case llvm::Triple::Win32: - return FloatAbiHard; - case llvm::Triple::FreeBSD: - switch (triple.getEnvironment()) { - case llvm::Triple::GNUEABIHF: - return FloatAbiHard; - default: - return FloatAbiSoft; - } - default: - switch (triple.getEnvironment()) { - case llvm::Triple::GNUEABIHF: - return FloatAbiHard; - case llvm::Triple::GNUEABI: - return FloatAbiSoftFp; - case llvm::Triple::EABIHF: - return FloatAbiHard; - case llvm::Triple::EABI: - return FloatAbiSoftFp; - case llvm::Triple::Android: - if (get_arm_sub_arch_version(triple) == 7) { - return FloatAbiSoftFp; - } else { - return FloatAbiSoft; - } - default: - return FloatAbiSoft; - } - } -} - -static Buf *get_dynamic_linker(CodeGen *g) { - llvm::TargetMachine *target_machine = reinterpret_cast(g->target_machine); - const llvm::Triple &triple = target_machine->getTargetTriple(); - - const llvm::Triple::ArchType arch = triple.getArch(); - - if (triple.getEnvironment() == llvm::Triple::Android) { - if (triple.isArch64Bit()) { - return buf_create_from_str("/system/bin/linker64"); - } else { - return buf_create_from_str("/system/bin/linker"); - } - } else if (arch == llvm::Triple::x86 || - arch == llvm::Triple::sparc || - arch == llvm::Triple::sparcel) - { - return buf_create_from_str("/lib/ld-linux.so.2"); - } else if (arch == llvm::Triple::aarch64) { - return buf_create_from_str("/lib/ld-linux-aarch64.so.1"); - } else if (arch == llvm::Triple::aarch64_be) { - return buf_create_from_str("/lib/ld-linux-aarch64_be.so.1"); - } else if (arch == llvm::Triple::arm || arch == llvm::Triple::thumb) { - if (triple.getEnvironment() == llvm::Triple::GNUEABIHF || - get_float_abi(triple) == FloatAbiHard) - { - return buf_create_from_str("/lib/ld-linux-armhf.so.3"); - } else { - return buf_create_from_str("/lib/ld-linux.so.3"); - } - } else if (arch == llvm::Triple::armeb || arch == llvm::Triple::thumbeb) { - if (triple.getEnvironment() == llvm::Triple::GNUEABIHF || - get_float_abi(triple) == FloatAbiHard) - { - return buf_create_from_str("/lib/ld-linux-armhf.so.3"); - } else { - return buf_create_from_str("/lib/ld-linux.so.3"); - } - } else if (arch == llvm::Triple::mips || arch == llvm::Triple::mipsel || - arch == llvm::Triple::mips64 || arch == llvm::Triple::mips64el) - { - // when you want to solve this TODO, grep clang codebase for - // getLinuxDynamicLinker - zig_panic("TODO figure out MIPS dynamic linker name"); - } else if (arch == llvm::Triple::ppc) { - return buf_create_from_str("/lib/ld.so.1"); - } else if (arch == llvm::Triple::ppc64) { - return buf_create_from_str("/lib64/ld64.so.2"); - } else if (arch == llvm::Triple::ppc64le) { - return buf_create_from_str("/lib64/ld64.so.2"); - } else if (arch == llvm::Triple::systemz) { - return buf_create_from_str("/lib64/ld64.so.1"); - } else if (arch == llvm::Triple::sparcv9) { - return buf_create_from_str("/lib64/ld-linux.so.2"); - } else if (arch == llvm::Triple::x86_64 && - triple.getEnvironment() == llvm::Triple::GNUX32) - { - return buf_create_from_str("/libx32/ld-linux-x32.so.2"); - } else { - return buf_create_from_str("/lib64/ld-linux-x86-64.so.2"); - } -} - static Buf *to_c_type(CodeGen *g, AstNode *type_node) { assert(type_node->type == NodeTypeType); assert(type_node->codegen_node); @@ -865,7 +735,7 @@ void code_gen_link(CodeGen *g, const char *out_file) { } } else { args.append("-dynamic-linker"); - args.append(buf_ptr(get_dynamic_linker(g))); + args.append(buf_ptr(get_dynamic_linker(g->target_machine))); } if (g->out_type == OutTypeLib) { diff --git a/src/zig_llvm.cpp b/src/zig_llvm.cpp index 42b6f5c0f8..81104914ab 100644 --- a/src/zig_llvm.cpp +++ b/src/zig_llvm.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -148,6 +149,22 @@ LLVMZigDIType *LLVMZigCreateDebugBasicType(LLVMZigDIBuilder *dibuilder, const ch return reinterpret_cast(di_type); } +LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder_wrapped, + LLVMZigDIFile *file, LLVMZigDIType **types_array, int types_array_len, unsigned flags) +{ + SmallVector types; + for (int i = 0; i < types_array_len; i += 1) { + DIType *ditype = reinterpret_cast(types_array[i]); + types.push_back(ditype); + } + DIBuilder *dibuilder = reinterpret_cast(dibuilder_wrapped); + DISubroutineType *subroutine_type = dibuilder->createSubroutineType( + reinterpret_cast(file), + dibuilder->getOrCreateTypeArray(types), + flags); + return reinterpret_cast(subroutine_type); +} + unsigned LLVMZigEncoding_DW_ATE_unsigned(void) { return dwarf::DW_ATE_unsigned; } @@ -161,12 +178,12 @@ unsigned LLVMZigLang_DW_LANG_C99(void) { } LLVMZigDIBuilder *LLVMZigCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) { - DIBuilder *di_builder = new DIBuilder(*llvm::unwrap(module), allow_unresolved); + DIBuilder *di_builder = new DIBuilder(*unwrap(module), allow_unresolved); return reinterpret_cast(di_builder); } void LLVMZigSetCurrentDebugLocation(LLVMBuilderRef builder, int line, int column, LLVMZigDIScope *scope) { - unwrap(builder)->SetCurrentDebugLocation(llvm::DebugLoc::get( + unwrap(builder)->SetCurrentDebugLocation(DebugLoc::get( line, column, reinterpret_cast(scope))); } @@ -223,7 +240,7 @@ LLVMZigDISubprogram *LLVMZigCreateFunction(LLVMZigDIBuilder *dibuilder, LLVMZigD 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(unwrap(function)); + Function *unwrapped_function = reinterpret_cast(unwrap(function)); DISubprogram *result = reinterpret_cast(dibuilder)->createFunction( reinterpret_cast(scope), name, linkage_name, @@ -237,3 +254,119 @@ LLVMZigDISubprogram *LLVMZigCreateFunction(LLVMZigDIBuilder *dibuilder, LLVMZigD void LLVMZigDIBuilderFinalize(LLVMZigDIBuilder *dibuilder) { reinterpret_cast(dibuilder)->finalize(); } + +enum FloatAbi { + FloatAbiHard, + FloatAbiSoft, + FloatAbiSoftFp, +}; + +static int get_arm_sub_arch_version(const Triple &triple) { + return ARMTargetParser::parseArchVersion(triple.getArchName()); +} + +static FloatAbi get_float_abi(const Triple &triple) { + switch (triple.getOS()) { + case Triple::Darwin: + case Triple::MacOSX: + case Triple::IOS: + if (get_arm_sub_arch_version(triple) == 6 || + get_arm_sub_arch_version(triple) == 7) + { + return FloatAbiSoftFp; + } else { + return FloatAbiSoft; + } + case Triple::Win32: + return FloatAbiHard; + case Triple::FreeBSD: + switch (triple.getEnvironment()) { + case Triple::GNUEABIHF: + return FloatAbiHard; + default: + return FloatAbiSoft; + } + default: + switch (triple.getEnvironment()) { + case Triple::GNUEABIHF: + return FloatAbiHard; + case Triple::GNUEABI: + return FloatAbiSoftFp; + case Triple::EABIHF: + return FloatAbiHard; + case Triple::EABI: + return FloatAbiSoftFp; + case Triple::Android: + if (get_arm_sub_arch_version(triple) == 7) { + return FloatAbiSoftFp; + } else { + return FloatAbiSoft; + } + default: + return FloatAbiSoft; + } + } +} + +Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine_ref) { + TargetMachine *target_machine = reinterpret_cast(target_machine_ref); + const Triple &triple = target_machine->getTargetTriple(); + + const Triple::ArchType arch = triple.getArch(); + + if (triple.getEnvironment() == Triple::Android) { + if (triple.isArch64Bit()) { + return buf_create_from_str("/system/bin/linker64"); + } else { + return buf_create_from_str("/system/bin/linker"); + } + } else if (arch == Triple::x86 || + arch == Triple::sparc || + arch == Triple::sparcel) + { + return buf_create_from_str("/lib/ld-linux.so.2"); + } else if (arch == Triple::aarch64) { + return buf_create_from_str("/lib/ld-linux-aarch64.so.1"); + } else if (arch == Triple::aarch64_be) { + return buf_create_from_str("/lib/ld-linux-aarch64_be.so.1"); + } else if (arch == Triple::arm || arch == Triple::thumb) { + if (triple.getEnvironment() == Triple::GNUEABIHF || + get_float_abi(triple) == FloatAbiHard) + { + return buf_create_from_str("/lib/ld-linux-armhf.so.3"); + } else { + return buf_create_from_str("/lib/ld-linux.so.3"); + } + } else if (arch == Triple::armeb || arch == Triple::thumbeb) { + if (triple.getEnvironment() == Triple::GNUEABIHF || + get_float_abi(triple) == FloatAbiHard) + { + return buf_create_from_str("/lib/ld-linux-armhf.so.3"); + } else { + return buf_create_from_str("/lib/ld-linux.so.3"); + } + } else if (arch == Triple::mips || arch == Triple::mipsel || + arch == Triple::mips64 || arch == Triple::mips64el) + { + // when you want to solve this TODO, grep clang codebase for + // getLinuxDynamicLinker + zig_panic("TODO figure out MIPS dynamic linker name"); + } else if (arch == Triple::ppc) { + return buf_create_from_str("/lib/ld.so.1"); + } else if (arch == Triple::ppc64) { + return buf_create_from_str("/lib64/ld64.so.2"); + } else if (arch == Triple::ppc64le) { + return buf_create_from_str("/lib64/ld64.so.2"); + } else if (arch == Triple::systemz) { + return buf_create_from_str("/lib64/ld64.so.1"); + } else if (arch == Triple::sparcv9) { + return buf_create_from_str("/lib64/ld-linux.so.2"); + } else if (arch == Triple::x86_64 && + triple.getEnvironment() == Triple::GNUX32) + { + return buf_create_from_str("/libx32/ld-linux-x32.so.2"); + } else { + return buf_create_from_str("/lib64/ld-linux-x86-64.so.2"); + } +} + diff --git a/src/zig_llvm.hpp b/src/zig_llvm.hpp index f084bf0712..4350624310 100644 --- a/src/zig_llvm.hpp +++ b/src/zig_llvm.hpp @@ -42,6 +42,9 @@ LLVMZigDIType *LLVMZigCreateDebugPointerType(LLVMZigDIBuilder *dibuilder, LLVMZi LLVMZigDIType *LLVMZigCreateDebugBasicType(LLVMZigDIBuilder *dibuilder, const char *name, uint64_t size_in_bits, uint64_t align_in_bits, unsigned encoding); +LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder_wrapped, + LLVMZigDIFile *file, LLVMZigDIType **types_array, int types_array_len, unsigned flags); + unsigned LLVMZigEncoding_DW_ATE_unsigned(void); unsigned LLVMZigEncoding_DW_ATE_signed(void); unsigned LLVMZigLang_DW_LANG_C99(void); @@ -72,4 +75,12 @@ LLVMZigDISubprogram *LLVMZigCreateFunction(LLVMZigDIBuilder *dibuilder, LLVMZigD void LLVMZigDIBuilderFinalize(LLVMZigDIBuilder *dibuilder); + +/* + * This stuff is not LLVM API but it depends on the LLVM C++ API so we put it here. + */ +#include "buffer.hpp" + +Buf *get_dynamic_linker(LLVMTargetMachineRef target_machine); + #endif