[cfe-commits] r96564 - in /cfe/trunk/lib/CodeGen: CGClass.cpp CodeGenFunction.cpp CodeGenFunction.h

John McCall rjmccall at apple.com
Wed Feb 17 19:17:58 PST 2010


Author: rjmccall
Date: Wed Feb 17 21:17:58 2010
New Revision: 96564

URL: http://llvm.org/viewvc/llvm-project?rev=96564&view=rev
Log:
Extract out function-body code generation into its own method.  No functionality
change.


Modified:
    cfe/trunk/lib/CodeGen/CGClass.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
    cfe/trunk/lib/CodeGen/CodeGenFunction.h

Modified: cfe/trunk/lib/CodeGen/CGClass.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGClass.cpp?rev=96564&r1=96563&r2=96564&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGClass.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGClass.cpp Wed Feb 17 21:17:58 2010
@@ -590,17 +590,44 @@
            Callee, ReturnValueSlot(), CallArgs, MD);
 }
 
-/// SynthesizeDefaultConstructor - synthesize a default constructor
-void
-CodeGenFunction::SynthesizeDefaultConstructor(const CXXConstructorDecl *Ctor,
-                                              CXXCtorType Type,
-                                              llvm::Function *Fn,
-                                              const FunctionArgList &Args) {
-  assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor");
-  StartFunction(GlobalDecl(Ctor, Type), Ctor->getResultType(), Fn, Args, 
-                SourceLocation());
-  EmitCtorPrologue(Ctor, Type);
-  FinishFunction();
+/// Synthesizes an implicit function body.  Since these only arise in
+/// C++, we only do them in C++.
+void CodeGenFunction::SynthesizeImplicitFunctionBody(GlobalDecl GD,
+                                                     llvm::Function *Fn,
+                                               const FunctionArgList &Args) {
+  const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
+
+  // FIXME: this should become isImplicitlyDefined() once we properly
+  // support that for C++0x.
+  assert(FD->isImplicit() && "Cannot synthesize a non-implicit function");
+
+  if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
+    assert(!CD->isTrivial() && "shouldn't need to synthesize a trivial ctor");
+
+    if (CD->isDefaultConstructor()) {
+      // Sema generates base and member initializers as for this, so
+      // the ctor prologue is good enough here.
+      return;
+    } else {
+      assert(CD->isCopyConstructor());
+      return SynthesizeCXXCopyConstructor(CD, GD.getCtorType(), Fn, Args);
+    }
+  }
+
+  if (isa<CXXDestructorDecl>(FD)) {
+    // The dtor epilogue does everything we'd need to do here.
+    return;
+  }
+
+  const CXXMethodDecl *MD = cast<CXXMethodDecl>(FD);
+
+  // FIXME: in C++0x we might have user-declared copy assignment operators
+  // coexisting with implicitly-defined ones.
+  assert(MD->isCopyAssignment() &&
+         !MD->getParent()->hasUserDeclaredCopyAssignment() &&
+         "Cannot synthesize a method that is not an implicitly-defined "
+         "copy constructor");
+  SynthesizeCXXCopyAssignment(MD, Fn, Args);
 }
 
 /// SynthesizeCXXCopyConstructor - This routine implicitly defines body of a
@@ -627,8 +654,6 @@
   assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
       "SynthesizeCXXCopyConstructor - copy constructor has definition already");
   assert(!Ctor->isTrivial() && "shouldn't need to generate trivial ctor");
-  StartFunction(GlobalDecl(Ctor, Type), Ctor->getResultType(), Fn, Args, 
-                SourceLocation());
 
   FunctionArgList::const_iterator i = Args.begin();
   const VarDecl *ThisArg = i->first;
@@ -698,7 +723,6 @@
   }
 
   InitializeVtablePtrs(ClassDecl);
-  FinishFunction();
 }
 
 /// SynthesizeCXXCopyAssignment - Implicitly define copy assignment operator.
@@ -728,7 +752,6 @@
   const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(CD->getDeclContext());
   assert(!ClassDecl->hasUserDeclaredCopyAssignment() &&
          "SynthesizeCXXCopyAssignment - copy assignment has user declaration");
-  StartFunction(CD, CD->getResultType(), Fn, Args, SourceLocation());
 
   FunctionArgList::const_iterator i = Args.begin();
   const VarDecl *ThisArg = i->first;
