// // This file is distributed under the MIT License. See LICENSE.md for details. // #include #include "llvm/Support/ToolOutputFile.h" #include "mlir/Pass/Pass.h" #include "mlir/Support/FileUtilities.h" #include "revng/CliftEmitC/CBackend.h" #include "revng/CliftEmitC/Headers.h" #include "revng/CliftImportModel/ImportModel.h" #include "revng/CliftTransforms/Passes.h" #include "revng/Support/Debug.h" namespace clift { #define GEN_PASS_DEF_CLIFTEMITC #define GEN_PASS_DEF_CLIFTEMITTYPEANDGLOBALHEADER #define GEN_PASS_DEF_CLIFTEMITHELPERHEADER #include "revng/CliftTransforms/Passes.h.inc" } // namespace clift namespace { template typename BaseT, auto Impl> struct CEmissionPass : BaseT> { using Base = BaseT>; static std::unique_ptr tryOpenOutputFile(llvm::StringRef Filename) { std::string ErrorMessage; auto File = mlir::openOutputFile(Filename, &ErrorMessage); if (File) File->keep(); else dbg << ErrorMessage << "\n"; return File; } void runOnOperation() override { auto File = tryOpenOutputFile(Base::Output); if (not File) return Base::signalPassFailure(); mlir::ModuleOp Module = Base::getOperation(); auto Tagging = static_cast(Base::EmitTags.getValue()); ptml::CTokenEmitter Emitter(File->os(), Tagging); if (not Impl(Module, Emitter)) return Base::signalPassFailure(); } }; } // namespace clift::PassPtr clift::createEmitCPass() { static constexpr auto Impl = [](mlir::ModuleOp Module, ptml::CTokenEmitter &Emitter) { Module->walk([&Emitter](clift::FunctionOp Function) { if (not Function.isExternal()) decompile(Function, Emitter); }); return true; }; return std::make_unique>(); } template using TaGHBase = clift::impl::CliftEmitTypeAndGlobalHeaderBase; clift::PassPtr clift::createEmitTypeAndGlobalHeaderPass() { static constexpr auto Impl = [](mlir::ModuleOp Module, ptml::CTokenEmitter &Tokens) { TypeEmitterConfiguration Configuration = { .TypeToOmit = {}, .EmitMaximumEnumValue = false, .ExplicitPadding = true, }; emitTypeAndGlobalHeader(Tokens, Module, Configuration); return true; }; return std::make_unique>(); } template using HHBase = clift::impl::CliftEmitHelperHeaderBase; clift::PassPtr clift::createEmitHelperHeaderPass() { static constexpr auto Impl = [](mlir::ModuleOp Module, ptml::CTokenEmitter &Tokens) { emitHelperHeader(Tokens, { Module }, model::Binary{}); return true; }; return std::make_unique>(); }