//===--- CodeGenAction.h - LLVM Code Generation Frontend Action -*- C++ -*-===//
 
//
 
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 
// See https://llvm.org/LICENSE.txt for license information.
 
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 
//
 
//===----------------------------------------------------------------------===//
 
 
 
#ifndef LLVM_CLANG_CODEGEN_CODEGENACTION_H
 
#define LLVM_CLANG_CODEGEN_CODEGENACTION_H
 
 
 
#include "clang/Frontend/FrontendAction.h"
 
#include <memory>
 
 
 
namespace llvm {
 
  class LLVMContext;
 
  class Module;
 
}
 
 
 
namespace clang {
 
class BackendConsumer;
 
class CodeGenerator;
 
 
 
class CodeGenAction : public ASTFrontendAction {
 
private:
 
  // Let BackendConsumer access LinkModule.
 
  friend class BackendConsumer;
 
 
 
  /// Info about module to link into a module we're generating.
 
  struct LinkModule {
 
    /// The module to link in.
 
    std::unique_ptr<llvm::Module> Module;
 
 
 
    /// If true, we set attributes on Module's functions according to our
 
    /// CodeGenOptions and LangOptions, as though we were generating the
 
    /// function ourselves.
 
    bool PropagateAttrs;
 
 
 
    /// If true, we use LLVM module internalizer.
 
    bool Internalize;
 
 
 
    /// Bitwise combination of llvm::LinkerFlags used when we link the module.
 
    unsigned LinkFlags;
 
  };
 
 
 
  unsigned Act;
 
  std::unique_ptr<llvm::Module> TheModule;
 
 
 
  /// Bitcode modules to link in to our module.
 
  SmallVector<LinkModule, 4> LinkModules;
 
  llvm::LLVMContext *VMContext;
 
  bool OwnsVMContext;
 
 
 
  std::unique_ptr<llvm::Module> loadModule(llvm::MemoryBufferRef MBRef);
 
 
 
protected:
 
  /// Create a new code generation action.  If the optional \p _VMContext
 
  /// parameter is supplied, the action uses it without taking ownership,
 
  /// otherwise it creates a fresh LLVM context and takes ownership.
 
  CodeGenAction(unsigned _Act, llvm::LLVMContext *_VMContext = nullptr);
 
 
 
  bool hasIRSupport() const override;
 
 
 
  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
 
                                                 StringRef InFile) override;
 
 
 
  void ExecuteAction() override;
 
 
 
  void EndSourceFileAction() override;
 
 
 
public:
 
  ~CodeGenAction() override;
 
 
 
  /// Take the generated LLVM module, for use after the action has been run.
 
  /// The result may be null on failure.
 
  std::unique_ptr<llvm::Module> takeModule();
 
 
 
  /// Take the LLVM context used by this action.
 
  llvm::LLVMContext *takeLLVMContext();
 
 
 
  CodeGenerator *getCodeGenerator() const;
 
 
 
  BackendConsumer *BEConsumer;
 
};
 
 
 
class EmitAssemblyAction : public CodeGenAction {
 
  virtual void anchor();
 
public:
 
  EmitAssemblyAction(llvm::LLVMContext *_VMContext = nullptr);
 
};
 
 
 
class EmitBCAction : public CodeGenAction {
 
  virtual void anchor();
 
public:
 
  EmitBCAction(llvm::LLVMContext *_VMContext = nullptr);
 
};
 
 
 
class EmitLLVMAction : public CodeGenAction {
 
  virtual void anchor();
 
public:
 
  EmitLLVMAction(llvm::LLVMContext *_VMContext = nullptr);
 
};
 
 
 
class EmitLLVMOnlyAction : public CodeGenAction {
 
  virtual void anchor();
 
public:
 
  EmitLLVMOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
 
};
 
 
 
class EmitCodeGenOnlyAction : public CodeGenAction {
 
  virtual void anchor();
 
public:
 
  EmitCodeGenOnlyAction(llvm::LLVMContext *_VMContext = nullptr);
 
};
 
 
 
class EmitObjAction : public CodeGenAction {
 
  virtual void anchor();
 
public:
 
  EmitObjAction(llvm::LLVMContext *_VMContext = nullptr);
 
};
 
 
 
}
 
 
 
#endif