/* * Copyright (c) 2015 Andrew Kelley * * This file is part of zig, which is MIT licensed. * See http://opensource.org/licenses/MIT */ /* * 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 "zig_llvm.h" #if __GNUC__ >= 8 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wclass-memaccess" #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #if __GNUC__ >= 8 #pragma GCC diagnostic pop #endif #include #include using namespace llvm; void ZigLLVMInitializeLoopStrengthReducePass(LLVMPassRegistryRef R) { initializeLoopStrengthReducePass(*unwrap(R)); } void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R) { initializeLowerIntrinsicsPass(*unwrap(R)); } char *ZigLLVMGetHostCPUName(void) { return strdup((const char *)sys::getHostCPUName().bytes_begin()); } char *ZigLLVMGetNativeFeatures(void) { SubtargetFeatures features; StringMap host_features; if (sys::getHostCPUFeatures(host_features)) { for (auto &F : host_features) features.AddFeature(F.first(), F.second); } return strdup((const char *)StringRef(features.getString()).bytes_begin()); } static void addDiscriminatorsPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) { PM.add(createAddDiscriminatorsPass()); } #ifndef NDEBUG static const bool assertions_on = true; #else static const bool assertions_on = false; #endif bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref, const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug, bool is_small, bool time_report) { TimePassesIsEnabled = time_report; std::error_code EC; raw_fd_ostream dest(filename, EC, sys::fs::F_None); if (EC) { *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin()); return true; } TargetMachine* target_machine = reinterpret_cast(targ_machine_ref); target_machine->setO0WantsFastISel(true); Module* module = unwrap(module_ref); PassManagerBuilder *PMBuilder = new(std::nothrow) PassManagerBuilder(); if (PMBuilder == nullptr) { *error_message = strdup("memory allocation failure"); return true; } PMBuilder->OptLevel = target_machine->getOptLevel(); PMBuilder->SizeLevel = is_small ? 2 : 0; PMBuilder->DisableTailCalls = is_debug; PMBuilder->DisableUnitAtATime = is_debug; PMBuilder->DisableUnrollLoops = is_debug; PMBuilder->SLPVectorize = !is_debug; PMBuilder->LoopVectorize = !is_debug; PMBuilder->RerollLoops = !is_debug; // Leaving NewGVN as default (off) because when on it caused issue #673 //PMBuilder->NewGVN = !is_debug; 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; TargetLibraryInfoImpl tlii(Triple(module->getTargetTriple())); PMBuilder->LibraryInfo = &tlii; if (is_debug) { PMBuilder->Inliner = createAlwaysInlinerLegacyPass(false); } else { target_machine->adjustPassManager(*PMBuilder); PMBuilder->addExtension(PassManagerBuilder::EP_EarlyAsPossible, addDiscriminatorsPass); PMBuilder->Inliner = createFunctionInliningPass(PMBuilder->OptLevel, PMBuilder->SizeLevel, false); } addCoroutinePassesToExtensionPoints(*PMBuilder); // Set up the per-function pass manager. legacy::FunctionPassManager FPM = legacy::FunctionPassManager(module); auto tliwp = new(std::nothrow) TargetLibraryInfoWrapperPass(tlii); FPM.add(tliwp); FPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); if (assertions_on) { FPM.add(createVerifierPass()); } PMBuilder->populateFunctionPassManager(FPM); // Set up the per-module pass manager. legacy::PassManager MPM; MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis())); PMBuilder->populateModulePassManager(MPM); // Set output pass. TargetMachine::CodeGenFileType ft; 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, nullptr, ft)) { *error_message = strdup("TargetMachine can't emit a file of this type"); return true; } } // run per function optimization passes FPM.doInitialization(); for (Function &F : *module) if (!F.isDeclaration()) FPM.run(F); FPM.doFinalization(); MPM.run(*module); if (output_type == ZigLLVM_EmitLLVMIr) { if (LLVMPrintModuleToFile(module_ref, filename, error_message)) { return true; } } if (time_report) { TimerGroup::printAll(errs()); } return false; } ZIG_EXTERN_C LLVMTypeRef ZigLLVMTokenTypeInContext(LLVMContextRef context_ref) { return wrap(Type::getTokenTy(*unwrap(context_ref))); } LLVMValueRef ZigLLVMBuildCall(LLVMBuilderRef B, LLVMValueRef Fn, LLVMValueRef *Args, unsigned NumArgs, unsigned CC, ZigLLVM_FnInline fn_inline, const char *Name) { CallInst *call_inst = CallInst::Create(unwrap(Fn), makeArrayRef(unwrap(Args), NumArgs), Name); call_inst->setCallingConv(CC); 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; } return wrap(unwrap(B)->Insert(call_inst)); } LLVMValueRef ZigLLVMBuildMemCpy(LLVMBuilderRef B, LLVMValueRef Dst, unsigned DstAlign, LLVMValueRef Src, unsigned SrcAlign, LLVMValueRef Size, bool isVolatile) { CallInst *call_inst = unwrap(B)->CreateMemCpy(unwrap(Dst), DstAlign, unwrap(Src), SrcAlign, unwrap(Size), isVolatile); return wrap(call_inst); } LLVMValueRef ZigLLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr, LLVMValueRef Val, LLVMValueRef Size, unsigned Align, bool isVolatile) { CallInst *call_inst = unwrap(B)->CreateMemSet(unwrap(Ptr), unwrap(Val), unwrap(Size), Align, isVolatile); return wrap(call_inst); } void ZigLLVMFnSetSubprogram(LLVMValueRef fn, ZigLLVMDISubprogram *subprogram) { assert( isa(unwrap(fn)) ); Function *unwrapped_function = reinterpret_cast(unwrap(fn)); unwrapped_function->setSubprogram(reinterpret_cast(subprogram)); } ZigLLVMDIType *ZigLLVMCreateDebugPointerType(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *pointee_type, uint64_t size_in_bits, uint64_t align_in_bits, const char *name) { DIType *di_type = reinterpret_cast(dibuilder)->createPointerType( reinterpret_cast(pointee_type), size_in_bits, align_in_bits, Optional(), name); return reinterpret_cast(di_type); } ZigLLVMDIType *ZigLLVMCreateDebugBasicType(ZigLLVMDIBuilder *dibuilder, const char *name, uint64_t size_in_bits, unsigned encoding) { DIType *di_type = reinterpret_cast(dibuilder)->createBasicType( name, size_in_bits, encoding); return reinterpret_cast(di_type); } struct ZigLLVMDIType *ZigLLVMDIBuilderCreateVectorType(struct ZigLLVMDIBuilder *dibuilder, uint64_t SizeInBits, uint32_t AlignInBits, struct ZigLLVMDIType *Ty, uint32_t elem_count) { SmallVector subrange; subrange.push_back(reinterpret_cast(dibuilder)->getOrCreateSubrange(0, elem_count)); DIType *di_type = reinterpret_cast(dibuilder)->createVectorType( SizeInBits, AlignInBits, reinterpret_cast(Ty), reinterpret_cast(dibuilder)->getOrCreateArray(subrange)); return reinterpret_cast(di_type); } ZigLLVMDIType *ZigLLVMCreateDebugArrayType(ZigLLVMDIBuilder *dibuilder, uint64_t size_in_bits, uint64_t align_in_bits, ZigLLVMDIType *elem_type, int elem_count) { SmallVector subrange; subrange.push_back(reinterpret_cast(dibuilder)->getOrCreateSubrange(0, elem_count)); DIType *di_type = reinterpret_cast(dibuilder)->createArrayType( size_in_bits, align_in_bits, reinterpret_cast(elem_type), reinterpret_cast(dibuilder)->getOrCreateArray(subrange)); return reinterpret_cast(di_type); } ZigLLVMDIEnumerator *ZigLLVMCreateDebugEnumerator(ZigLLVMDIBuilder *dibuilder, const char *name, int64_t val) { DIEnumerator *di_enumerator = reinterpret_cast(dibuilder)->createEnumerator(name, val); return reinterpret_cast(di_enumerator); } 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) { SmallVector fields; for (int i = 0; i < enumerator_array_len; i += 1) { DIEnumerator *dienumerator = reinterpret_cast(enumerator_array[i]); fields.push_back(dienumerator); } DIType *di_type = reinterpret_cast(dibuilder)->createEnumerationType( reinterpret_cast(scope), name, reinterpret_cast(file), line_number, size_in_bits, align_in_bits, reinterpret_cast(dibuilder)->getOrCreateArray(fields), reinterpret_cast(underlying_type), unique_id); return reinterpret_cast(di_type); } 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) { assert(flags == 0); DIType *di_type = reinterpret_cast(dibuilder)->createMemberType( reinterpret_cast(scope), name, reinterpret_cast(file), line, size_in_bits, align_in_bits, offset_in_bits, DINode::FlagZero, reinterpret_cast(type)); return reinterpret_cast(di_type); } 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, unsigned run_time_lang, const char *unique_id) { SmallVector fields; for (int i = 0; i < types_array_len; i += 1) { DIType *ditype = reinterpret_cast(types_array[i]); fields.push_back(ditype); } assert(flags == 0); DIType *di_type = reinterpret_cast(dibuilder)->createUnionType( reinterpret_cast(scope), name, reinterpret_cast(file), line_number, size_in_bits, align_in_bits, DINode::FlagZero, reinterpret_cast(dibuilder)->getOrCreateArray(fields), run_time_lang, unique_id); return reinterpret_cast(di_type); } ZigLLVMDIType *ZigLLVMCreateDebugStructType(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 *derived_from, ZigLLVMDIType **types_array, int types_array_len, unsigned run_time_lang, ZigLLVMDIType *vtable_holder, const char *unique_id) { SmallVector fields; for (int i = 0; i < types_array_len; i += 1) { DIType *ditype = reinterpret_cast(types_array[i]); fields.push_back(ditype); } assert(flags == 0); DIType *di_type = reinterpret_cast(dibuilder)->createStructType( reinterpret_cast(scope), name, reinterpret_cast(file), line_number, size_in_bits, align_in_bits, DINode::FlagZero, reinterpret_cast(derived_from), reinterpret_cast(dibuilder)->getOrCreateArray(fields), run_time_lang, reinterpret_cast(vtable_holder), unique_id); return reinterpret_cast(di_type); } ZigLLVMDIType *ZigLLVMCreateReplaceableCompositeType(ZigLLVMDIBuilder *dibuilder, unsigned tag, const char *name, ZigLLVMDIScope *scope, ZigLLVMDIFile *file, unsigned line) { DIType *di_type = reinterpret_cast(dibuilder)->createReplaceableCompositeType( tag, name, reinterpret_cast(scope), reinterpret_cast(file), line); return reinterpret_cast(di_type); } ZigLLVMDIType *ZigLLVMCreateDebugForwardDeclType(ZigLLVMDIBuilder *dibuilder, unsigned tag, const char *name, ZigLLVMDIScope *scope, ZigLLVMDIFile *file, unsigned line) { DIType *di_type = reinterpret_cast(dibuilder)->createForwardDecl( tag, name, reinterpret_cast(scope), reinterpret_cast(file), line); return reinterpret_cast(di_type); } void ZigLLVMReplaceTemporary(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *type, ZigLLVMDIType *replacement) { reinterpret_cast(dibuilder)->replaceTemporary( TempDIType(reinterpret_cast(type)), reinterpret_cast(replacement)); } void ZigLLVMReplaceDebugArrays(ZigLLVMDIBuilder *dibuilder, ZigLLVMDIType *type, ZigLLVMDIType **types_array, int types_array_len) { SmallVector fields; for (int i = 0; i < types_array_len; i += 1) { DIType *ditype = reinterpret_cast(types_array[i]); fields.push_back(ditype); } DICompositeType *composite_type = (DICompositeType*)reinterpret_cast(type); reinterpret_cast(dibuilder)->replaceArrays( composite_type, reinterpret_cast(dibuilder)->getOrCreateArray(fields)); } ZigLLVMDIType *ZigLLVMCreateSubroutineType(ZigLLVMDIBuilder *dibuilder_wrapped, ZigLLVMDIType **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); } assert(flags == 0); DIBuilder *dibuilder = reinterpret_cast(dibuilder_wrapped); DISubroutineType *subroutine_type = dibuilder->createSubroutineType( dibuilder->getOrCreateTypeArray(types), DINode::FlagZero); DIType *ditype = subroutine_type; return reinterpret_cast(ditype); } unsigned ZigLLVMEncoding_DW_ATE_unsigned(void) { return dwarf::DW_ATE_unsigned; } unsigned ZigLLVMEncoding_DW_ATE_signed(void) { return dwarf::DW_ATE_signed; } unsigned ZigLLVMEncoding_DW_ATE_float(void) { return dwarf::DW_ATE_float; } unsigned ZigLLVMEncoding_DW_ATE_boolean(void) { return dwarf::DW_ATE_boolean; } unsigned ZigLLVMEncoding_DW_ATE_unsigned_char(void) { return dwarf::DW_ATE_unsigned_char; } unsigned ZigLLVMEncoding_DW_ATE_signed_char(void) { return dwarf::DW_ATE_signed_char; } unsigned ZigLLVMLang_DW_LANG_C99(void) { return dwarf::DW_LANG_C99; } unsigned ZigLLVMTag_DW_variable(void) { return dwarf::DW_TAG_variable; } unsigned ZigLLVMTag_DW_structure_type(void) { return dwarf::DW_TAG_structure_type; } unsigned ZigLLVMTag_DW_enumeration_type(void) { return dwarf::DW_TAG_enumeration_type; } unsigned ZigLLVMTag_DW_union_type(void) { return dwarf::DW_TAG_union_type; } ZigLLVMDIBuilder *ZigLLVMCreateDIBuilder(LLVMModuleRef module, bool allow_unresolved) { DIBuilder *di_builder = new(std::nothrow) DIBuilder(*unwrap(module), allow_unresolved); if (di_builder == nullptr) return nullptr; return reinterpret_cast(di_builder); } void ZigLLVMDisposeDIBuilder(ZigLLVMDIBuilder *dbuilder) { DIBuilder *di_builder = reinterpret_cast(dbuilder); delete di_builder; } void ZigLLVMSetCurrentDebugLocation(LLVMBuilderRef builder, int line, int column, ZigLLVMDIScope *scope) { unwrap(builder)->SetCurrentDebugLocation(DebugLoc::get( line, column, reinterpret_cast(scope))); } void ZigLLVMClearCurrentDebugLocation(LLVMBuilderRef builder) { unwrap(builder)->SetCurrentDebugLocation(DebugLoc()); } ZigLLVMDILexicalBlock *ZigLLVMCreateLexicalBlock(ZigLLVMDIBuilder *dbuilder, ZigLLVMDIScope *scope, ZigLLVMDIFile *file, unsigned line, unsigned col) { DILexicalBlock *result = reinterpret_cast(dbuilder)->createLexicalBlock( reinterpret_cast(scope), reinterpret_cast(file), line, col); return reinterpret_cast(result); } ZigLLVMDILocalVariable *ZigLLVMCreateAutoVariable(ZigLLVMDIBuilder *dbuilder, ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no, ZigLLVMDIType *type, bool always_preserve, unsigned flags) { assert(flags == 0); DILocalVariable *result = reinterpret_cast(dbuilder)->createAutoVariable( reinterpret_cast(scope), name, reinterpret_cast(file), line_no, reinterpret_cast(type), always_preserve, DINode::FlagZero); return reinterpret_cast(result); } ZigLLVMDIGlobalVariable *ZigLLVMCreateGlobalVariable(ZigLLVMDIBuilder *dbuilder, ZigLLVMDIScope *scope, const char *name, const char *linkage_name, ZigLLVMDIFile *file, unsigned line_no, ZigLLVMDIType *di_type, bool is_local_to_unit) { DIGlobalVariableExpression *result = reinterpret_cast(dbuilder)->createGlobalVariableExpression( reinterpret_cast(scope), name, linkage_name, reinterpret_cast(file), line_no, reinterpret_cast(di_type), is_local_to_unit); return reinterpret_cast(result); } ZigLLVMDILocalVariable *ZigLLVMCreateParameterVariable(ZigLLVMDIBuilder *dbuilder, ZigLLVMDIScope *scope, const char *name, ZigLLVMDIFile *file, unsigned line_no, ZigLLVMDIType *type, bool always_preserve, unsigned flags, unsigned arg_no) { assert(flags == 0); assert(arg_no != 0); DILocalVariable *result = reinterpret_cast(dbuilder)->createParameterVariable( reinterpret_cast(scope), name, arg_no, reinterpret_cast(file), line_no, reinterpret_cast(type), always_preserve, DINode::FlagZero); return reinterpret_cast(result); } ZigLLVMDIScope *ZigLLVMLexicalBlockToScope(ZigLLVMDILexicalBlock *lexical_block) { DIScope *scope = reinterpret_cast(lexical_block); return reinterpret_cast(scope); } ZigLLVMDIScope *ZigLLVMCompileUnitToScope(ZigLLVMDICompileUnit *compile_unit) { DIScope *scope = reinterpret_cast(compile_unit); return reinterpret_cast(scope); } ZigLLVMDIScope *ZigLLVMFileToScope(ZigLLVMDIFile *difile) { DIScope *scope = reinterpret_cast(difile); return reinterpret_cast(scope); } ZigLLVMDIScope *ZigLLVMSubprogramToScope(ZigLLVMDISubprogram *subprogram) { DIScope *scope = reinterpret_cast(subprogram); return reinterpret_cast(scope); } ZigLLVMDIScope *ZigLLVMTypeToScope(ZigLLVMDIType *type) { DIScope *scope = reinterpret_cast(type); return reinterpret_cast(scope); } ZigLLVMDICompileUnit *ZigLLVMCreateCompileUnit(ZigLLVMDIBuilder *dibuilder, unsigned lang, ZigLLVMDIFile *difile, 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)->createCompileUnit( lang, reinterpret_cast(difile), producer, is_optimized, flags, runtime_version, split_name, (emit_debug_info ? DICompileUnit::DebugEmissionKind::FullDebug : DICompileUnit::DebugEmissionKind::NoDebug), dwo_id); return reinterpret_cast(result); } ZigLLVMDIFile *ZigLLVMCreateFile(ZigLLVMDIBuilder *dibuilder, const char *filename, const char *directory) { DIFile *result = reinterpret_cast(dibuilder)->createFile(filename, directory); return reinterpret_cast(result); } 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) { DISubroutineType *di_sub_type = static_cast(reinterpret_cast(fn_di_type)); assert(flags == 0); DISubprogram *result = reinterpret_cast(dibuilder)->createFunction( reinterpret_cast(scope), name, linkage_name, reinterpret_cast(file), lineno, di_sub_type, scope_line, DINode::FlagStaticMember, DISubprogram::toSPFlags(is_local_to_unit, is_definition, is_optimized), nullptr, reinterpret_cast(decl_subprogram), nullptr); return reinterpret_cast(result); } void ZigLLVMDIBuilderFinalize(ZigLLVMDIBuilder *dibuilder) { reinterpret_cast(dibuilder)->finalize(); } LLVMValueRef ZigLLVMInsertDeclareAtEnd(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage, ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc, LLVMBasicBlockRef basic_block_ref) { Instruction *result = reinterpret_cast(dibuilder)->insertDeclare( unwrap(storage), reinterpret_cast(var_info), reinterpret_cast(dibuilder)->createExpression(), reinterpret_cast(debug_loc), static_cast(unwrap(basic_block_ref))); return wrap(result); } LLVMValueRef ZigLLVMInsertDeclare(ZigLLVMDIBuilder *dibuilder, LLVMValueRef storage, ZigLLVMDILocalVariable *var_info, ZigLLVMDILocation *debug_loc, LLVMValueRef insert_before_instr) { Instruction *result = reinterpret_cast(dibuilder)->insertDeclare( unwrap(storage), reinterpret_cast(var_info), reinterpret_cast(dibuilder)->createExpression(), reinterpret_cast(debug_loc), static_cast(unwrap(insert_before_instr))); return wrap(result); } ZigLLVMDILocation *ZigLLVMGetDebugLoc(unsigned line, unsigned col, ZigLLVMDIScope *scope) { DebugLoc debug_loc = DebugLoc::get(line, col, reinterpret_cast(scope), nullptr); return reinterpret_cast(debug_loc.get()); } void ZigLLVMSetFastMath(LLVMBuilderRef builder_wrapped, bool on_state) { if (on_state) { FastMathFlags fmf; fmf.setFast(); unwrap(builder_wrapped)->setFastMathFlags(fmf); } else { unwrap(builder_wrapped)->clearFastMathFlags(); } } void ZigLLVMAddFunctionAttr(LLVMValueRef fn_ref, const char *attr_name, const char *attr_value) { Function *func = unwrap(fn_ref); const AttributeList attr_set = func->getAttributes(); AttrBuilder attr_builder; if (attr_value) { attr_builder.addAttribute(attr_name, attr_value); } else { attr_builder.addAttribute(attr_name); } const AttributeList new_attr_set = attr_set.addAttributes(func->getContext(), AttributeList::FunctionIndex, attr_builder); func->setAttributes(new_attr_set); } void ZigLLVMAddFunctionAttrCold(LLVMValueRef fn_ref) { Function *func = unwrap(fn_ref); const AttributeList attr_set = func->getAttributes(); const AttributeList new_attr_set = attr_set.addAttribute(func->getContext(), AttributeList::FunctionIndex, Attribute::Cold); func->setAttributes(new_attr_set); } void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) { llvm::cl::ParseCommandLineOptions(argc, argv); } const char *ZigLLVMGetArchTypeName(ZigLLVM_ArchType arch) { return (const char*)Triple::getArchTypeName((Triple::ArchType)arch).bytes_begin(); } const char *ZigLLVMGetVendorTypeName(ZigLLVM_VendorType vendor) { return (const char*)Triple::getVendorTypeName((Triple::VendorType)vendor).bytes_begin(); } const char *ZigLLVMGetOSTypeName(ZigLLVM_OSType os) { return (const char*)Triple::getOSTypeName((Triple::OSType)os).bytes_begin(); } const char *ZigLLVMGetEnvironmentTypeName(ZigLLVM_EnvironmentType env_type) { return (const char*)Triple::getEnvironmentTypeName((Triple::EnvironmentType)env_type).bytes_begin(); } void ZigLLVMGetNativeTarget(ZigLLVM_ArchType *arch_type, ZigLLVM_SubArchType *sub_arch_type, ZigLLVM_VendorType *vendor_type, ZigLLVM_OSType *os_type, ZigLLVM_EnvironmentType *environ_type, ZigLLVM_ObjectFormatType *oformat) { char *native_triple = LLVMGetDefaultTargetTriple(); Triple triple(Triple::normalize(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(); *oformat = (ZigLLVM_ObjectFormatType)triple.getObjectFormat(); free(native_triple); } const char *ZigLLVMGetSubArchTypeName(ZigLLVM_SubArchType sub_arch) { switch (sub_arch) { case ZigLLVM_NoSubArch: return ""; case ZigLLVM_ARMSubArch_v8_5a: return "v8_5a"; case ZigLLVM_ARMSubArch_v8_4a: return "v8_4a"; case ZigLLVM_ARMSubArch_v8_3a: return "v8_3a"; case ZigLLVM_ARMSubArch_v8_2a: return "v8_2a"; case ZigLLVM_ARMSubArch_v8_1a: return "v8_1a"; case ZigLLVM_ARMSubArch_v8: return "v8"; case ZigLLVM_ARMSubArch_v8r: return "v8r"; case ZigLLVM_ARMSubArch_v8m_baseline: return "v8m_baseline"; case ZigLLVM_ARMSubArch_v8m_mainline: return "v8m_mainline"; case ZigLLVM_ARMSubArch_v7: return "v7"; case ZigLLVM_ARMSubArch_v7em: return "v7em"; case ZigLLVM_ARMSubArch_v7m: return "v7m"; case ZigLLVM_ARMSubArch_v7s: return "v7s"; case ZigLLVM_ARMSubArch_v7k: return "v7k"; case ZigLLVM_ARMSubArch_v7ve: return "v7ve"; 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"; case ZigLLVM_MipsSubArch_r6: return "r6"; } abort(); } void ZigLLVMAddModuleDebugInfoFlag(LLVMModuleRef module) { unwrap(module)->addModuleFlag(Module::Warning, "Debug Info Version", DEBUG_METADATA_VERSION); } void ZigLLVMAddModuleCodeViewFlag(LLVMModuleRef module) { unwrap(module)->addModuleFlag(Module::Warning, "CodeView", 1); } static AtomicOrdering mapFromLLVMOrdering(LLVMAtomicOrdering Ordering) { switch (Ordering) { 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; } abort(); } LLVMValueRef ZigLLVMBuildCmpXchg(LLVMBuilderRef builder, LLVMValueRef ptr, LLVMValueRef cmp, LLVMValueRef new_val, LLVMAtomicOrdering success_ordering, LLVMAtomicOrdering failure_ordering, bool is_weak) { 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); } 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) { 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)); } LLVMValueRef ZigLLVMBuildAShrExact(LLVMBuilderRef builder, LLVMValueRef LHS, LLVMValueRef RHS, const char *name) { return wrap(unwrap(builder)->CreateAShr(unwrap(LHS), unwrap(RHS), name, true)); } 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; }; bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count, ZigLLVM_OSType os_type) { object::Archive::Kind kind; switch (os_type) { case ZigLLVM_Win32: // For some reason llvm-lib passes K_GNU on windows. // See lib/ToolDrivers/llvm-lib/LibDriver.cpp:168 in libDriverMain kind = object::Archive::K_GNU; break; case ZigLLVM_Linux: kind = object::Archive::K_GNU; break; case ZigLLVM_Darwin: case ZigLLVM_IOS: kind = object::Archive::K_DARWIN; break; case ZigLLVM_OpenBSD: case ZigLLVM_FreeBSD: kind = object::Archive::K_BSD; break; default: kind = object::Archive::K_GNU; } SmallVector new_members; for (size_t i = 0; i < file_name_count; i += 1) { Expected new_member = NewArchiveMember::getFile(file_names[i], true); Error err = new_member.takeError(); if (err) return true; new_members.push_back(std::move(*new_member)); } Error err = writeArchive(archive_name, new_members, true, kind, true, false, nullptr); if (err) return true; return false; } bool ZigLLDLink(ZigLLVM_ObjectFormatType oformat, const char **args, size_t arg_count, void (*append_diagnostic)(void *, const char *, size_t), void *context) { ArrayRef array_ref_args(args, arg_count); MyOStream diag(append_diagnostic, context); switch (oformat) { case ZigLLVM_UnknownObjectFormat: assert(false); // unreachable case ZigLLVM_COFF: return lld::coff::link(array_ref_args, false, diag); case ZigLLVM_ELF: return lld::elf::link(array_ref_args, false, diag); case ZigLLVM_MachO: return lld::mach_o::link(array_ref_args, false, diag); case ZigLLVM_Wasm: return lld::wasm::link(array_ref_args, false, diag); } assert(false); // unreachable abort(); } static_assert((Triple::ArchType)ZigLLVM_UnknownArch == Triple::UnknownArch, ""); static_assert((Triple::ArchType)ZigLLVM_arm == Triple::arm, ""); static_assert((Triple::ArchType)ZigLLVM_armeb == Triple::armeb, ""); static_assert((Triple::ArchType)ZigLLVM_aarch64 == Triple::aarch64, ""); static_assert((Triple::ArchType)ZigLLVM_aarch64_be == Triple::aarch64_be, ""); static_assert((Triple::ArchType)ZigLLVM_arc == Triple::arc, ""); static_assert((Triple::ArchType)ZigLLVM_avr == Triple::avr, ""); static_assert((Triple::ArchType)ZigLLVM_bpfel == Triple::bpfel, ""); static_assert((Triple::ArchType)ZigLLVM_bpfeb == Triple::bpfeb, ""); static_assert((Triple::ArchType)ZigLLVM_hexagon == Triple::hexagon, ""); static_assert((Triple::ArchType)ZigLLVM_mips == Triple::mips, ""); static_assert((Triple::ArchType)ZigLLVM_mipsel == Triple::mipsel, ""); static_assert((Triple::ArchType)ZigLLVM_mips64 == Triple::mips64, ""); static_assert((Triple::ArchType)ZigLLVM_mips64el == Triple::mips64el, ""); static_assert((Triple::ArchType)ZigLLVM_msp430 == Triple::msp430, ""); static_assert((Triple::ArchType)ZigLLVM_ppc == Triple::ppc, ""); static_assert((Triple::ArchType)ZigLLVM_ppc64 == Triple::ppc64, ""); static_assert((Triple::ArchType)ZigLLVM_ppc64le == Triple::ppc64le, ""); static_assert((Triple::ArchType)ZigLLVM_r600 == Triple::r600, ""); static_assert((Triple::ArchType)ZigLLVM_amdgcn == Triple::amdgcn, ""); static_assert((Triple::ArchType)ZigLLVM_riscv32 == Triple::riscv32, ""); static_assert((Triple::ArchType)ZigLLVM_riscv64 == Triple::riscv64, ""); static_assert((Triple::ArchType)ZigLLVM_sparc == Triple::sparc, ""); static_assert((Triple::ArchType)ZigLLVM_sparcv9 == Triple::sparcv9, ""); static_assert((Triple::ArchType)ZigLLVM_sparcel == Triple::sparcel, ""); static_assert((Triple::ArchType)ZigLLVM_systemz == Triple::systemz, ""); static_assert((Triple::ArchType)ZigLLVM_tce == Triple::tce, ""); static_assert((Triple::ArchType)ZigLLVM_tcele == Triple::tcele, ""); static_assert((Triple::ArchType)ZigLLVM_thumb == Triple::thumb, ""); static_assert((Triple::ArchType)ZigLLVM_thumbeb == Triple::thumbeb, ""); static_assert((Triple::ArchType)ZigLLVM_x86 == Triple::x86, ""); static_assert((Triple::ArchType)ZigLLVM_x86_64 == Triple::x86_64, ""); static_assert((Triple::ArchType)ZigLLVM_xcore == Triple::xcore, ""); static_assert((Triple::ArchType)ZigLLVM_nvptx == Triple::nvptx, ""); static_assert((Triple::ArchType)ZigLLVM_nvptx64 == Triple::nvptx64, ""); static_assert((Triple::ArchType)ZigLLVM_le32 == Triple::le32, ""); static_assert((Triple::ArchType)ZigLLVM_le64 == Triple::le64, ""); static_assert((Triple::ArchType)ZigLLVM_amdil == Triple::amdil, ""); static_assert((Triple::ArchType)ZigLLVM_amdil64 == Triple::amdil64, ""); static_assert((Triple::ArchType)ZigLLVM_hsail == Triple::hsail, ""); static_assert((Triple::ArchType)ZigLLVM_hsail64 == Triple::hsail64, ""); static_assert((Triple::ArchType)ZigLLVM_spir == Triple::spir, ""); static_assert((Triple::ArchType)ZigLLVM_spir64 == Triple::spir64, ""); static_assert((Triple::ArchType)ZigLLVM_kalimba == Triple::kalimba, ""); static_assert((Triple::ArchType)ZigLLVM_shave == Triple::shave, ""); static_assert((Triple::ArchType)ZigLLVM_lanai == Triple::lanai, ""); static_assert((Triple::ArchType)ZigLLVM_wasm32 == Triple::wasm32, ""); static_assert((Triple::ArchType)ZigLLVM_wasm64 == Triple::wasm64, ""); static_assert((Triple::ArchType)ZigLLVM_renderscript32 == Triple::renderscript32, ""); static_assert((Triple::ArchType)ZigLLVM_renderscript64 == Triple::renderscript64, ""); static_assert((Triple::ArchType)ZigLLVM_LastArchType == Triple::LastArchType, ""); static_assert((Triple::SubArchType)ZigLLVM_NoSubArch == Triple::NoSubArch, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_4a == Triple::ARMSubArch_v8_4a, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_3a == Triple::ARMSubArch_v8_3a, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_2a == Triple::ARMSubArch_v8_2a, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8_1a == Triple::ARMSubArch_v8_1a, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8 == Triple::ARMSubArch_v8, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8r == Triple::ARMSubArch_v8r, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8m_baseline == Triple::ARMSubArch_v8m_baseline, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v8m_mainline == Triple::ARMSubArch_v8m_mainline, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7 == Triple::ARMSubArch_v7, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7em == Triple::ARMSubArch_v7em, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7m == Triple::ARMSubArch_v7m, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7s == Triple::ARMSubArch_v7s, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7k == Triple::ARMSubArch_v7k, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v7ve == Triple::ARMSubArch_v7ve, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6 == Triple::ARMSubArch_v6, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6m == Triple::ARMSubArch_v6m, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6k == Triple::ARMSubArch_v6k, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v6t2 == Triple::ARMSubArch_v6t2, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v5 == Triple::ARMSubArch_v5, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v5te == Triple::ARMSubArch_v5te, ""); static_assert((Triple::SubArchType)ZigLLVM_ARMSubArch_v4t == Triple::ARMSubArch_v4t, ""); static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v3 == Triple::KalimbaSubArch_v3, ""); static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v4 == Triple::KalimbaSubArch_v4, ""); static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v5 == Triple::KalimbaSubArch_v5, ""); static_assert((Triple::SubArchType)ZigLLVM_KalimbaSubArch_v5 == Triple::KalimbaSubArch_v5, ""); static_assert((Triple::SubArchType)ZigLLVM_MipsSubArch_r6 == Triple::MipsSubArch_r6, ""); static_assert((Triple::VendorType)ZigLLVM_UnknownVendor == Triple::UnknownVendor, ""); static_assert((Triple::VendorType)ZigLLVM_Apple == Triple::Apple, ""); static_assert((Triple::VendorType)ZigLLVM_PC == Triple::PC, ""); static_assert((Triple::VendorType)ZigLLVM_SCEI == Triple::SCEI, ""); static_assert((Triple::VendorType)ZigLLVM_BGP == Triple::BGP, ""); static_assert((Triple::VendorType)ZigLLVM_BGQ == Triple::BGQ, ""); static_assert((Triple::VendorType)ZigLLVM_Freescale == Triple::Freescale, ""); static_assert((Triple::VendorType)ZigLLVM_IBM == Triple::IBM, ""); static_assert((Triple::VendorType)ZigLLVM_ImaginationTechnologies == Triple::ImaginationTechnologies, ""); static_assert((Triple::VendorType)ZigLLVM_MipsTechnologies == Triple::MipsTechnologies, ""); static_assert((Triple::VendorType)ZigLLVM_NVIDIA == Triple::NVIDIA, ""); static_assert((Triple::VendorType)ZigLLVM_CSR == Triple::CSR, ""); static_assert((Triple::VendorType)ZigLLVM_Myriad == Triple::Myriad, ""); static_assert((Triple::VendorType)ZigLLVM_AMD == Triple::AMD, ""); static_assert((Triple::VendorType)ZigLLVM_Mesa == Triple::Mesa, ""); static_assert((Triple::VendorType)ZigLLVM_SUSE == Triple::SUSE, ""); static_assert((Triple::VendorType)ZigLLVM_OpenEmbedded == Triple::OpenEmbedded, ""); static_assert((Triple::VendorType)ZigLLVM_LastVendorType == Triple::LastVendorType, ""); static_assert((Triple::OSType)ZigLLVM_UnknownOS == Triple::UnknownOS, ""); static_assert((Triple::OSType)ZigLLVM_Ananas == Triple::Ananas, ""); static_assert((Triple::OSType)ZigLLVM_CloudABI == Triple::CloudABI, ""); static_assert((Triple::OSType)ZigLLVM_Darwin == Triple::Darwin, ""); static_assert((Triple::OSType)ZigLLVM_DragonFly == Triple::DragonFly, ""); static_assert((Triple::OSType)ZigLLVM_FreeBSD == Triple::FreeBSD, ""); static_assert((Triple::OSType)ZigLLVM_Fuchsia == Triple::Fuchsia, ""); static_assert((Triple::OSType)ZigLLVM_IOS == Triple::IOS, ""); // Commented out to work around a Debian/Ubuntu bug. // See https://github.com/ziglang/zig/issues/2076 //static_assert((Triple::OSType)ZigLLVM_KFreeBSD == Triple::KFreeBSD, ""); static_assert((Triple::OSType)ZigLLVM_Linux == Triple::Linux, ""); static_assert((Triple::OSType)ZigLLVM_Lv2 == Triple::Lv2, ""); static_assert((Triple::OSType)ZigLLVM_MacOSX == Triple::MacOSX, ""); static_assert((Triple::OSType)ZigLLVM_NetBSD == Triple::NetBSD, ""); static_assert((Triple::OSType)ZigLLVM_OpenBSD == Triple::OpenBSD, ""); static_assert((Triple::OSType)ZigLLVM_Solaris == Triple::Solaris, ""); static_assert((Triple::OSType)ZigLLVM_Win32 == Triple::Win32, ""); static_assert((Triple::OSType)ZigLLVM_Haiku == Triple::Haiku, ""); static_assert((Triple::OSType)ZigLLVM_Minix == Triple::Minix, ""); static_assert((Triple::OSType)ZigLLVM_RTEMS == Triple::RTEMS, ""); static_assert((Triple::OSType)ZigLLVM_NaCl == Triple::NaCl, ""); static_assert((Triple::OSType)ZigLLVM_CNK == Triple::CNK, ""); static_assert((Triple::OSType)ZigLLVM_AIX == Triple::AIX, ""); static_assert((Triple::OSType)ZigLLVM_CUDA == Triple::CUDA, ""); static_assert((Triple::OSType)ZigLLVM_NVCL == Triple::NVCL, ""); static_assert((Triple::OSType)ZigLLVM_AMDHSA == Triple::AMDHSA, ""); static_assert((Triple::OSType)ZigLLVM_PS4 == Triple::PS4, ""); static_assert((Triple::OSType)ZigLLVM_ELFIAMCU == Triple::ELFIAMCU, ""); static_assert((Triple::OSType)ZigLLVM_TvOS == Triple::TvOS, ""); static_assert((Triple::OSType)ZigLLVM_WatchOS == Triple::WatchOS, ""); static_assert((Triple::OSType)ZigLLVM_Mesa3D == Triple::Mesa3D, ""); static_assert((Triple::OSType)ZigLLVM_Contiki == Triple::Contiki, ""); static_assert((Triple::OSType)ZigLLVM_AMDPAL == Triple::AMDPAL, ""); static_assert((Triple::OSType)ZigLLVM_LastOSType == Triple::LastOSType, ""); static_assert((Triple::EnvironmentType)ZigLLVM_UnknownEnvironment == Triple::UnknownEnvironment, ""); static_assert((Triple::EnvironmentType)ZigLLVM_GNU == Triple::GNU, ""); static_assert((Triple::EnvironmentType)ZigLLVM_GNUABIN32 == Triple::GNUABIN32, ""); static_assert((Triple::EnvironmentType)ZigLLVM_GNUABI64 == Triple::GNUABI64, ""); static_assert((Triple::EnvironmentType)ZigLLVM_GNUEABI == Triple::GNUEABI, ""); static_assert((Triple::EnvironmentType)ZigLLVM_GNUEABIHF == Triple::GNUEABIHF, ""); static_assert((Triple::EnvironmentType)ZigLLVM_GNUX32 == Triple::GNUX32, ""); static_assert((Triple::EnvironmentType)ZigLLVM_CODE16 == Triple::CODE16, ""); static_assert((Triple::EnvironmentType)ZigLLVM_EABI == Triple::EABI, ""); static_assert((Triple::EnvironmentType)ZigLLVM_EABIHF == Triple::EABIHF, ""); static_assert((Triple::EnvironmentType)ZigLLVM_Android == Triple::Android, ""); static_assert((Triple::EnvironmentType)ZigLLVM_Musl == Triple::Musl, ""); static_assert((Triple::EnvironmentType)ZigLLVM_MuslEABI == Triple::MuslEABI, ""); static_assert((Triple::EnvironmentType)ZigLLVM_MuslEABIHF == Triple::MuslEABIHF, ""); static_assert((Triple::EnvironmentType)ZigLLVM_MSVC == Triple::MSVC, ""); static_assert((Triple::EnvironmentType)ZigLLVM_Itanium == Triple::Itanium, ""); static_assert((Triple::EnvironmentType)ZigLLVM_Cygnus == Triple::Cygnus, ""); static_assert((Triple::EnvironmentType)ZigLLVM_CoreCLR == Triple::CoreCLR, ""); static_assert((Triple::EnvironmentType)ZigLLVM_Simulator == Triple::Simulator, ""); static_assert((Triple::EnvironmentType)ZigLLVM_LastEnvironmentType == Triple::LastEnvironmentType, ""); 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, ""); static_assert((Triple::ObjectFormatType)ZigLLVM_Wasm == Triple::Wasm, "");