Frontend: Add CodeGenAction::takeModule().

llvm-svn: 97111
This commit is contained in:
Daniel Dunbar 2010-02-25 04:37:50 +00:00
parent cea0c70f12
commit 400a6939a8
2 changed files with 39 additions and 8 deletions

View File

@ -8,18 +8,31 @@
//===----------------------------------------------------------------------===//
#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 {

View File

@ -62,7 +62,7 @@ namespace {
llvm::OwningPtr<CodeGenerator> Gen;
llvm::Module *TheModule;
llvm::OwningPtr<llvm::Module> TheModule;
llvm::TargetData *TheTargetData;
mutable FunctionPassManager *CodeGenPasses;
@ -97,7 +97,7 @@ namespace {
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)
@ -109,12 +109,13 @@ namespace {
~BackendConsumer() {
delete TheTargetData;
delete TheModule;
delete CodeGenPasses;
delete PerModulePasses;
delete PerFunctionPasses;
}
llvm::Module *takeModule() { return TheModule.take(); }
virtual void Initialize(ASTContext &Ctx) {
Context = &Ctx;
@ -123,7 +124,7 @@ namespace {
Gen->Initialize(Ctx);
TheModule = Gen->GetModule();
TheModule.reset(Gen->GetModule());
TheTargetData = new llvm::TargetData(Ctx.Target.getTargetDescription());
if (llvm::TimePassesIsEnabled)
@ -179,7 +180,7 @@ namespace {
FunctionPassManager *BackendConsumer::getCodeGenPasses() const {
if (!CodeGenPasses) {
CodeGenPasses = new FunctionPassManager(TheModule);
CodeGenPasses = new FunctionPassManager(&*TheModule);
CodeGenPasses->add(new TargetData(*TheTargetData));
}
@ -197,7 +198,7 @@ PassManager *BackendConsumer::getPerModulePasses() const {
FunctionPassManager *BackendConsumer::getPerFunctionPasses() const {
if (!PerFunctionPasses) {
PerFunctionPasses = new FunctionPassManager(TheModule);
PerFunctionPasses = new FunctionPassManager(&*TheModule);
PerFunctionPasses->add(new TargetData(*TheTargetData));
}
@ -391,11 +392,12 @@ void BackendConsumer::EmitAssembly() {
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())
@ -433,6 +435,22 @@ void BackendConsumer::EmitAssembly() {
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);