Index: source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp =================================================================== --- source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp +++ source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp @@ -881,6 +881,16 @@ bool m_using_file_addr; }; +namespace { + // This should become a generic lambda when using of c++14 will be allowed. + template + bool InitializePtr(std::unique_ptr& member, bool& is_valid, + const Fn& fn, Args&... args) { + member.reset(fn(args...)); + return (is_valid = member.operator bool()); + } +} // namespace + DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler( const char *triple, const char *cpu, const char *features_str, unsigned flavor, DisassemblerLLVMC &owner) @@ -888,61 +898,76 @@ std::string Status; const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple, Status); - if (!curr_target) { + if (nullptr == curr_target) { m_is_valid = false; return; } - m_instr_info_ap.reset(curr_target->createMCInstrInfo()); - m_reg_info_ap.reset(curr_target->createMCRegInfo(triple)); + if (!InitializePtr(m_instr_info_ap, m_is_valid, + [curr_target]() { return curr_target->createMCInstrInfo(); })) + return; - m_subtarget_info_ap.reset( - curr_target->createMCSubtargetInfo(triple, cpu, features_str)); + if (!InitializePtr(m_reg_info_ap, m_is_valid, + [curr_target, triple]() { return curr_target->createMCRegInfo(triple); })) + return; - std::unique_ptr reg_info( - curr_target->createMCRegInfo(triple)); - m_asm_info_ap.reset(curr_target->createMCAsmInfo(*reg_info, triple)); + if (!InitializePtr(m_subtarget_info_ap, m_is_valid, + [curr_target, triple, cpu, features_str]() { + return curr_target->createMCSubtargetInfo(triple, cpu, features_str); + })) + return; - if (m_instr_info_ap.get() == NULL || m_reg_info_ap.get() == NULL || - m_subtarget_info_ap.get() == NULL || m_asm_info_ap.get() == NULL) { - m_is_valid = false; + if (!InitializePtr(m_asm_info_ap, m_is_valid, + [curr_target, triple](const llvm::MCRegisterInfo& reg_info) { + return curr_target->createMCAsmInfo(reg_info, triple); + }, *m_reg_info_ap)) return; - } - m_context_ap.reset( - new llvm::MCContext(m_asm_info_ap.get(), m_reg_info_ap.get(), 0)); + if (!InitializePtr(m_context_ap, m_is_valid, + [](const llvm::MCAsmInfo& asm_info, + const llvm::MCRegisterInfo& reg_info) { + // llvm::MCContext doesn't expect first two arguments to be nullptrs. + return new llvm::MCContext(&asm_info, ®_info, nullptr); + }, *m_asm_info_ap, *m_reg_info_ap)) + return; - m_disasm_ap.reset(curr_target->createMCDisassembler( - *m_subtarget_info_ap.get(), *m_context_ap.get())); - if (m_disasm_ap.get() && m_context_ap.get()) { - std::unique_ptr RelInfo( - curr_target->createMCRelocationInfo(triple, *m_context_ap.get())); - if (!RelInfo) { - m_is_valid = false; - return; - } - std::unique_ptr symbolizer_up( - curr_target->createMCSymbolizer( + if (!InitializePtr(m_disasm_ap, m_is_valid, + [curr_target](const llvm::MCSubtargetInfo& subtarget_info, + llvm::MCContext& context) { + return curr_target->createMCDisassembler(subtarget_info, context); + }, *m_subtarget_info_ap, *m_context_ap)) + return; + + std::unique_ptr RelInfo; + if (!InitializePtr(RelInfo, m_is_valid, + [curr_target, triple](llvm::MCContext& context) { + return curr_target->createMCRelocationInfo(triple, context); + }, *m_context_ap)) + return; + + std::unique_ptr symbolizer_up; + if (!InitializePtr(symbolizer_up, m_is_valid, + [curr_target, triple, &owner, &RelInfo](llvm::MCContext& context) { + return curr_target->createMCSymbolizer( triple, NULL, DisassemblerLLVMC::SymbolLookupCallback, - (void *)&owner, m_context_ap.get(), std::move(RelInfo))); - m_disasm_ap->setSymbolizer(std::move(symbolizer_up)); + static_cast(&owner), &context, std::move(RelInfo)); + }, *m_context_ap)) + return; - unsigned asm_printer_variant; - if (flavor == ~0U) - asm_printer_variant = m_asm_info_ap->getAssemblerDialect(); - else { - asm_printer_variant = flavor; - } + m_disasm_ap->setSymbolizer(std::move(symbolizer_up)); - m_instr_printer_ap.reset(curr_target->createMCInstPrinter( - llvm::Triple{triple}, asm_printer_variant, *m_asm_info_ap.get(), - *m_instr_info_ap.get(), *m_reg_info_ap.get())); - if (m_instr_printer_ap.get() == NULL) { - m_disasm_ap.reset(); - m_is_valid = false; - } - } else - m_is_valid = false; + unsigned asm_printer_variant = + flavor == ~0U ? m_asm_info_ap->getAssemblerDialect() : flavor; + + if (!InitializePtr(m_instr_printer_ap, m_is_valid, + [curr_target, triple, asm_printer_variant]( + const llvm::MCAsmInfo& asm_info, + const llvm::MCInstrInfo& instr_info, + const llvm::MCRegisterInfo& reg_info) { + return curr_target->createMCInstPrinter(llvm::Triple{ triple }, + asm_printer_variant, asm_info, instr_info, reg_info); + }, *m_asm_info_ap, *m_instr_info_ap, *m_reg_info_ap)) + m_disasm_ap.reset(); } DisassemblerLLVMC::LLVMCDisassembler::~LLVMCDisassembler() = default;