//===----------------------------------------------------------------------===//
#include "clang/Frontend/FrontendAction.h"
+#include "llvm/ADT/OwningPtr.h"
+
+namespace llvm {
+ class Module;
+}
namespace clang {
class CodeGenAction : public ASTFrontendAction {
private:
unsigned Act;
+ llvm::OwningPtr<llvm::Module> TheModule;
protected:
CodeGenAction(unsigned _Act);
virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile);
+
+ virtual void EndSourceFileAction();
+
+public:
+ /// takeModule - Take the generated LLVM module, for use after the action has
+ /// been run. The result may be null on failure.
+ llvm::Module *takeModule();
};
class EmitAssemblyAction : public CodeGenAction {
llvm::OwningPtr<CodeGenerator> Gen;
- llvm::Module *TheModule;
+ llvm::OwningPtr<llvm::Module> TheModule;
llvm::TargetData *TheTargetData;
mutable FunctionPassManager *CodeGenPasses;
LLVMIRGeneration("LLVM IR Generation Time"),
CodeGenerationTime("Code Generation Time"),
Gen(CreateLLVMCodeGen(Diags, infile, compopts, C)),
- TheModule(0), TheTargetData(0),
+ TheTargetData(0),
CodeGenPasses(0), PerModulePasses(0), PerFunctionPasses(0) {
if (AsmOutStream)
~BackendConsumer() {
delete TheTargetData;
- delete TheModule;
delete CodeGenPasses;
delete PerModulePasses;
delete PerFunctionPasses;
}
+ llvm::Module *takeModule() { return TheModule.take(); }
+
virtual void Initialize(ASTContext &Ctx) {
Context = &Ctx;
Gen->Initialize(Ctx);
- TheModule = Gen->GetModule();
+ TheModule.reset(Gen->GetModule());
TheTargetData = new llvm::TargetData(Ctx.Target.getTargetDescription());
if (llvm::TimePassesIsEnabled)
FunctionPassManager *BackendConsumer::getCodeGenPasses() const {
if (!CodeGenPasses) {
- CodeGenPasses = new FunctionPassManager(TheModule);
+ CodeGenPasses = new FunctionPassManager(&*TheModule);
CodeGenPasses->add(new TargetData(*TheTargetData));
}
FunctionPassManager *BackendConsumer::getPerFunctionPasses() const {
if (!PerFunctionPasses) {
- PerFunctionPasses = new FunctionPassManager(TheModule);
+ PerFunctionPasses = new FunctionPassManager(&*TheModule);
PerFunctionPasses->add(new TargetData(*TheTargetData));
}
if (!M) {
// The module has been released by IR gen on failures, do not
// double free.
- TheModule = 0;
+ TheModule.take();
return;
}
- assert(TheModule == M && "Unexpected module change during IR generation");
+ assert(TheModule.get() == M &&
+ "Unexpected module change during IR generation");
CreatePasses();
if (!AddEmitPasses())
CodeGenAction::CodeGenAction(unsigned _Act) : Act(_Act) {}
+void CodeGenAction::EndSourceFileAction() {
+ // If the consumer creation failed, do nothing.
+ if (!getCompilerInstance().hasASTConsumer())
+ return;
+
+ // Steal the module from the consumer.
+ BackendConsumer *Consumer = static_cast<BackendConsumer*>(
+ &getCompilerInstance().getASTConsumer());
+
+ TheModule.reset(Consumer->takeModule());
+}
+
+llvm::Module *CodeGenAction::takeModule() {
+ return TheModule.take();
+}
+
ASTConsumer *CodeGenAction::CreateASTConsumer(CompilerInstance &CI,
llvm::StringRef InFile) {
BackendAction BA = static_cast<BackendAction>(Act);