@@ -796,8 +819,6 @@
 
   // return *this;
   Builder.CreateStore(LoadOfThis, ReturnValue);
-
-  FinishFunction();
 }
 
 static void EmitBaseInitializer(CodeGenFunction &CGF, 
@@ -1054,20 +1075,6 @@
   }
 }
 
-void CodeGenFunction::SynthesizeDefaultDestructor(const CXXDestructorDecl *Dtor,
-                                                  CXXDtorType DtorType,
-                                                  llvm::Function *Fn,
-                                                  const FunctionArgList &Args) {
-  assert(!Dtor->getParent()->hasUserDeclaredDestructor() &&
-         "SynthesizeDefaultDestructor - destructor has user declaration");
-
-  StartFunction(GlobalDecl(Dtor, DtorType), Dtor->getResultType(), Fn, Args, 
-                SourceLocation());
-  InitializeVtablePtrs(Dtor->getParent());
-  EmitDtorEpilogue(Dtor, DtorType);
-  FinishFunction();
-}
-
 /// EmitCXXAggrConstructorCall - This routine essentially creates a (nested)
 /// for-loop to call the default constructor on individual members of the
 /// array. 

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.cpp?rev=96564&r1=96563&r2=96564&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.cpp Wed Feb 17 21:17:58 2010
@@ -241,6 +241,53 @@
   }
 }
 
+void CodeGenFunction::GenerateBody(GlobalDecl GD, llvm::Function *Fn, 
+                                   FunctionArgList &Args) {
+  const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
+
+  Stmt *Body = FD->getBody();
+  assert((Body || FD->isImplicit()) && "non-implicit function def has no body");
+
+  // Emit special ctor/dtor prologues.
+  llvm::BasicBlock *DtorEpilogue = 0;
+  if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
+    EmitCtorPrologue(CD, GD.getCtorType());
+  } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) {
+    DtorEpilogue = createBasicBlock("dtor.epilogue");
+    PushCleanupBlock(DtorEpilogue);
+
+    InitializeVtablePtrs(DD->getParent());
+  }
+
+  // Emit the body of the function.
+  if (!Body)
+    SynthesizeImplicitFunctionBody(GD, Fn, Args);
+  else {
+    if (isa<CXXTryStmt>(Body))
+      OuterTryBlock = cast<CXXTryStmt>(Body);
+
+    EmitStmt(Body);
+  }
+
+  // Emit special ctor/ctor epilogues.
+  if (isa<CXXConstructorDecl>(FD)) {
+    // If any of the member initializers are temporaries bound to references
+    // make sure to emit their destructors.
+    EmitCleanupBlocks(0);
+  } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) {
+    CleanupBlockInfo Info = PopCleanupBlock();
+    assert(Info.CleanupBlock == DtorEpilogue && "Block mismatch!");
+
+    EmitBlock(DtorEpilogue);
+    EmitDtorEpilogue(DD, GD.getDtorType());
+      
+    if (Info.SwitchBlock)
+      EmitBlock(Info.SwitchBlock);
+    if (Info.EndBlock)
+      EmitBlock(Info.EndBlock);
+  }
+}
+
 void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn) {
   const FunctionDecl *FD = cast<FunctionDecl>(GD.getDecl());
   
@@ -284,80 +331,17 @@
                                     FProto->getArgType(i)));
   }
 
