Switch the initialization required by return statements over to the
new InitializationSequence. This fixes some bugs (e.g., PR5808),
changed some diagnostics, and caused more churn than expected. What's
new:
- InitializationSequence now has a "C conversion sequence" category
and step kind, which falls back to
- Changed the diagnostics for returns to always have the result type
of the function first and the type of the expression second.
CheckSingleAssignmentConstraints to peform checking in C.
- Improved ASTs for initialization of return values. The ASTs now
capture all of the temporaries we need to create, but
intentionally do not bind the tempoary that is actually returned,
so that it won't get destroyed twice.
- Make sure to perform an (elidable!) copy of the class object that
is returned from a class.
- Fix copy elision in CodeGen to properly see through the
subexpressions that occur with elidable copies.
- Give "new" its own entity kind; as with return values and thrown
objects, we don't bind the expression so we don't call a
destructor for it.
Note that, with this patch, I've broken returning move-only types in
C++0x. We'll fix it later, when we tackle NRVO.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91669 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaInit.h b/lib/Sema/SemaInit.h
index da6587b..c42badd 100644
--- a/lib/Sema/SemaInit.h
+++ b/lib/Sema/SemaInit.h
@@ -47,6 +47,9 @@
/// \brief The entity being initialized is an exception object that
/// is being thrown.
EK_Exception,
+ /// \brief The entity being initialized is an object (or array of
+ /// objects) allocated via new.
+ EK_New,
/// \brief The entity being initialized is a temporary object.
EK_Temporary,
/// \brief The entity being initialized is a base member subobject.
@@ -76,9 +79,10 @@
/// the VarDecl, ParmVarDecl, or FieldDecl, respectively.
DeclaratorDecl *VariableOrMember;
- /// \brief When Kind == EK_Result or EK_Exception, the location of the
- /// 'return' or 'throw' keyword, respectively. When Kind == EK_Temporary,
- /// the location where the temporary is being created.
+ /// \brief When Kind == EK_Result, EK_Exception, or EK_New, the
+ /// location of the 'return', 'throw', or 'new' keyword,
+ /// respectively. When Kind == EK_Temporary, the location where
+ /// the temporary is being created.
unsigned Location;
/// \brief When Kind == EK_Base, the base specifier that provides the
@@ -150,6 +154,11 @@
TypeLoc TL) {
return InitializedEntity(EK_Exception, ThrowLoc, TL);
}
+
+ /// \brief Create the initialization entity for an object allocated via new.
+ static InitializedEntity InitializeNew(SourceLocation NewLoc, TypeLoc TL) {
+ return InitializedEntity(EK_New, NewLoc, TL);
+ }
/// \brief Create the initialization entity for a temporary.
static InitializedEntity InitializeTemporary(TypeLoc TL) {
@@ -373,7 +382,10 @@
NoInitialization,
/// \brief Standard conversion sequence.
- StandardConversion
+ StandardConversion,
+
+ /// \brief C conversion sequence.
+ CAssignment
};
/// \brief Describes the kind of a particular step in an initialization
@@ -404,7 +416,9 @@
/// \brief Perform initialization via a constructor.
SK_ConstructorInitialization,
/// \brief Zero-initialize the object
- SK_ZeroInitialization
+ SK_ZeroInitialization,
+ /// \brief C assignment
+ SK_CAssignment
};
/// \brief A single step in the initialization sequence.
@@ -607,6 +621,13 @@
/// \brief Add a zero-initialization step.
void AddZeroInitializationStep(QualType T);
+ /// \brief Add a C assignment step.
+ //
+ // FIXME: It isn't clear whether this should ever be needed;
+ // ideally, we would handle everything needed in C in the common
+ // path. However, that isn't the case yet.
+ void AddCAssignmentStep(QualType T);
+
/// \brief Note that this initialization sequence failed.
void SetFailed(FailureKind Failure) {
SequenceKind = FailedSequence;