]> granicus.if.org Git - clang/commitdiff
Frontend: Add CodeGenAction::takeModule().
authorDaniel Dunbar <daniel@zuster.org>
Thu, 25 Feb 2010 04:37:50 +0000 (04:37 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 25 Feb 2010 04:37:50 +0000 (04:37 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@97111 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/CodeGenAction.h
lib/Frontend/CodeGenAction.cpp

index f782e1287a2944fd009cef797b728453732705c3..07e02e5c6e7831c2ad09ce641e0551b6b3e50457 100644 (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 {
index 7800d1534eeae89f9a87d06d2557720918c4fed4..ff24854339beb481221490acc67f9568f583bec0 100644 (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);