1 //===--- CIRGenAction.cpp - LLVM Code generation Frontend Action ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "clang/CIR/FrontendAction/CIRGenAction.h" 10 #include "clang/CIR/CIRGenerator.h" 11 #include "clang/Frontend/CompilerInstance.h" 12 13 #include "mlir/IR/MLIRContext.h" 14 #include "mlir/IR/OwningOpRef.h" 15 16 using namespace cir; 17 using namespace clang; 18 19 namespace cir { 20 21 class CIRGenConsumer : public clang::ASTConsumer { 22 23 virtual void anchor(); 24 25 CIRGenAction::OutputType Action; 26 27 std::unique_ptr<raw_pwrite_stream> OutputStream; 28 29 ASTContext *Context{nullptr}; 30 IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; 31 std::unique_ptr<CIRGenerator> Gen; 32 33 public: 34 CIRGenConsumer(CIRGenAction::OutputType Action, 35 DiagnosticsEngine &DiagnosticsEngine, 36 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, 37 const HeaderSearchOptions &HeaderSearchOptions, 38 const CodeGenOptions &CodeGenOptions, 39 const TargetOptions &TargetOptions, 40 const LangOptions &LangOptions, 41 const FrontendOptions &FEOptions, 42 std::unique_ptr<raw_pwrite_stream> OS) 43 : Action(Action), OutputStream(std::move(OS)), FS(VFS), 44 Gen(std::make_unique<CIRGenerator>(DiagnosticsEngine, std::move(VFS), 45 CodeGenOptions)) {} 46 47 void Initialize(ASTContext &Ctx) override { 48 assert(!Context && "initialized multiple times"); 49 Context = &Ctx; 50 Gen->Initialize(Ctx); 51 } 52 53 bool HandleTopLevelDecl(DeclGroupRef D) override { 54 Gen->HandleTopLevelDecl(D); 55 return true; 56 } 57 58 void HandleTranslationUnit(ASTContext &C) override { 59 Gen->HandleTranslationUnit(C); 60 mlir::ModuleOp MlirModule = Gen->getModule(); 61 switch (Action) { 62 case CIRGenAction::OutputType::EmitCIR: 63 if (OutputStream && MlirModule) { 64 mlir::OpPrintingFlags Flags; 65 Flags.enableDebugInfo(/*enable=*/true, /*prettyForm=*/false); 66 MlirModule->print(*OutputStream, Flags); 67 } 68 break; 69 } 70 } 71 }; 72 } // namespace cir 73 74 void CIRGenConsumer::anchor() {} 75 76 CIRGenAction::CIRGenAction(OutputType Act, mlir::MLIRContext *MLIRCtx) 77 : MLIRCtx(MLIRCtx ? MLIRCtx : new mlir::MLIRContext), Action(Act) {} 78 79 CIRGenAction::~CIRGenAction() { MLIRMod.release(); } 80 81 static std::unique_ptr<raw_pwrite_stream> 82 getOutputStream(CompilerInstance &CI, StringRef InFile, 83 CIRGenAction::OutputType Action) { 84 switch (Action) { 85 case CIRGenAction::OutputType::EmitCIR: 86 return CI.createDefaultOutputFile(false, InFile, "cir"); 87 } 88 llvm_unreachable("Invalid CIRGenAction::OutputType"); 89 } 90 91 std::unique_ptr<ASTConsumer> 92 CIRGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { 93 std::unique_ptr<llvm::raw_pwrite_stream> Out = CI.takeOutputStream(); 94 95 if (!Out) 96 Out = getOutputStream(CI, InFile, Action); 97 98 auto Result = std::make_unique<cir::CIRGenConsumer>( 99 Action, CI.getDiagnostics(), &CI.getVirtualFileSystem(), 100 CI.getHeaderSearchOpts(), CI.getCodeGenOpts(), CI.getTargetOpts(), 101 CI.getLangOpts(), CI.getFrontendOpts(), std::move(Out)); 102 103 return Result; 104 } 105 106 void EmitCIRAction::anchor() {} 107 EmitCIRAction::EmitCIRAction(mlir::MLIRContext *MLIRCtx) 108 : CIRGenAction(OutputType::EmitCIR, MLIRCtx) {} 109