xref: /llvm-project/clang/lib/CIR/FrontendAction/CIRGenAction.cpp (revision eaa4eb281d4a0e34c7b4c2dac50cd151c3cb27e6)
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