-  if (const CompoundStmt *S = FD->getCompoundBody()) {
-    StartFunction(GD, FD->getResultType(), Fn, Args, S->getLBracLoc());
+  SourceRange BodyRange;
+  if (Stmt *Body = FD->getBody()) BodyRange = Body->getSourceRange();
 
-    if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
-      EmitCtorPrologue(CD, GD.getCtorType());
-      EmitStmt(S);
-      
-      // If any of the member initializers are temporaries bound to references
-      // make sure to emit their destructors.
-      EmitCleanupBlocks(0);
-      
-    } else if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(FD)) {
-      llvm::BasicBlock *DtorEpilogue  = createBasicBlock("dtor.epilogue");
-      PushCleanupBlock(DtorEpilogue);
+  // Emit the standard function prologue.
+  StartFunction(GD, FD->getResultType(), Fn, Args, BodyRange.getBegin());
 
-      InitializeVtablePtrs(DD->getParent());
+  // Generate the body of the function.
+  GenerateBody(GD, Fn, Args);
 
-      EmitStmt(S);
-      
-      CleanupBlockInfo Info = PopCleanupBlock();
-
-      assert(Info.CleanupBlock == DtorEpilogue && "Block mismatch!");
-      EmitBlock(DtorEpilogue);
-      EmitDtorEpilogue(DD, GD.getDtorType());
-      
-      if (Info.SwitchBlock)
-        EmitBlock(Info.SwitchBlock);
-      if (Info.EndBlock)
-        EmitBlock(Info.EndBlock);
-    } else {
-      // Just a regular function, emit its body.
-      EmitStmt(S);
-    }
-    
-    FinishFunction(S->getRBracLoc());
-  } else if (FD->isImplicit()) {
-    const CXXRecordDecl *ClassDecl =
-      cast<CXXRecordDecl>(FD->getDeclContext());
-    (void) ClassDecl;
-    if (const CXXConstructorDecl *CD = dyn_cast<CXXConstructorDecl>(FD)) {
-      // FIXME: For C++0x, we want to look for implicit *definitions* of
-      // these special member functions, rather than implicit *declarations*.
-      if (CD->isCopyConstructor()) {
-        assert(!ClassDecl->hasUserDeclaredCopyConstructor() &&
-               "Cannot synthesize a non-implicit copy constructor");
-        SynthesizeCXXCopyConstructor(CD, GD.getCtorType(), Fn, Args);
-      } else if (CD->isDefaultConstructor()) {
-        assert(!ClassDecl->hasUserDeclaredConstructor() &&
-               "Cannot synthesize a non-implicit default constructor.");
-        SynthesizeDefaultConstructor(CD, GD.getCtorType(), Fn, Args);
-      } else {
-        assert(false && "Implicit constructor cannot be synthesized");
-      }
-    } else if (const CXXDestructorDecl *CD = dyn_cast<CXXDestructorDecl>(FD)) {
-      assert(!ClassDecl->hasUserDeclaredDestructor() &&
-             "Cannot synthesize a non-implicit destructor");
-      SynthesizeDefaultDestructor(CD, GD.getDtorType(), Fn, Args);
-    } else if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
-      assert(MD->isCopyAssignment() && 
-             !ClassDecl->hasUserDeclaredCopyAssignment() &&
-             "Cannot synthesize a method that is not an implicit-defined "
-             "copy constructor");
-      SynthesizeCXXCopyAssignment(MD, Fn, Args);
-    } else {
-      assert(false && "Cannot synthesize unknown implicit function");
-    }
-  } else if (const Stmt *S = FD->getBody()) {
-    if (const CXXTryStmt *TS = dyn_cast<CXXTryStmt>(S)) {
-      OuterTryBlock = TS;
-      StartFunction(GD, FD->getResultType(), Fn, Args, TS->getTryLoc());
-      EmitStmt(TS);
-      FinishFunction(TS->getEndLoc());
-    }
-  }
+  // Emit the standard function epilogue.
+  FinishFunction(BodyRange.getEnd());
 
   // Destroy the 'this' declaration.
   if (CXXThisDecl)

Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=96564&r1=96563&r2=96564&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Wed Feb 17 21:17:58 2010
@@ -494,6 +494,8 @@
                      const FunctionArgList &Args,
                      SourceLocation StartLoc);
 
+  void GenerateBody(GlobalDecl GD, llvm::Function *Fn,  FunctionArgList &Args);
+
   /// EmitReturnBlock - Emit the unified return block, trying to avoid its
   /// emission when possible.
   void EmitReturnBlock();
@@ -536,15 +538,9 @@
                                    llvm::Function *Fn,
                                    const FunctionArgList &Args);
 
-  void SynthesizeDefaultConstructor(const CXXConstructorDecl *Ctor,
-                                    CXXCtorType Type,
-                                    llvm::Function *Fn,
-                                    const FunctionArgList &Args);
-
-  void SynthesizeDefaultDestructor(const CXXDestructorDecl *Dtor,
-                                   CXXDtorType Type,
-                                   llvm::Function *Fn,
-                                   const FunctionArgList &Args);
+  void SynthesizeImplicitFunctionBody(GlobalDecl GD,
+                                      llvm::Function *Fn,
+                                      const FunctionArgList &Args);
 
   /// EmitDtorEpilogue - Emit all code that comes at the end of class's
   /// destructor. This is to call destructors on members and base classes in





More information about the cfe-commits mailing list