2015-11-25 04:00:38 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2015 Andrew Kelley
|
|
|
|
*
|
|
|
|
* This file is part of zig, which is MIT licensed.
|
|
|
|
* See http://opensource.org/licenses/MIT
|
|
|
|
*/
|
|
|
|
|
2016-02-11 16:33:27 +08:00
|
|
|
|
2015-12-01 05:10:07 +08:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2017-12-27 08:44:08 +08:00
|
|
|
#include "zig_llvm.h"
|
2017-10-24 10:37:59 +08:00
|
|
|
|
2017-03-24 06:59:43 +08:00
|
|
|
#include <llvm/Analysis/TargetLibraryInfo.h>
|
|
|
|
#include <llvm/Analysis/TargetTransformInfo.h>
|
|
|
|
#include <llvm/IR/DIBuilder.h>
|
|
|
|
#include <llvm/IR/DiagnosticInfo.h>
|
|
|
|
#include <llvm/IR/IRBuilder.h>
|
|
|
|
#include <llvm/IR/InlineAsm.h>
|
|
|
|
#include <llvm/IR/Instructions.h>
|
|
|
|
#include <llvm/IR/LegacyPassManager.h>
|
|
|
|
#include <llvm/IR/Module.h>
|
|
|
|
#include <llvm/IR/Verifier.h>
|
2015-11-25 04:00:38 +08:00
|
|
|
#include <llvm/InitializePasses.h>
|
|
|
|
#include <llvm/MC/SubtargetFeature.h>
|
2017-03-24 06:59:43 +08:00
|
|
|
#include <llvm/PassRegistry.h>
|
2015-11-28 06:46:06 +08:00
|
|
|
#include <llvm/Support/FileSystem.h>
|
2015-12-01 05:43:09 +08:00
|
|
|
#include <llvm/Support/TargetParser.h>
|
2017-03-24 06:59:43 +08:00
|
|
|
#include <llvm/Support/raw_ostream.h>
|
2015-11-28 06:46:06 +08:00
|
|
|
#include <llvm/Target/TargetMachine.h>
|
2018-02-26 07:09:39 +08:00
|
|
|
#include <llvm/Transforms/Coroutines.h>
|
2015-11-28 06:46:06 +08:00
|
|
|
#include <llvm/Transforms/IPO.h>
|
|
|
|
#include <llvm/Transforms/IPO/PassManagerBuilder.h>
|
2017-04-11 15:37:44 +08:00
|
|
|
#include <llvm/Transforms/IPO/AlwaysInliner.h>
|
2015-11-28 06:46:06 +08:00
|
|
|
#include <llvm/Transforms/Scalar.h>
|
2015-11-25 04:00:38 +08:00
|
|
|
|
2017-10-24 09:43:18 +08:00
|
|
|
#include <lld/Common/Driver.h>
|
2017-03-13 23:54:56 +08:00
|
|
|
|
2017-12-27 08:44:08 +08:00
|
|
|
#include <new>
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
2015-11-25 04:00:38 +08:00
|
|
|
using namespace llvm;
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) {
|
2015-11-25 04:00:38 +08:00
|
|
|
initializeLoopStrengthReducePass(*unwrap(R));
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R) {
|
2015-11-25 04:00:38 +08:00
|
|
|
initializeLowerIntrinsicsPass(*unwrap(R));
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
char *ZigLLVMGetHostCPUName(void) {
|
2017-12-27 08:44:08 +08:00
|
|
|
return strdup((const char *)sys::getHostCPUName().bytes_begin());
|
2015-11-25 04:00:38 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
char *ZigLLVMGetNativeFeatures(void) {
|
2015-11-25 06:01:37 +08:00
|
|
|
SubtargetFeatures features;
|
2015-11-25 04:00:38 +08:00
|
|
|
|
2015-11-25 06:01:37 +08:00
|
|
|
StringMap<bool> host_features;
|
|
|
|
if (sys::getHostCPUFeatures(host_features)) {
|
|
|
|
for (auto &F : host_features)
|
|
|
|
features.AddFeature(F.first(), F.second);
|
|
|
|
}
|
2015-11-25 04:00:38 +08:00
|
|
|
|
2017-12-27 08:44:08 +08:00
|
|
|
return strdup((const char *)StringRef(features.getString()).bytes_begin());
|
2015-11-25 04:00:38 +08:00
|
|
|
}
|
2015-11-28 06:46:06 +08:00
|
|
|
|
2017-04-11 15:37:44 +08:00
|
|
|
static void addDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) {
|
2017-12-27 08:44:08 +08:00
|
|
|
PM.add(createAddDiscriminatorsPass());
|
2015-11-28 06:46:06 +08:00
|
|
|
}
|
|
|
|
|
2017-04-11 15:37:44 +08:00
|
|
|
#ifndef NDEBUG
|
|
|
|
static const bool assertions_on = true;
|
|
|
|
#else
|
|
|
|
static const bool assertions_on = false;
|
|
|
|
#endif
|
2015-11-28 06:46:06 +08:00
|
|
|
|
2017-04-11 15:37:44 +08:00
|
|
|
bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
|
2018-04-16 08:26:10 +08:00
|
|
|
const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, bool is_small)
|
2017-04-11 15:37:44 +08:00
|
|
|
{
|
|
|
|
std::error_code EC;
|
|
|
|
raw_fd_ostream dest(filename, EC, sys::fs::F_None);
|
|
|
|
if (EC) {
|
2017-12-27 08:44:08 +08:00
|
|
|
*error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
|
2017-04-11 15:37:44 +08:00
|
|
|
return true;
|
|
|
|
}
|
2015-11-28 06:46:06 +08:00
|
|
|
TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);
|
2017-04-11 15:37:44 +08:00
|
|
|
target_machine->setO0WantsFastISel(true);
|
|
|
|
|
2015-11-28 06:46:06 +08:00
|
|
|
Module* module = unwrap(module_ref);
|
|
|
|
|
2018-02-13 23:54:46 +08:00
|
|
|
PassManagerBuilder *PMBuilder = new(std::nothrow) PassManagerBuilder();
|
|
|
|
if (PMBuilder == nullptr) {
|
|
|
|
*error_message = strdup("memory allocation failure");
|
|
|
|
return true;
|
|
|
|
}
|
2015-11-28 06:46:06 +08:00
|
|
|
PMBuilder->OptLevel = target_machine->getOptLevel();
|
2018-04-16 08:54:40 +08:00
|
|
|
PMBuilder->SizeLevel = is_small ? 2 : 0;
|
2015-11-28 06:46:06 +08:00
|
|
|
|
2017-04-11 15:37:44 +08:00
|
|
|
PMBuilder->DisableTailCalls = is_debug;
|
|
|
|
PMBuilder->DisableUnitAtATime = is_debug;
|
|
|
|
PMBuilder->DisableUnrollLoops = is_debug;
|
|
|
|
PMBuilder->SLPVectorize = !is_debug;
|
|
|
|
PMBuilder->LoopVectorize = !is_debug;
|
|
|
|
PMBuilder->RerollLoops = !is_debug;
|
2018-01-06 13:15:37 +08:00
|
|
|
// Leaving NewGVN as default (off) because when on it caused issue #673
|
|
|
|
//PMBuilder->NewGVN = !is_debug;
|
2017-04-11 15:37:44 +08:00
|
|
|
PMBuilder->DisableGVNLoadPRE = is_debug;
|
|
|
|
PMBuilder->VerifyInput = assertions_on;
|
|
|
|
PMBuilder->VerifyOutput = assertions_on;
|
|
|
|
PMBuilder->MergeFunctions = !is_debug;
|
|
|
|
PMBuilder->PrepareForLTO = false;
|
|
|
|
PMBuilder->PrepareForThinLTO = false;
|
|
|
|
PMBuilder->PerformThinLTO = false;
|
2015-11-28 06:46:06 +08:00
|
|
|
|
2017-04-11 15:37:44 +08:00
|
|
|
TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple()));
|
2015-11-28 06:46:06 +08:00
|
|
|
PMBuilder->LibraryInfo = &tlii;
|
|
|
|
|
2017-04-11 15:37:44 +08:00
|
|
|
if (is_debug) {
|
|
|
|
PMBuilder->Inliner = createAlwaysInlinerLegacyPass(false);
|
|
|
|
} else {
|
2017-06-20 09:36:54 +08:00
|
|
|
target_machine->adjustPassManager(*PMBuilder);
|
2017-04-11 15:37:44 +08:00
|
|
|
|
|
|
|
PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, addDiscriminatorsPass);
|
2017-06-20 09:36:54 +08:00
|
|
|
PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel, false);
|
2017-04-11 15:37:44 +08:00
|
|
|
}
|
2015-11-28 06:46:06 +08:00
|
|
|
|
2018-02-26 07:09:39 +08:00
|
|
|
addCoroutinePassesToExtensionPoints(*PMBuilder);
|
|
|
|
|
2015-11-28 06:46:06 +08:00
|
|
|
// Set up the per-function pass manager.
|
2017-04-11 15:37:44 +08:00
|
|
|
legacy::FunctionPassManager FPM = legacy::FunctionPassManager(module);
|
2018-02-13 23:54:46 +08:00
|
|
|
auto tliwp = new(std::nothrow) TargetLibraryInfoWrapperPass(tlii);
|
|
|
|
FPM.add(tliwp);
|
2017-04-11 15:37:44 +08:00
|
|
|
FPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));
|
|
|
|
if (assertions_on) {
|
|
|
|
FPM.add(createVerifierPass());
|
2015-11-28 06:46:06 +08:00
|
|
|
}
|
2017-04-11 15:37:44 +08:00
|
|
|
PMBuilder->populateFunctionPassManager(FPM);
|
2015-11-28 06:46:06 +08:00
|
|
|
|
|
|
|
// Set up the per-module pass manager.
|
2017-04-11 15:37:44 +08:00
|
|
|
legacy::PassManager MPM;
|
|
|
|
MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));
|
|
|
|
PMBuilder->populateModulePassManager(MPM);
|
|
|
|
|
2017-11-03 21:09:33 +08:00
|
|
|
// Set output pass.
|
2017-04-11 15:37:44 +08:00
|
|
|
TargetMachine::CodeGenFileType ft;
|
2017-11-03 21:09:33 +08:00
|
|
|
if (output_type != ZigLLVM_EmitLLVMIr) {
|
|
|
|
switch (output_type) {
|
|
|
|
case ZigLLVM_EmitAssembly:
|
|
|
|
ft = TargetMachine::CGFT_AssemblyFile;
|
|
|
|
break;
|
|
|
|
case ZigLLVM_EmitBinary:
|
|
|
|
ft = TargetMachine::CGFT_ObjectFile;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (target_machine->addPassesToEmitFile(MPM, dest, ft)) {
|
|
|
|
*error_message = strdup("TargetMachine can't emit a file of this type");
|
|
|
|
return true;
|
|
|
|
}
|
2017-04-11 15:37:44 +08:00
|
|
|
}
|
2015-11-28 06:46:06 +08:00
|
|
|
|
|
|
|
// run per function optimization passes
|
2017-04-11 15:37:44 +08:00
|
|
|
FPM.doInitialization();
|
2015-11-28 06:46:06 +08:00
|
|
|
for (Function &F : *module)
|
|
|
|
if (!F.isDeclaration())
|
2017-04-11 15:37:44 +08:00
|
|
|
FPM.run(F);
|
|
|
|
FPM.doFinalization();
|
2015-11-28 06:46:06 +08:00
|
|
|
|
2017-04-11 15:37:44 +08:00
|
|
|
MPM.run(*module);
|
|
|
|
|
2017-11-03 21:09:33 +08:00
|
|
|
if (output_type == ZigLLVM_EmitLLVMIr) {
|
|
|
|
if (LLVMPrintModuleToFile(module_ref, filename, error_message)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
2017-10-16 09:06:04 +08:00
|
|
|
|
2017-04-11 15:37:44 +08:00
|
|
|
return false;
|
2015-11-28 06:46:06 +08:00
|
|
|
}
|
|
|
|
|
2018-02-26 04:10:29 +08:00
|
|
|
ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref) {
|
|
|
|
return wrap(Type::getTokenTy(*unwrap(context_ref)));
|
|
|
|
}
|
2017-04-11 15:37:44 +08:00
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args,
|
2017-12-07 07:12:05 +08:00
|
|
|
unsigned NumArgs, unsigned CC, ZigLLVM_FnInline fn_inline, const char *Name)
|
2015-11-28 06:46:06 +08:00
|
|
|
{
|
|
|
|
CallInst *call_inst = CallInst::Create(unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Name);
|
|
|
|
call_inst->setCallingConv(CC);
|
2017-12-07 07:12:05 +08:00
|
|
|
switch (fn_inline) {
|
|
|
|
case ZigLLVM_FnInlineAuto:
|
|
|
|
break;
|
|
|
|
case ZigLLVM_FnInlineAlways:
|
|
|
|
call_inst->addAttribute(AttributeList::FunctionIndex, Attribute::AlwaysInline);
|
|
|
|
break;
|
|
|
|
case ZigLLVM_FnInlineNever:
|
|
|
|
call_inst->addAttribute(AttributeList::FunctionIndex, Attribute::NoInline);
|
|
|
|
break;
|
2017-04-13 12:13:54 +08:00
|
|
|
}
|
2015-11-28 06:46:06 +08:00
|
|
|
return wrap(unwrap(B)->Insert(call_inst));
|
|
|
|
}
|
2015-12-01 05:10:07 +08:00
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
void ZigLLVMFnSetSubprogram(LLVMValueRef fn, ZigLLVMDISubprogram *subprogram) {
|
2016-04-10 05:21:00 +08:00
|
|
|
assert( isa<Function>(unwrap(fn)) );
|
|
|
|
Function *unwrapped_function = reinterpret_cast<Function*>(unwrap(fn));
|
|
|
|
unwrapped_function->setSubprogram(reinterpret_cast<DISubprogram*>(subprogram));
|
|
|
|
}
|
|
|
|
|
2016-02-06 05:29:26 +08:00
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIType *ZigLLVMCreateDebugPointerType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *pointee_type,
|
2015-12-01 05:10:07 +08:00
|
|
|
uint64_t size_in_bits, uint64_t align_in_bits, const char *name)
|
|
|
|
{
|
|
|
|
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createPointerType(
|
2017-06-20 09:36:54 +08:00
|
|
|
reinterpret_cast<DIType*>(pointee_type), size_in_bits, align_in_bits, Optional<unsigned>(), name);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIType*>(di_type);
|
2015-12-01 05:10:07 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIType *ZigLLVMCreateDebugBasicType(ZigLLVMDIBuilder *dibuilder, const char *name,
|
2017-03-10 15:29:01 +08:00
|
|
|
uint64_t size_in_bits, unsigned encoding)
|
2015-12-01 05:10:07 +08:00
|
|
|
{
|
|
|
|
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createBasicType(
|
2017-03-10 15:29:01 +08:00
|
|
|
name, size_in_bits, encoding);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIType*>(di_type);
|
2015-12-01 05:10:07 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t size_in_bits,
|
|
|
|
uint64_t align_in_bits, ZigLLVMDIType *elem_type, int elem_count)
|
2015-12-08 11:07:46 +08:00
|
|
|
{
|
|
|
|
SmallVector<Metadata *, 1> subrange;
|
2016-02-03 17:44:21 +08:00
|
|
|
subrange.push_back(reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateSubrange(0, elem_count));
|
2015-12-08 11:07:46 +08:00
|
|
|
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createArrayType(
|
|
|
|
size_in_bits, align_in_bits,
|
|
|
|
reinterpret_cast<DIType*>(elem_type),
|
|
|
|
reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(subrange));
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIType*>(di_type);
|
2015-12-08 11:07:46 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(ZigLLVMDIBuilder *dibuilder, const char *name, int64_t val) {
|
2016-01-11 15:25:17 +08:00
|
|
|
DIEnumerator *di_enumerator = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerator(name, val);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIEnumerator*>(di_enumerator);
|
2016-01-11 15:25:17 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIType *ZigLLVMCreateDebugEnumerationType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
|
|
|
|
const char *name, ZigLLVMDIFile *file, unsigned line_number, uint64_t size_in_bits,
|
|
|
|
uint64_t align_in_bits, ZigLLVMDIEnumerator **enumerator_array, int enumerator_array_len,
|
|
|
|
ZigLLVMDIType *underlying_type, const char *unique_id)
|
2016-01-11 15:25:17 +08:00
|
|
|
{
|
|
|
|
SmallVector<Metadata *, 8> fields;
|
|
|
|
for (int i = 0; i < enumerator_array_len; i += 1) {
|
|
|
|
DIEnumerator *dienumerator = reinterpret_cast<DIEnumerator*>(enumerator_array[i]);
|
|
|
|
fields.push_back(dienumerator);
|
|
|
|
}
|
|
|
|
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createEnumerationType(
|
|
|
|
reinterpret_cast<DIScope*>(scope),
|
|
|
|
name,
|
|
|
|
reinterpret_cast<DIFile*>(file),
|
|
|
|
line_number, size_in_bits, align_in_bits,
|
|
|
|
reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
|
|
|
|
reinterpret_cast<DIType*>(underlying_type),
|
|
|
|
unique_id);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIType*>(di_type);
|
2016-01-11 15:25:17 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIType *ZigLLVMCreateDebugMemberType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
|
|
|
|
const char *name, ZigLLVMDIFile *file, unsigned line, uint64_t size_in_bits,
|
|
|
|
uint64_t align_in_bits, uint64_t offset_in_bits, unsigned flags, ZigLLVMDIType *type)
|
2015-12-17 08:11:35 +08:00
|
|
|
{
|
2017-03-10 15:29:01 +08:00
|
|
|
assert(flags == 0);
|
2015-12-17 08:11:35 +08:00
|
|
|
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createMemberType(
|
|
|
|
reinterpret_cast<DIScope*>(scope),
|
|
|
|
name,
|
|
|
|
reinterpret_cast<DIFile*>(file),
|
2017-03-10 15:29:01 +08:00
|
|
|
line, size_in_bits, align_in_bits, offset_in_bits, DINode::FlagZero,
|
2015-12-17 08:11:35 +08:00
|
|
|
reinterpret_cast<DIType*>(type));
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIType*>(di_type);
|
2015-12-17 08:11:35 +08:00
|
|
|
}
|
2015-12-12 15:10:37 +08:00
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIType *ZigLLVMCreateDebugUnionType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
|
|
|
|
const char *name, ZigLLVMDIFile *file, unsigned line_number, uint64_t size_in_bits,
|
|
|
|
uint64_t align_in_bits, unsigned flags, ZigLLVMDIType **types_array, int types_array_len,
|
2016-01-11 15:25:17 +08:00
|
|
|
unsigned run_time_lang, const char *unique_id)
|
|
|
|
{
|
|
|
|
SmallVector<Metadata *, 8> fields;
|
|
|
|
for (int i = 0; i < types_array_len; i += 1) {
|
|
|
|
DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
|
|
|
|
fields.push_back(ditype);
|
|
|
|
}
|
2017-03-10 15:29:01 +08:00
|
|
|
assert(flags == 0);
|
2016-01-11 15:25:17 +08:00
|
|
|
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createUnionType(
|
|
|
|
reinterpret_cast<DIScope*>(scope),
|
|
|
|
name,
|
|
|
|
reinterpret_cast<DIFile*>(file),
|
2017-03-10 15:29:01 +08:00
|
|
|
line_number, size_in_bits, align_in_bits, DINode::FlagZero,
|
2016-01-11 15:25:17 +08:00
|
|
|
reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
|
|
|
|
run_time_lang, unique_id);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIType*>(di_type);
|
2016-01-11 15:25:17 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIType *ZigLLVMCreateDebugStructType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
|
|
|
|
const char *name, ZigLLVMDIFile *file, unsigned line_number, uint64_t size_in_bits,
|
2017-09-02 01:27:04 +08:00
|
|
|
uint64_t align_in_bits, unsigned flags, ZigLLVMDIType *derived_from,
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIType **types_array, int types_array_len, unsigned run_time_lang, ZigLLVMDIType *vtable_holder,
|
2015-12-12 15:10:37 +08:00
|
|
|
const char *unique_id)
|
|
|
|
{
|
|
|
|
SmallVector<Metadata *, 8> fields;
|
|
|
|
for (int i = 0; i < types_array_len; i += 1) {
|
|
|
|
DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
|
|
|
|
fields.push_back(ditype);
|
|
|
|
}
|
2017-03-10 15:29:01 +08:00
|
|
|
assert(flags == 0);
|
2015-12-12 15:10:37 +08:00
|
|
|
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createStructType(
|
|
|
|
reinterpret_cast<DIScope*>(scope),
|
|
|
|
name,
|
|
|
|
reinterpret_cast<DIFile*>(file),
|
2017-03-10 15:29:01 +08:00
|
|
|
line_number, size_in_bits, align_in_bits, DINode::FlagZero,
|
2015-12-12 15:10:37 +08:00
|
|
|
reinterpret_cast<DIType*>(derived_from),
|
|
|
|
reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields),
|
|
|
|
run_time_lang,
|
|
|
|
reinterpret_cast<DIType*>(vtable_holder),
|
|
|
|
unique_id);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIType*>(di_type);
|
2015-12-12 15:10:37 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIType *ZigLLVMCreateReplaceableCompositeType(ZigLLVMDIBuilder *dibuilder, unsigned tag,
|
|
|
|
const char *name, ZigLLVMDIScope *scope, ZigLLVMDIFile *file, unsigned line)
|
2015-12-17 08:11:35 +08:00
|
|
|
{
|
|
|
|
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createReplaceableCompositeType(
|
|
|
|
tag, name,
|
|
|
|
reinterpret_cast<DIScope*>(scope),
|
|
|
|
reinterpret_cast<DIFile*>(file),
|
2016-02-01 08:48:19 +08:00
|
|
|
line);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIType*>(di_type);
|
2016-02-01 08:48:19 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIType *ZigLLVMCreateDebugForwardDeclType(ZigLLVMDIBuilder *dibuilder, unsigned tag,
|
|
|
|
const char *name, ZigLLVMDIScope *scope, ZigLLVMDIFile *file, unsigned line)
|
2016-02-01 08:48:19 +08:00
|
|
|
{
|
|
|
|
DIType *di_type = reinterpret_cast<DIBuilder*>(dibuilder)->createForwardDecl(
|
|
|
|
tag, name,
|
|
|
|
reinterpret_cast<DIScope*>(scope),
|
|
|
|
reinterpret_cast<DIFile*>(file),
|
2015-12-17 08:11:35 +08:00
|
|
|
line);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIType*>(di_type);
|
2015-12-17 08:11:35 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
void ZigLLVMReplaceTemporary(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *type,
|
|
|
|
ZigLLVMDIType *replacement)
|
2015-12-17 08:11:35 +08:00
|
|
|
{
|
|
|
|
reinterpret_cast<DIBuilder*>(dibuilder)->replaceTemporary(
|
|
|
|
TempDIType(reinterpret_cast<DIType*>(type)),
|
|
|
|
reinterpret_cast<DIType*>(replacement));
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
void ZigLLVMReplaceDebugArrays(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *type,
|
|
|
|
ZigLLVMDIType **types_array, int types_array_len)
|
2015-12-17 08:11:35 +08:00
|
|
|
{
|
|
|
|
SmallVector<Metadata *, 8> fields;
|
|
|
|
for (int i = 0; i < types_array_len; i += 1) {
|
|
|
|
DIType *ditype = reinterpret_cast<DIType*>(types_array[i]);
|
|
|
|
fields.push_back(ditype);
|
|
|
|
}
|
|
|
|
DICompositeType *composite_type = (DICompositeType*)reinterpret_cast<DIType*>(type);
|
|
|
|
reinterpret_cast<DIBuilder*>(dibuilder)->replaceArrays(
|
|
|
|
composite_type,
|
|
|
|
reinterpret_cast<DIBuilder*>(dibuilder)->getOrCreateArray(fields));
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIType *ZigLLVMCreateSubroutineType(ZigLLVMDIBuilder *dibuilder_wrapped,
|
|
|
|
ZigLLVMDIType **types_array, int types_array_len, unsigned flags)
|
2015-12-01 05:43:09 +08:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
2017-03-10 15:29:01 +08:00
|
|
|
assert(flags == 0);
|
2015-12-01 05:43:09 +08:00
|
|
|
DIBuilder *dibuilder = reinterpret_cast<DIBuilder*>(dibuilder_wrapped);
|
|
|
|
DISubroutineType *subroutine_type = dibuilder->createSubroutineType(
|
|
|
|
dibuilder->getOrCreateTypeArray(types),
|
2017-03-10 15:29:01 +08:00
|
|
|
DINode::FlagZero);
|
2016-01-19 07:42:45 +08:00
|
|
|
DIType *ditype = subroutine_type;
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIType*>(ditype);
|
2015-12-01 05:43:09 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
unsigned ZigLLVMEncoding_DW_ATE_unsigned(void) {
|
2015-12-01 05:10:07 +08:00
|
|
|
return dwarf::DW_ATE_unsigned;
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
unsigned ZigLLVMEncoding_DW_ATE_signed(void) {
|
2015-12-01 05:10:07 +08:00
|
|
|
return dwarf::DW_ATE_signed;
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
unsigned ZigLLVMEncoding_DW_ATE_float(void) {
|
2015-12-09 03:25:30 +08:00
|
|
|
return dwarf::DW_ATE_float;
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
unsigned ZigLLVMEncoding_DW_ATE_boolean(void) {
|
2016-02-05 05:02:37 +08:00
|
|
|
return dwarf::DW_ATE_boolean;
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
unsigned ZigLLVMEncoding_DW_ATE_unsigned_char(void) {
|
2016-02-05 05:02:37 +08:00
|
|
|
return dwarf::DW_ATE_unsigned_char;
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
unsigned ZigLLVMEncoding_DW_ATE_signed_char(void) {
|
2016-02-05 05:02:37 +08:00
|
|
|
return dwarf::DW_ATE_signed_char;
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
unsigned ZigLLVMLang_DW_LANG_C99(void) {
|
2015-12-01 05:10:07 +08:00
|
|
|
return dwarf::DW_LANG_C99;
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
unsigned ZigLLVMTag_DW_variable(void) {
|
2016-03-09 09:56:14 +08:00
|
|
|
return dwarf::DW_TAG_variable;
|
2015-12-08 13:11:04 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
unsigned ZigLLVMTag_DW_structure_type(void) {
|
2015-12-17 08:11:35 +08:00
|
|
|
return dwarf::DW_TAG_structure_type;
|
|
|
|
}
|
|
|
|
|
2018-01-31 14:51:15 +08:00
|
|
|
unsigned ZigLLVMTag_DW_enumeration_type(void) {
|
|
|
|
return dwarf::DW_TAG_enumeration_type;
|
|
|
|
}
|
|
|
|
|
2017-11-15 12:53:53 +08:00
|
|
|
unsigned ZigLLVMTag_DW_union_type(void) {
|
|
|
|
return dwarf::DW_TAG_union_type;
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) {
|
2018-02-13 23:54:46 +08:00
|
|
|
DIBuilder *di_builder = new(std::nothrow) DIBuilder(*unwrap(module), allow_unresolved);
|
2017-12-27 08:44:08 +08:00
|
|
|
if (di_builder == nullptr)
|
|
|
|
return nullptr;
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIBuilder *>(di_builder);
|
2015-12-01 05:10:07 +08:00
|
|
|
}
|
|
|
|
|
2018-07-17 08:52:50 +08:00
|
|
|
void ZigLLVMDisposeDIBuilder(ZigLLVMDIBuilder *dbuilder) {
|
|
|
|
DIBuilder *di_builder = reinterpret_cast<DIBuilder *>(dbuilder);
|
|
|
|
delete di_builder;
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, int line, int column, ZigLLVMDIScope *scope) {
|
2015-12-01 05:43:09 +08:00
|
|
|
unwrap(builder)->SetCurrentDebugLocation(DebugLoc::get(
|
2015-12-01 05:10:07 +08:00
|
|
|
line, column, reinterpret_cast<DIScope*>(scope)));
|
|
|
|
}
|
|
|
|
|
2016-04-28 08:34:53 +08:00
|
|
|
void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder) {
|
|
|
|
unwrap(builder)->SetCurrentDebugLocation(DebugLoc());
|
|
|
|
}
|
|
|
|
|
2015-12-01 05:10:07 +08:00
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDILexicalBlock *ZigLLVMCreateLexicalBlock(ZigLLVMDIBuilder *dbuilder, ZigLLVMDIScope *scope,
|
|
|
|
ZigLLVMDIFile *file, unsigned line, unsigned col)
|
2015-12-01 05:10:07 +08:00
|
|
|
{
|
|
|
|
DILexicalBlock *result = reinterpret_cast<DIBuilder*>(dbuilder)->createLexicalBlock(
|
|
|
|
reinterpret_cast<DIScope*>(scope),
|
|
|
|
reinterpret_cast<DIFile*>(file),
|
|
|
|
line,
|
|
|
|
col);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDILexicalBlock*>(result);
|
2015-12-01 05:10:07 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder,
|
|
|
|
ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,
|
|
|
|
ZigLLVMDIType *type, bool always_preserve, unsigned flags)
|
2016-03-09 09:56:14 +08:00
|
|
|
{
|
2017-03-10 15:29:01 +08:00
|
|
|
assert(flags == 0);
|
2016-03-09 09:56:14 +08:00
|
|
|
DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createAutoVariable(
|
|
|
|
reinterpret_cast<DIScope*>(scope),
|
|
|
|
name,
|
|
|
|
reinterpret_cast<DIFile*>(file),
|
|
|
|
line_no,
|
|
|
|
reinterpret_cast<DIType*>(type),
|
|
|
|
always_preserve,
|
2017-03-10 15:29:01 +08:00
|
|
|
DINode::FlagZero);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDILocalVariable*>(result);
|
2016-03-09 09:56:14 +08:00
|
|
|
}
|
2015-12-08 13:11:04 +08:00
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIGlobalVariable *ZigLLVMCreateGlobalVariable(ZigLLVMDIBuilder *dbuilder,
|
|
|
|
ZigLLVMDIScope *scope, const char *name, const char *linkage_name, ZigLLVMDIFile *file,
|
2017-03-10 15:29:01 +08:00
|
|
|
unsigned line_no, ZigLLVMDIType *di_type, bool is_local_to_unit)
|
2016-09-05 13:32:23 +08:00
|
|
|
{
|
2017-03-10 15:29:01 +08:00
|
|
|
DIGlobalVariableExpression *result = reinterpret_cast<DIBuilder*>(dbuilder)->createGlobalVariableExpression(
|
2016-09-05 13:32:23 +08:00
|
|
|
reinterpret_cast<DIScope*>(scope),
|
|
|
|
name,
|
|
|
|
linkage_name,
|
|
|
|
reinterpret_cast<DIFile*>(file),
|
|
|
|
line_no,
|
|
|
|
reinterpret_cast<DIType*>(di_type),
|
2017-03-10 15:29:01 +08:00
|
|
|
is_local_to_unit);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIGlobalVariable*>(result);
|
2016-09-05 13:32:23 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilder,
|
|
|
|
ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no,
|
|
|
|
ZigLLVMDIType *type, bool always_preserve, unsigned flags, unsigned arg_no)
|
2015-12-08 13:11:04 +08:00
|
|
|
{
|
2017-03-10 15:29:01 +08:00
|
|
|
assert(flags == 0);
|
2016-03-09 09:56:14 +08:00
|
|
|
DILocalVariable *result = reinterpret_cast<DIBuilder*>(dbuilder)->createParameterVariable(
|
2015-12-08 13:11:04 +08:00
|
|
|
reinterpret_cast<DIScope*>(scope),
|
|
|
|
name,
|
2016-03-09 09:56:14 +08:00
|
|
|
arg_no,
|
2015-12-08 13:11:04 +08:00
|
|
|
reinterpret_cast<DIFile*>(file),
|
|
|
|
line_no,
|
|
|
|
reinterpret_cast<DIType*>(type),
|
|
|
|
always_preserve,
|
2017-03-10 15:29:01 +08:00
|
|
|
DINode::FlagZero);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDILocalVariable*>(result);
|
2015-12-08 13:11:04 +08:00
|
|
|
}
|
2015-12-08 11:57:45 +08:00
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(ZigLLVMDILexicalBlock *lexical_block) {
|
2015-12-01 05:10:07 +08:00
|
|
|
DIScope *scope = reinterpret_cast<DILexicalBlock*>(lexical_block);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIScope*>(scope);
|
2015-12-01 05:10:07 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIScope *ZigLLVMCompileUnitToScope(ZigLLVMDICompileUnit *compile_unit) {
|
2015-12-01 05:10:07 +08:00
|
|
|
DIScope *scope = reinterpret_cast<DICompileUnit*>(compile_unit);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIScope*>(scope);
|
2015-12-01 05:10:07 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIScope *ZigLLVMFileToScope(ZigLLVMDIFile *difile) {
|
2015-12-01 05:10:07 +08:00
|
|
|
DIScope *scope = reinterpret_cast<DIFile*>(difile);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIScope*>(scope);
|
2015-12-01 05:10:07 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIScope *ZigLLVMSubprogramToScope(ZigLLVMDISubprogram *subprogram) {
|
2015-12-01 05:10:07 +08:00
|
|
|
DIScope *scope = reinterpret_cast<DISubprogram*>(subprogram);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIScope*>(scope);
|
2015-12-01 05:10:07 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIScope *ZigLLVMTypeToScope(ZigLLVMDIType *type) {
|
2015-12-17 08:11:35 +08:00
|
|
|
DIScope *scope = reinterpret_cast<DIType*>(type);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIScope*>(scope);
|
2015-12-17 08:11:35 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDICompileUnit *ZigLLVMCreateCompileUnit(ZigLLVMDIBuilder *dibuilder,
|
2017-03-10 15:29:01 +08:00
|
|
|
unsigned lang, ZigLLVMDIFile *difile, const char *producer,
|
2015-12-01 05:10:07 +08:00
|
|
|
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(
|
2017-03-10 15:29:01 +08:00
|
|
|
lang,
|
|
|
|
reinterpret_cast<DIFile*>(difile),
|
|
|
|
producer, is_optimized, flags, runtime_version, split_name,
|
|
|
|
(emit_debug_info ? DICompileUnit::DebugEmissionKind::FullDebug : DICompileUnit::DebugEmissionKind::NoDebug),
|
|
|
|
dwo_id);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDICompileUnit*>(result);
|
2015-12-01 05:10:07 +08:00
|
|
|
}
|
|
|
|
|
2016-09-05 09:30:40 +08:00
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDIFile *ZigLLVMCreateFile(ZigLLVMDIBuilder *dibuilder, const char *filename, const char *directory) {
|
2015-12-01 05:10:07 +08:00
|
|
|
DIFile *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFile(filename, directory);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDIFile*>(result);
|
2015-12-01 05:10:07 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDISubprogram *ZigLLVMCreateFunction(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIScope *scope,
|
|
|
|
const char *name, const char *linkage_name, ZigLLVMDIFile *file, unsigned lineno,
|
|
|
|
ZigLLVMDIType *fn_di_type, bool is_local_to_unit, bool is_definition, unsigned scope_line,
|
|
|
|
unsigned flags, bool is_optimized, ZigLLVMDISubprogram *decl_subprogram)
|
2015-12-01 05:10:07 +08:00
|
|
|
{
|
2016-01-19 07:42:45 +08:00
|
|
|
DISubroutineType *di_sub_type = static_cast<DISubroutineType*>(reinterpret_cast<DIType*>(fn_di_type));
|
2017-03-10 15:29:01 +08:00
|
|
|
assert(flags == 0);
|
2015-12-01 05:10:07 +08:00
|
|
|
DISubprogram *result = reinterpret_cast<DIBuilder*>(dibuilder)->createFunction(
|
|
|
|
reinterpret_cast<DIScope*>(scope),
|
|
|
|
name, linkage_name,
|
|
|
|
reinterpret_cast<DIFile*>(file),
|
|
|
|
lineno,
|
2016-01-19 07:42:45 +08:00
|
|
|
di_sub_type,
|
2017-03-10 15:29:01 +08:00
|
|
|
is_local_to_unit, is_definition, scope_line, DINode::FlagZero, is_optimized,
|
2016-03-09 09:56:14 +08:00
|
|
|
nullptr,
|
|
|
|
reinterpret_cast<DISubprogram *>(decl_subprogram));
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDISubprogram*>(result);
|
2015-12-01 05:10:07 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
void ZigLLVMDIBuilderFinalize(ZigLLVMDIBuilder *dibuilder) {
|
2015-12-01 05:10:07 +08:00
|
|
|
reinterpret_cast<DIBuilder*>(dibuilder)->finalize();
|
|
|
|
}
|
2015-12-01 05:43:09 +08:00
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
LLVMValueRef ZigLLVMInsertDeclareAtEnd(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
|
|
|
|
ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref)
|
2016-01-03 11:42:32 +08:00
|
|
|
{
|
|
|
|
Instruction *result = reinterpret_cast<DIBuilder*>(dibuilder)->insertDeclare(
|
|
|
|
unwrap(storage),
|
|
|
|
reinterpret_cast<DILocalVariable *>(var_info),
|
|
|
|
reinterpret_cast<DIBuilder*>(dibuilder)->createExpression(),
|
|
|
|
reinterpret_cast<DILocation*>(debug_loc),
|
|
|
|
static_cast<BasicBlock*>(unwrap(basic_block_ref)));
|
|
|
|
return wrap(result);
|
|
|
|
}
|
2015-12-08 14:09:48 +08:00
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
LLVMValueRef ZigLLVMInsertDeclare(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage,
|
|
|
|
ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc, LLVMValueRef insert_before_instr)
|
2015-12-08 14:09:48 +08:00
|
|
|
{
|
|
|
|
Instruction *result = reinterpret_cast<DIBuilder*>(dibuilder)->insertDeclare(
|
|
|
|
unwrap(storage),
|
|
|
|
reinterpret_cast<DILocalVariable *>(var_info),
|
|
|
|
reinterpret_cast<DIBuilder*>(dibuilder)->createExpression(),
|
|
|
|
reinterpret_cast<DILocation*>(debug_loc),
|
|
|
|
static_cast<Instruction*>(unwrap(insert_before_instr)));
|
|
|
|
return wrap(result);
|
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScope *scope) {
|
2015-12-08 14:09:48 +08:00
|
|
|
DebugLoc debug_loc = DebugLoc::get(line, col, reinterpret_cast<DIScope*>(scope), nullptr);
|
2016-09-10 00:25:16 +08:00
|
|
|
return reinterpret_cast<ZigLLVMDILocation*>(debug_loc.get());
|
2015-12-08 14:09:48 +08:00
|
|
|
}
|
|
|
|
|
2016-09-10 00:25:16 +08:00
|
|
|
void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) {
|
2015-12-09 03:25:30 +08:00
|
|
|
if (on_state) {
|
|
|
|
FastMathFlags fmf;
|
2017-11-30 08:11:34 +08:00
|
|
|
fmf.setFast();
|
2016-03-09 09:56:14 +08:00
|
|
|
unwrap(builder_wrapped)->setFastMathFlags(fmf);
|
2015-12-09 03:25:30 +08:00
|
|
|
} else {
|
|
|
|
unwrap(builder_wrapped)->clearFastMathFlags();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-28 08:34:53 +08:00
|
|
|
void ZigLLVMAddFunctionAttr(LLVMValueRef fn_ref, const char *attr_name, const char *attr_value) {
|
|
|
|
Function *func = unwrap<Function>(fn_ref);
|
2017-06-20 09:36:54 +08:00
|
|
|
const AttributeList attr_set = func->getAttributes();
|
2016-04-28 08:34:53 +08:00
|
|
|
AttrBuilder attr_builder;
|
|
|
|
if (attr_value) {
|
|
|
|
attr_builder.addAttribute(attr_name, attr_value);
|
|
|
|
} else {
|
|
|
|
attr_builder.addAttribute(attr_name);
|
|
|
|
}
|
2017-06-20 09:36:54 +08:00
|
|
|
const AttributeList new_attr_set = attr_set.addAttributes(func->getContext(),
|
|
|
|
AttributeList::FunctionIndex, attr_builder);
|
2016-04-28 08:34:53 +08:00
|
|
|
func->setAttributes(new_attr_set);
|
|
|
|
}
|
|
|
|
|
2017-02-07 02:50:19 +08:00
|
|
|
void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn_ref) {
|
|
|
|
Function *func = unwrap<Function>(fn_ref);
|
2017-06-20 09:36:54 +08:00
|
|
|
const AttributeList attr_set = func->getAttributes();
|
|
|
|
const AttributeList new_attr_set = attr_set.addAttribute(func->getContext(), AttributeList::FunctionIndex,
|
2017-02-07 02:50:19 +08:00
|
|
|
Attribute::Cold);
|
|
|
|
func->setAttributes(new_attr_set);
|
|
|
|
}
|
|
|
|
|
2017-12-27 08:44:08 +08:00
|
|
|
void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) {
|
2017-09-18 05:46:16 +08:00
|
|
|
llvm::cl::ParseCommandLineOptions(argc, argv);
|
|
|
|
}
|
|
|
|
|
2016-02-11 06:41:50 +08:00
|
|
|
|
|
|
|
static_assert((Triple::ArchType)ZigLLVM_LastArchType == Triple::LastArchType, "");
|
|
|
|
static_assert((Triple::VendorType)ZigLLVM_LastVendorType == Triple::LastVendorType, "");
|
|
|
|
static_assert((Triple::OSType)ZigLLVM_LastOSType == Triple::LastOSType, "");
|
|
|
|
static_assert((Triple::EnvironmentType)ZigLLVM_LastEnvironmentType == Triple::LastEnvironmentType, "");
|
2017-10-24 09:43:18 +08:00
|
|
|
static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v5 == Triple::KalimbaSubArch_v5, "");
|
2016-02-11 06:41:50 +08:00
|
|
|
|
2016-02-11 16:33:27 +08:00
|
|
|
static_assert((Triple::ObjectFormatType)ZigLLVM_UnknownObjectFormat == Triple::UnknownObjectFormat, "");
|
|
|
|
static_assert((Triple::ObjectFormatType)ZigLLVM_COFF == Triple::COFF, "");
|
|
|
|
static_assert((Triple::ObjectFormatType)ZigLLVM_ELF == Triple::ELF, "");
|
|
|
|
static_assert((Triple::ObjectFormatType)ZigLLVM_MachO == Triple::MachO, "");
|
2017-10-24 09:43:18 +08:00
|
|
|
static_assert((Triple::ObjectFormatType)ZigLLVM_Wasm == Triple::Wasm, "");
|
2016-02-11 16:33:27 +08:00
|
|
|
|
2016-02-11 06:41:50 +08:00
|
|
|
const char *ZigLLVMGetArchTypeName(ZigLLVM_ArchType arch) {
|
2017-03-10 15:29:01 +08:00
|
|
|
return (const char*)Triple::getArchTypeName((Triple::ArchType)arch).bytes_begin();
|
2016-02-11 06:41:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor) {
|
2017-03-10 15:29:01 +08:00
|
|
|
return (const char*)Triple::getVendorTypeName((Triple::VendorType)vendor).bytes_begin();
|
2016-02-11 06:41:50 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *ZigLLVMGetOSTypeName(ZigLLVM_OSType os) {
|
2017-03-10 15:29:01 +08:00
|
|
|
return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin();
|
2016-02-11 06:41:50 +08:00
|
|
|
}
|
|
|
|
|
2016-02-17 11:03:41 +08:00
|
|
|
const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) {
|
2017-03-10 15:29:01 +08:00
|
|
|
return (const char*)Triple::getEnvironmentTypeName((Triple::EnvironmentType)env_type).bytes_begin();
|
2016-02-11 06:41:50 +08:00
|
|
|
}
|
|
|
|
|
2016-02-11 07:35:07 +08:00
|
|
|
void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *sub_arch_type,
|
2016-02-11 16:33:27 +08:00
|
|
|
ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type,
|
|
|
|
ZigLLVM_ObjectFormatType *oformat)
|
2016-02-11 07:35:07 +08:00
|
|
|
{
|
|
|
|
char *native_triple = LLVMGetDefaultTargetTriple();
|
|
|
|
Triple triple(native_triple);
|
|
|
|
|
|
|
|
*arch_type = (ZigLLVM_ArchType)triple.getArch();
|
|
|
|
*sub_arch_type = (ZigLLVM_SubArchType)triple.getSubArch();
|
|
|
|
*vendor_type = (ZigLLVM_VendorType)triple.getVendor();
|
|
|
|
*os_type = (ZigLLVM_OSType)triple.getOS();
|
|
|
|
*environ_type = (ZigLLVM_EnvironmentType)triple.getEnvironment();
|
2016-02-11 16:33:27 +08:00
|
|
|
*oformat = (ZigLLVM_ObjectFormatType)triple.getObjectFormat();
|
2016-02-11 07:35:07 +08:00
|
|
|
|
|
|
|
free(native_triple);
|
|
|
|
}
|
|
|
|
|
2016-02-11 07:58:15 +08:00
|
|
|
const char *ZigLLVMGetSubArchTypeName(ZigLLVM_SubArchType sub_arch) {
|
|
|
|
switch (sub_arch) {
|
|
|
|
case ZigLLVM_NoSubArch:
|
|
|
|
return "(none)";
|
2017-10-24 09:43:18 +08:00
|
|
|
case ZigLLVM_ARMSubArch_v8_3a:
|
|
|
|
return "v8_3a";
|
2016-03-09 09:56:14 +08:00
|
|
|
case ZigLLVM_ARMSubArch_v8_2a:
|
|
|
|
return "v8_2a";
|
2016-02-11 07:58:15 +08:00
|
|
|
case ZigLLVM_ARMSubArch_v8_1a:
|
|
|
|
return "v8_1a";
|
|
|
|
case ZigLLVM_ARMSubArch_v8:
|
|
|
|
return "v8";
|
2017-03-10 15:29:01 +08:00
|
|
|
case ZigLLVM_ARMSubArch_v8r:
|
|
|
|
return "v8r";
|
2016-09-05 09:30:40 +08:00
|
|
|
case ZigLLVM_ARMSubArch_v8m_baseline:
|
|
|
|
return "v8m_baseline";
|
|
|
|
case ZigLLVM_ARMSubArch_v8m_mainline:
|
|
|
|
return "v8m_mainline";
|
2016-02-11 07:58:15 +08:00
|
|
|
case ZigLLVM_ARMSubArch_v7:
|
|
|
|
return "v7";
|
|
|
|
case ZigLLVM_ARMSubArch_v7em:
|
|
|
|
return "v7em";
|
|
|
|
case ZigLLVM_ARMSubArch_v7m:
|
|
|
|
return "v7m";
|
|
|
|
case ZigLLVM_ARMSubArch_v7s:
|
|
|
|
return "v7s";
|
2016-03-09 09:56:14 +08:00
|
|
|
case ZigLLVM_ARMSubArch_v7k:
|
|
|
|
return "v7k";
|
2017-06-20 09:36:54 +08:00
|
|
|
case ZigLLVM_ARMSubArch_v7ve:
|
|
|
|
return "v7ve";
|
2016-02-11 07:58:15 +08:00
|
|
|
case ZigLLVM_ARMSubArch_v6:
|
|
|
|
return "v6";
|
|
|
|
case ZigLLVM_ARMSubArch_v6m:
|
|
|
|
return "v6m";
|
|
|
|
case ZigLLVM_ARMSubArch_v6k:
|
|
|
|
return "v6k";
|
|
|
|
case ZigLLVM_ARMSubArch_v6t2:
|
|
|
|
return "v6t2";
|
|
|
|
case ZigLLVM_ARMSubArch_v5:
|
|
|
|
return "v5";
|
|
|
|
case ZigLLVM_ARMSubArch_v5te:
|
|
|
|
return "v5te";
|
|
|
|
case ZigLLVM_ARMSubArch_v4t:
|
|
|
|
return "v4t";
|
|
|
|
case ZigLLVM_KalimbaSubArch_v3:
|
|
|
|
return "v3";
|
|
|
|
case ZigLLVM_KalimbaSubArch_v4:
|
|
|
|
return "v4";
|
|
|
|
case ZigLLVM_KalimbaSubArch_v5:
|
|
|
|
return "v5";
|
|
|
|
}
|
2016-02-13 05:07:12 +08:00
|
|
|
abort();
|
2016-02-11 07:58:15 +08:00
|
|
|
}
|
|
|
|
|
2016-04-10 05:21:00 +08:00
|
|
|
void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module) {
|
|
|
|
unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION);
|
|
|
|
}
|
|
|
|
|
2017-10-11 06:04:02 +08:00
|
|
|
void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module) {
|
|
|
|
unwrap(module)->addModuleFlag(Module::Warning, "CodeView", 1);
|
|
|
|
}
|
|
|
|
|
2016-05-05 09:19:49 +08:00
|
|
|
static AtomicOrdering mapFromLLVMOrdering(LLVMAtomicOrdering Ordering) {
|
|
|
|
switch (Ordering) {
|
2016-09-05 09:30:40 +08:00
|
|
|
case LLVMAtomicOrderingNotAtomic: return AtomicOrdering::NotAtomic;
|
|
|
|
case LLVMAtomicOrderingUnordered: return AtomicOrdering::Unordered;
|
|
|
|
case LLVMAtomicOrderingMonotonic: return AtomicOrdering::Monotonic;
|
|
|
|
case LLVMAtomicOrderingAcquire: return AtomicOrdering::Acquire;
|
|
|
|
case LLVMAtomicOrderingRelease: return AtomicOrdering::Release;
|
|
|
|
case LLVMAtomicOrderingAcquireRelease: return AtomicOrdering::AcquireRelease;
|
|
|
|
case LLVMAtomicOrderingSequentiallyConsistent: return AtomicOrdering::SequentiallyConsistent;
|
2016-05-05 09:19:49 +08:00
|
|
|
}
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef ZigLLVMBuildCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef cmp,
|
|
|
|
LLVMValueRef new_val, LLVMAtomicOrdering success_ordering,
|
2018-04-19 00:16:42 +08:00
|
|
|
LLVMAtomicOrdering failure_ordering, bool is_weak)
|
2016-05-05 09:19:49 +08:00
|
|
|
{
|
2018-04-19 00:16:42 +08:00
|
|
|
AtomicCmpXchgInst *inst = unwrap(builder)->CreateAtomicCmpXchg(unwrap(ptr), unwrap(cmp),
|
|
|
|
unwrap(new_val), mapFromLLVMOrdering(success_ordering), mapFromLLVMOrdering(failure_ordering));
|
|
|
|
inst->setWeak(is_weak);
|
|
|
|
return wrap(inst);
|
2016-05-05 09:19:49 +08:00
|
|
|
}
|
|
|
|
|
2016-05-07 06:46:38 +08:00
|
|
|
LLVMValueRef ZigLLVMBuildNSWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
return wrap(unwrap(builder)->CreateShl(unwrap(LHS), unwrap(RHS), name, false, true));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef ZigLLVMBuildNUWShl(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *name)
|
|
|
|
{
|
2017-08-09 22:09:38 +08:00
|
|
|
return wrap(unwrap(builder)->CreateShl(unwrap(LHS), unwrap(RHS), name, true, false));
|
|
|
|
}
|
|
|
|
|
|
|
|
LLVMValueRef ZigLLVMBuildLShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
return wrap(unwrap(builder)->CreateLShr(unwrap(LHS), unwrap(RHS), name, true));
|
2016-05-07 06:46:38 +08:00
|
|
|
}
|
|
|
|
|
2017-08-09 22:09:38 +08:00
|
|
|
LLVMValueRef ZigLLVMBuildAShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
return wrap(unwrap(builder)->CreateAShr(unwrap(LHS), unwrap(RHS), name, true));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-12-27 08:44:08 +08:00
|
|
|
class MyOStream: public raw_ostream {
|
|
|
|
public:
|
|
|
|
MyOStream(void (*_append_diagnostic)(void *, const char *, size_t), void *_context) :
|
|
|
|
raw_ostream(true), append_diagnostic(_append_diagnostic), context(_context), pos(0) {
|
|
|
|
|
|
|
|
}
|
|
|
|
void write_impl(const char *ptr, size_t len) override {
|
|
|
|
append_diagnostic(context, ptr, len);
|
|
|
|
pos += len;
|
|
|
|
}
|
|
|
|
uint64_t current_pos() const override {
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
void (*append_diagnostic)(void *, const char *, size_t);
|
|
|
|
void *context;
|
|
|
|
size_t pos;
|
|
|
|
};
|
|
|
|
|
2016-02-11 06:41:50 +08:00
|
|
|
|
2017-12-27 08:44:08 +08:00
|
|
|
bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count,
|
|
|
|
void (*append_diagnostic)(void *, const char *, size_t), void *context)
|
|
|
|
{
|
2017-03-13 23:54:56 +08:00
|
|
|
ArrayRef<const char *> array_ref_args(args, arg_count);
|
|
|
|
|
2017-12-27 08:44:08 +08:00
|
|
|
MyOStream diag(append_diagnostic, context);
|
2017-03-13 23:54:56 +08:00
|
|
|
|
|
|
|
switch (oformat) {
|
|
|
|
case ZigLLVM_UnknownObjectFormat:
|
2017-12-27 08:44:08 +08:00
|
|
|
assert(false); // unreachable
|
2017-03-13 23:54:56 +08:00
|
|
|
|
|
|
|
case ZigLLVM_COFF:
|
2017-12-02 02:44:28 +08:00
|
|
|
return lld::coff::link(array_ref_args, false, diag);
|
2017-03-13 23:54:56 +08:00
|
|
|
|
|
|
|
case ZigLLVM_ELF:
|
|
|
|
return lld::elf::link(array_ref_args, false, diag);
|
|
|
|
|
|
|
|
case ZigLLVM_MachO:
|
|
|
|
return lld::mach_o::link(array_ref_args, diag);
|
2017-06-20 09:36:54 +08:00
|
|
|
|
|
|
|
case ZigLLVM_Wasm:
|
2018-06-10 10:39:22 +08:00
|
|
|
return lld::wasm::link(array_ref_args, false, diag);
|
2017-03-13 23:54:56 +08:00
|
|
|
}
|
2017-12-27 08:44:08 +08:00
|
|
|
assert(false); // unreachable
|
|
|
|
abort();
|
2017-03-13 23:54:56 +08:00
|
|
|
}
|