╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ zig_llvm.cpp ─────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
414 if (LLVMPrintModuleToFile(module_ref, options->llvm_ir_filename, error_message)) { 415 return true; 416 } 417 } 418 419 if (dest_bin && options->lto) { 420 WriteBitcodeToFile(llvm_module, *dest_bin); 421 } 422 if (dest_bitcode) { 423 WriteBitcodeToFile(llvm_module, *dest_bitcode); 424 } 425 426 // This must only happen once we know we've succeeded and will be returning `false`, because 427 // this code `malloc`s memory which will become owned by the caller (in Zig code). 428 if (options->time_report_out != nullptr) { 429 std::string out_str; 430 auto os = raw_string_ostream(out_str); 431 TimerGroup::printAll(os); 432 TimerGroup::clearAll(); 433 auto c_str = (char *)malloc(out_str.length() + 1); 434 strcpy(c_str, out_str.c_str()); 435 *options->time_report_out = c_str; 436 } 437 return false; 438 } 439 440 void ZigLLVMSetOptBisectLimit(LLVMContextRef context_ref, int limit) { 441 static OptBisect opt_bisect; 442 opt_bisect.setIntervals({0, limit}); 443 unwrap(context_ref)->setOptPassGate(opt_bisect); 444 } 445 446 struct ZigDiagnosticHandler : public DiagnosticHandler { 447 bool BrokenDebugInfo; 448 ZigDiagnosticHandler() : BrokenDebugInfo(false) {} 449 bool handleDiagnostics(const DiagnosticInfo &DI) override { 450 // This dyn_cast should be casting to DiagnosticInfoIgnoringInvalidDebugMetadata 451 // but DiagnosticInfoIgnoringInvalidDebugMetadata is treated as DiagnosticInfoDebugMetadataVersion 452 // because of a bug in LLVM (see https://github.com/ziglang/zig/issues/19161). 453 // After this is fixed add an additional check for DiagnosticInfoIgnoringInvalidDebugMetadata 454 // but don't remove the current one as both indicate that debug info is broken. 455 if (auto *Remark = dyn_cast<DiagnosticInfoDebugMetadataVersion>(&DI)) { 456 BrokenDebugInfo = true; 457 } 458 return false; 459 } 460 }; 461 462 void ZigLLVMEnableBrokenDebugInfoCheck(LLVMContextRef context_ref) { 463 unwrap(context_ref)->setDiagnosticHandler(std::make_unique<ZigDiagnosticHandler>()); 464 } 465 466 bool ZigLLVMGetBrokenDebugInfo(LLVMContextRef context_ref) { 467 return ((const ZigDiagnosticHandler*) 468 unwrap(context_ref)->getDiagHandlerPtr())->BrokenDebugInfo; 469 } 470 471 void ZigLLVMParseCommandLineOptions(size_t argc, const char *const *argv) { 472 cl::ParseCommandLineOptions(argc, argv); 473 } 474 475 bool ZigLLVMWriteArchive(const char *archive_name, const char **file_names, size_t file_name_count, 476 ZigLLVMArchiveKind archive_kind, size_t *err_file_index_out, char **err_msg_out) 477 { 478 SmallVector<NewArchiveMember, 4> new_members; 479 for (size_t i = 0; i < file_name_count; i += 1) { 480 Expected<NewArchiveMember> new_member = NewArchiveMember::getFile(file_names[i], true); 481 Error err = new_member.takeError(); 482 if (err) { 483 *err_file_index_out = i; 484 const std::string msg = toString(std::move(err)); 485 *err_msg_out = (char *)malloc(msg.length() + 1); 486 strcpy(*err_msg_out, msg.c_str()); 487 return true; 488 } 489 new_members.push_back(std::move(*new_member)); 490 } 491 Error err = writeArchive(archive_name, new_members, 492 SymtabWritingMode::NormalSymtab, static_cast<object::Archive::Kind>(archive_kind), true, false, nullptr); 493 494 if (err) { 495 *err_file_index_out = file_name_count; 496 const std::string msg = toString(std::move(err)); 497 *err_msg_out = (char *)malloc(msg.length() + 1); 498 strcpy(*err_msg_out, msg.c_str()); 499 return true; 500 } 501 502 return false; 503 } 504 505 // The header file in LLD 16 exposed these functions. As of 17 they are only 506 // exposed via a macro ("LLD_HAS_DRIVER") which I have copied and pasted the 507 // body of here so that you don't have to wonder what it is doing. 508 namespace lld { 509 namespace coff { 510 bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, 511 llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput); 512 } 513 namespace elf { 514 bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, 515 llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput); 516 } 517 namespace wasm { 518 bool link(llvm::ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS, 519 llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput); 520 } 521 } 522 523 bool ZigLLDLinkCOFF(int argc, const char **argv, bool can_exit_early, bool disable_output) { 524 std::vector<const char *> args(argv, argv + argc); 525 return lld::coff::link(args, llvm::outs(), llvm::errs(), can_exit_early, disable_output); 526 } 527 528 bool ZigLLDLinkELF(int argc, const char **argv, bool can_exit_early, bool disable_output) { 529 std::vector<const char *> args(argv, argv + argc); 530 return lld::elf::link(args, llvm::outs(), llvm::errs(), can_exit_early, disable_output); 531 } 532 533 bool ZigLLDLinkWasm(int argc, const char **argv, bool can_exit_early, bool disable_output) { 534 std::vector<const char *> args(argv, argv + argc); 535 return lld::wasm::link(args, llvm::outs(), llvm::errs(), can_exit_early, disable_output); 536 } 537 538 static_assert((FloatABI::ABIType)ZigLLVMFloatABI_Default == FloatABI::ABIType::Default, ""); 539 static_assert((FloatABI::ABIType)ZigLLVMFloatABI_Soft == FloatABI::ABIType::Soft, ""); 540 static_assert((FloatABI::ABIType)ZigLLVMFloatABI_Hard == FloatABI::ABIType::Hard, ""); 541 542 static_assert((object::Archive::Kind)ZigLLVMArchiveKind_GNU == object::Archive::Kind::K_GNU, ""); 543 static_assert((object::Archive::Kind)ZigLLVMArchiveKind_GNU64 == object::Archive::Kind::K_GNU64, ""); 544 static_assert((object::Archive::Kind)ZigLLVMArchiveKind_BSD == object::Archive::Kind::K_BSD, ""); 545 static_assert((object::Archive::Kind)ZigLLVMArchiveKind_DARWIN == object::Archive::Kind::K_DARWIN, ""); 546 static_assert((object::Archive::Kind)ZigLLVMArchiveKind_DARWIN64 == object::Archive::Kind::K_DARWIN64, ""); 547 static_assert((object::Archive::Kind)ZigLLVMArchiveKind_COFF == object::Archive::Kind::K_COFF, ""); 548 static_assert((object::Archive::Kind)ZigLLVMArchiveKind_AIXBIG == object::Archive::Kind::K_AIXBIG, ""); 549