mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 13:54:21 +00:00
all LLVM C++ API contained to one file
This commit is contained in:
parent
f36255b670
commit
b77c423f77
3 changed files with 155 additions and 141 deletions
146
src/codegen.cpp
146
src/codegen.cpp
|
|
@ -15,13 +15,7 @@
|
|||
#include "semantic_info.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <llvm/IR/IRBuilder.h>
|
||||
#include <llvm/IR/DIBuilder.h>
|
||||
#include <llvm/IR/DiagnosticInfo.h>
|
||||
#include <llvm/IR/DiagnosticPrinter.h>
|
||||
#include <llvm/Target/TargetMachine.h>
|
||||
#include <llvm/Support/TargetParser.h>
|
||||
#include <errno.h>
|
||||
|
||||
CodeGen *create_codegen(AstNode *root, Buf *in_full_path) {
|
||||
CodeGen *g = allocate<CodeGen>(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<llvm::Metadata *, 8> types;
|
||||
|
||||
llvm::DIType *return_type = reinterpret_cast<llvm::DIType*>(to_llvm_debug_type(fn_proto->return_type));
|
||||
types.push_back(return_type);
|
||||
|
||||
LLVMZigDIType **types = allocate<LLVMZigDIType*>(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<llvm::DIType*>(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<llvm::DIBuilder*>(g->dbuilder);
|
||||
|
||||
llvm::DISubroutineType *result = dibuilder->createSubroutineType(
|
||||
reinterpret_cast<llvm::DIFile*>(di_file),
|
||||
dibuilder->getOrCreateTypeArray(types));
|
||||
return reinterpret_cast<LLVMZigDISubroutineType*>(result);
|
||||
return LLVMZigCreateSubroutineType(g->dbuilder, di_file, types, types_len, 0);
|
||||
}
|
||||
|
||||
void code_gen(CodeGen *g) {
|
||||
|
|
@ -596,122 +582,6 @@ ZigList<ErrorMsg> *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<llvm::TargetMachine*>(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) {
|
||||
|
|
|
|||
139
src/zig_llvm.cpp
139
src/zig_llvm.cpp
|
|
@ -19,6 +19,7 @@
|
|||
#include <llvm/MC/SubtargetFeature.h>
|
||||
#include <llvm/Support/raw_ostream.h>
|
||||
#include <llvm/Support/FileSystem.h>
|
||||
#include <llvm/Support/TargetParser.h>
|
||||
#include <llvm/Target/TargetMachine.h>
|
||||
#include <llvm/IR/LegacyPassManager.h>
|
||||
#include <llvm/IR/Module.h>
|
||||
|
|
@ -148,6 +149,22 @@ LLVMZigDIType *LLVMZigCreateDebugBasicType(LLVMZigDIBuilder *dibuilder, const ch
|
|||
return reinterpret_cast<LLVMZigDIType*>(di_type);
|
||||
}
|
||||
|
||||
LLVMZigDISubroutineType *LLVMZigCreateSubroutineType(LLVMZigDIBuilder *dibuilder_wrapped,
|
||||
LLVMZigDIFile *file, LLVMZigDIType **types_array, int types_array_len, unsigned flags)
|
||||
{
|
||||
SmallVector<Metadata *, 8> types;
|
||||
for (int i = 0; i < types_array_len; i += 1) {
|
||||
DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
|
||||
types.push_back(ditype);
|
||||
}
|
||||
DIBuilder *dibuilder = reinterpret_cast<DIBuilder*>(dibuilder_wrapped);
|
||||
DISubroutineType *subroutine_type = dibuilder->createSubroutineType(
|
||||
reinterpret_cast<DIFile*>(file),
|
||||
dibuilder->getOrCreateTypeArray(types),
|
||||
flags);
|
||||
return reinterpret_cast<LLVMZigDISubroutineType*>(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<LLVMZigDIBuilder *>(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<DIScope*>(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<llvm::Function*>(unwrap(function));
|
||||
Function *unwrapped_function = reinterpret_cast<Function*>(unwrap(function));
|
||||
DISubprogram *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFunction(
|
||||
reinterpret_cast<DIScope*>(scope),
|
||||
name, linkage_name,
|
||||
|
|
@ -237,3 +254,119 @@ LLVMZigDISubprogram *LLVMZigCreateFunction(LLVMZigDIBuilder *dibuilder, LLVMZigD
|
|||
void LLVMZigDIBuilderFinalize(LLVMZigDIBuilder *dibuilder) {
|
||||
reinterpret_cast<DIBuilder*>(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<TargetMachine*>(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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue