[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