11bb52e94SNathan Lanza //===--- CIRGenAction.cpp - LLVM Code generation Frontend Action ---------===// 21bb52e94SNathan Lanza // 31bb52e94SNathan Lanza // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41bb52e94SNathan Lanza // See https://llvm.org/LICENSE.txt for license information. 51bb52e94SNathan Lanza // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61bb52e94SNathan Lanza // 71bb52e94SNathan Lanza //===----------------------------------------------------------------------===// 81bb52e94SNathan Lanza 91bb52e94SNathan Lanza #include "clang/CIR/FrontendAction/CIRGenAction.h" 101bb52e94SNathan Lanza #include "clang/CIR/CIRGenerator.h" 111bb52e94SNathan Lanza #include "clang/Frontend/CompilerInstance.h" 121bb52e94SNathan Lanza 131bb52e94SNathan Lanza #include "mlir/IR/MLIRContext.h" 141bb52e94SNathan Lanza #include "mlir/IR/OwningOpRef.h" 151bb52e94SNathan Lanza 161bb52e94SNathan Lanza using namespace cir; 171bb52e94SNathan Lanza using namespace clang; 181bb52e94SNathan Lanza 191bb52e94SNathan Lanza namespace cir { 201bb52e94SNathan Lanza 211bb52e94SNathan Lanza class CIRGenConsumer : public clang::ASTConsumer { 221bb52e94SNathan Lanza 231bb52e94SNathan Lanza virtual void anchor(); 241bb52e94SNathan Lanza 25*c695a325SDavid Olsen CIRGenAction::OutputType Action; 26*c695a325SDavid Olsen 271bb52e94SNathan Lanza std::unique_ptr<raw_pwrite_stream> OutputStream; 281bb52e94SNathan Lanza 29*c695a325SDavid Olsen ASTContext *Context{nullptr}; 301bb52e94SNathan Lanza IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; 311bb52e94SNathan Lanza std::unique_ptr<CIRGenerator> Gen; 321bb52e94SNathan Lanza 331bb52e94SNathan Lanza public: 341bb52e94SNathan Lanza CIRGenConsumer(CIRGenAction::OutputType Action, 351bb52e94SNathan Lanza DiagnosticsEngine &DiagnosticsEngine, 361bb52e94SNathan Lanza IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, 371bb52e94SNathan Lanza const HeaderSearchOptions &HeaderSearchOptions, 381bb52e94SNathan Lanza const CodeGenOptions &CodeGenOptions, 391bb52e94SNathan Lanza const TargetOptions &TargetOptions, 401bb52e94SNathan Lanza const LangOptions &LangOptions, 411bb52e94SNathan Lanza const FrontendOptions &FEOptions, 421bb52e94SNathan Lanza std::unique_ptr<raw_pwrite_stream> OS) 43*c695a325SDavid Olsen : Action(Action), OutputStream(std::move(OS)), FS(VFS), 441bb52e94SNathan Lanza Gen(std::make_unique<CIRGenerator>(DiagnosticsEngine, std::move(VFS), 451bb52e94SNathan Lanza CodeGenOptions)) {} 461bb52e94SNathan Lanza 47*c695a325SDavid Olsen void Initialize(ASTContext &Ctx) override { 48*c695a325SDavid Olsen assert(!Context && "initialized multiple times"); 49*c695a325SDavid Olsen Context = &Ctx; 50*c695a325SDavid Olsen Gen->Initialize(Ctx); 51*c695a325SDavid Olsen } 52*c695a325SDavid Olsen 531bb52e94SNathan Lanza bool HandleTopLevelDecl(DeclGroupRef D) override { 541bb52e94SNathan Lanza Gen->HandleTopLevelDecl(D); 551bb52e94SNathan Lanza return true; 561bb52e94SNathan Lanza } 57*c695a325SDavid Olsen 58*c695a325SDavid Olsen void HandleTranslationUnit(ASTContext &C) override { 59*c695a325SDavid Olsen Gen->HandleTranslationUnit(C); 60*c695a325SDavid Olsen mlir::ModuleOp MlirModule = Gen->getModule(); 61*c695a325SDavid Olsen switch (Action) { 62*c695a325SDavid Olsen case CIRGenAction::OutputType::EmitCIR: 63*c695a325SDavid Olsen if (OutputStream && MlirModule) { 64*c695a325SDavid Olsen mlir::OpPrintingFlags Flags; 65*c695a325SDavid Olsen Flags.enableDebugInfo(/*enable=*/true, /*prettyForm=*/false); 66*c695a325SDavid Olsen MlirModule->print(*OutputStream, Flags); 67*c695a325SDavid Olsen } 68*c695a325SDavid Olsen break; 69*c695a325SDavid Olsen } 70*c695a325SDavid Olsen } 711bb52e94SNathan Lanza }; 721bb52e94SNathan Lanza } // namespace cir 731bb52e94SNathan Lanza 741bb52e94SNathan Lanza void CIRGenConsumer::anchor() {} 751bb52e94SNathan Lanza 761bb52e94SNathan Lanza CIRGenAction::CIRGenAction(OutputType Act, mlir::MLIRContext *MLIRCtx) 771bb52e94SNathan Lanza : MLIRCtx(MLIRCtx ? MLIRCtx : new mlir::MLIRContext), Action(Act) {} 781bb52e94SNathan Lanza 791bb52e94SNathan Lanza CIRGenAction::~CIRGenAction() { MLIRMod.release(); } 801bb52e94SNathan Lanza 81*c695a325SDavid Olsen static std::unique_ptr<raw_pwrite_stream> 82*c695a325SDavid Olsen getOutputStream(CompilerInstance &CI, StringRef InFile, 83*c695a325SDavid Olsen CIRGenAction::OutputType Action) { 84*c695a325SDavid Olsen switch (Action) { 85*c695a325SDavid Olsen case CIRGenAction::OutputType::EmitCIR: 86*c695a325SDavid Olsen return CI.createDefaultOutputFile(false, InFile, "cir"); 87*c695a325SDavid Olsen } 88*c695a325SDavid Olsen llvm_unreachable("Invalid CIRGenAction::OutputType"); 89*c695a325SDavid Olsen } 90*c695a325SDavid Olsen 911bb52e94SNathan Lanza std::unique_ptr<ASTConsumer> 921bb52e94SNathan Lanza CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 931bb52e94SNathan Lanza std::unique_ptr<llvm::raw_pwrite_stream> Out = CI.takeOutputStream(); 941bb52e94SNathan Lanza 95*c695a325SDavid Olsen if (!Out) 96*c695a325SDavid Olsen Out = getOutputStream(CI, InFile, Action); 97*c695a325SDavid Olsen 981bb52e94SNathan Lanza auto Result = std::make_unique<cir::CIRGenConsumer>( 991bb52e94SNathan Lanza Action, CI.getDiagnostics(), &CI.getVirtualFileSystem(), 1001bb52e94SNathan Lanza CI.getHeaderSearchOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(), 1011bb52e94SNathan Lanza CI.getLangOpts(), CI.getFrontendOpts(), std::move(Out)); 1021bb52e94SNathan Lanza 1031bb52e94SNathan Lanza return Result; 1041bb52e94SNathan Lanza } 1051bb52e94SNathan Lanza 1061bb52e94SNathan Lanza void EmitCIRAction::anchor() {} 1071bb52e94SNathan Lanza EmitCIRAction::EmitCIRAction(mlir::MLIRContext *MLIRCtx) 1081bb52e94SNathan Lanza : CIRGenAction(OutputType::EmitCIR, MLIRCtx) {} 109