1//===--- CodeGenAction.h - LLVM Code Generation Frontend Action -*- C++ -*-===//
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#ifndef LLVM_CLANG_CODEGEN_CODEGENACTION_H
10#define LLVM_CLANG_CODEGEN_CODEGENACTION_H
11
12#include "clang/Frontend/FrontendAction.h"
13#include <memory>
14
15namespace llvm {
16  class LLVMContext;
17  class Module;
18}
19
20namespace clang {
21class BackendConsumer;
22
23class CodeGenAction : public ASTFrontendAction {
24private:
25  // Let BackendConsumer access LinkModule.
26  friend class BackendConsumer;
27
28  /// Info about module to link into a module we're generating.
29  struct LinkModule {
30    /// The module to link in.
31    std::unique_ptr<llvm::Module> Module;
32
33    /// If true, we set attributes on Module's functions according to our
34    /// CodeGenOptions and LangOptions, as though we were generating the
35    /// function ourselves.
36    bool PropagateAttrs;
37
38    /// If true, we use LLVM module internalizer.
39    bool Internalize;
40
41    /// Bitwise combination of llvm::LinkerFlags used when we link the module.
42    unsigned LinkFlags;
43  };
44
45  unsigned Act;
46  std::unique_ptr<llvm::Module> TheModule;
47
48  /// Bitcode modules to link in to our module.
49  SmallVector<LinkModule, 4> LinkModules;
50  llvm::LLVMContext *VMContext;
51  bool OwnsVMContext;
52
53  std::unique_ptr<llvm::Module> loadModule(llvm::MemoryBufferRef MBRef);
54
55protected:
56  /// Create a new code generation action.  If the optional \p _VMContext
57  /// parameter is supplied, the action uses it without taking ownership,
58  /// otherwise it creates a fresh LLVM context and takes ownership.
59  CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext = nullptr);
60
61  bool hasIRSupport() const override;
62
63  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
64                                                 StringRef InFile) override;
65
66  void ExecuteAction() override;
67
68  void EndSourceFileAction() override;
69
70public:
71  ~CodeGenAction() override;
72
73  /// Take the generated LLVM module, for use after the action has been run.
74  /// The result may be null on failure.
75  std::unique_ptr<llvm::Module> takeModule();
76
77  /// Take the LLVM context used by this action.
78  llvm::LLVMContext *takeLLVMContext();
79
80  BackendConsumer *BEConsumer;
81};
82
83class EmitAssemblyAction : public CodeGenAction {
84  virtual void anchor();
85public:
86  EmitAssemblyAction(llvm::LLVMContext *_VMContext = nullptr);
87};
88
89class EmitBCAction : public CodeGenAction {
90  virtual void anchor();
91public:
92  EmitBCAction(llvm::LLVMContext *_VMContext = nullptr);
93};
94
95class EmitLLVMAction : public CodeGenAction {
96  virtual void anchor();
97public:
98  EmitLLVMAction(llvm::LLVMContext *_VMContext = nullptr);
99};
100
101class EmitLLVMOnlyAction : public CodeGenAction {
102  virtual void anchor();
103public:
104  EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
105};
106
107class EmitCodeGenOnlyAction : public CodeGenAction {
108  virtual void anchor();
109public:
110  EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
111};
112
113class EmitObjAction : public CodeGenAction {
114  virtual void anchor();
115public:
116  EmitObjAction(llvm::LLVMContext *_VMContext = nullptr);
117};
118
119}
120
121#endif
122