aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaInit.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-05-15 00:13:29 +0000
committerDouglas Gregor <dgregor@apple.com>2010-05-15 00:13:29 +0000
commit3c9034cb7ff1d6c1e4ecd1b44c98f553df013c7c (patch)
tree51a260b4bf4837766cfd3d2f06de837b8ffc08df /lib/Sema/SemaInit.cpp
parent67d438d39a1cc37c372a2684dc354f58d0169bb1 (diff)
Recognize when the named return value optimization applies in a
"return" statement and mark the corresponding CXXConstructExpr as elidable. Teach CodeGen that eliding a temporary is different from eliding an object construction. This is just a baby step toward NRVO. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103849 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaInit.cpp')
-rw-r--r--lib/Sema/SemaInit.cpp48
1 files changed, 39 insertions, 9 deletions
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 851fb9e835..06d202d3e0 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -1984,6 +1984,26 @@ DeclaratorDecl *InitializedEntity::getDecl() const {
return 0;
}
+bool InitializedEntity::allowsNRVO() const {
+ switch (getKind()) {
+ case EK_Result:
+ case EK_Exception:
+ return LocAndNRVO.NRVO;
+
+ case EK_Variable:
+ case EK_Parameter:
+ case EK_Member:
+ case EK_New:
+ case EK_Temporary:
+ case EK_Base:
+ case EK_ArrayElement:
+ case EK_VectorElement:
+ break;
+ }
+
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Initialization sequence
//===----------------------------------------------------------------------===//
@@ -3242,9 +3262,9 @@ static Sema::OwningExprResult CopyObject(Sema &S,
// directly into the target of the omitted copy/move
//
// Note that the other three bullets are handled elsewhere. Copy
- // elision for return statements and throw expressions are (FIXME:
- // not yet) handled as part of constructor initialization, while
- // copy elision for exception handlers is handled by the run-time.
+ // elision for return statements and throw expressions are handled as part
+ // of constructor initialization, while copy elision for exception handlers
+ // is handled by the run-time.
bool Elidable = CurInitExpr->isTemporaryObject() &&
S.Context.hasSameUnqualifiedType(T, CurInitExpr->getType());
SourceLocation Loc;
@@ -3737,7 +3757,7 @@ InitializationSequence::Perform(Sema &S,
unsigned NumArgs = Args.size();
CXXConstructorDecl *Constructor
= cast<CXXConstructorDecl>(Step->Function.Function);
-
+
// Build a call to the selected constructor.
ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);
SourceLocation Loc = Kind.getLocation();
@@ -3774,11 +3794,21 @@ InitializationSequence::Perform(Sema &S,
CXXConstructExpr::CK_VirtualBase :
CXXConstructExpr::CK_NonVirtualBase;
}
- CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
- Constructor,
- move_arg(ConstructorArgs),
- ConstructorInitRequiresZeroInit,
- ConstructKind);
+
+ // If the entity allows NRVO, mark the construction as elidable
+ // unconditionally.
+ if (Entity.allowsNRVO())
+ CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
+ Constructor, /*Elidable=*/true,
+ move_arg(ConstructorArgs),
+ ConstructorInitRequiresZeroInit,
+ ConstructKind);
+ else
+ CurInit = S.BuildCXXConstructExpr(Loc, Entity.getType(),
+ Constructor,
+ move_arg(ConstructorArgs),
+ ConstructorInitRequiresZeroInit,
+ ConstructKind);
}
if (CurInit.isInvalid())
return S.ExprError();