forked from OSchip/llvm-project
Switch expressions like T() and T(1,2) over to new-style initialization. I'm
not quite sure what we want to do about the AST representation; comments welcome. llvm-svn: 94967
This commit is contained in:
parent
604179775a
commit
a682427e42
|
@ -60,7 +60,7 @@ static bool canDevirtualizeMemberFunctionCalls(const Expr *Base) {
|
|||
}
|
||||
|
||||
// We can always devirtualize calls on temporary object expressions.
|
||||
if (isa<CXXTemporaryObjectExpr>(Base))
|
||||
if (isa<CXXConstructExpr>(Base))
|
||||
return true;
|
||||
|
||||
// And calls on bound temporaries.
|
||||
|
|
|
@ -1924,12 +1924,6 @@ public:
|
|||
bool RequiresZeroInit = false,
|
||||
bool BaseInitialization = false);
|
||||
|
||||
OwningExprResult BuildCXXTemporaryObjectExpr(CXXConstructorDecl *Cons,
|
||||
QualType writtenTy,
|
||||
SourceLocation tyBeginLoc,
|
||||
MultiExprArg Args,
|
||||
SourceLocation rParenLoc);
|
||||
|
||||
OwningExprResult BuildCXXCastArgument(SourceLocation CastLoc,
|
||||
QualType Ty,
|
||||
CastExpr::CastKind Kind,
|
||||
|
@ -1983,14 +1977,6 @@ public:
|
|||
Expr **Args, unsigned NumArgs,
|
||||
SourceLocation Loc,
|
||||
InitializationKind Kind);
|
||||
|
||||
CXXConstructorDecl *
|
||||
PerformInitializationByConstructor(QualType ClassType,
|
||||
MultiExprArg ArgsPtr,
|
||||
SourceLocation Loc, SourceRange Range,
|
||||
DeclarationName InitEntity,
|
||||
InitializationKind Kind,
|
||||
ASTOwningVector<&ActionBase::DeleteExpr> &ConvertedArgs);
|
||||
|
||||
bool CompleteConstructorCall(CXXConstructorDecl *Constructor,
|
||||
MultiExprArg ArgsPtr,
|
||||
|
|
|
@ -3965,22 +3965,6 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
|||
RequiresZeroInit, BaseInitialization));
|
||||
}
|
||||
|
||||
Sema::OwningExprResult
|
||||
Sema::BuildCXXTemporaryObjectExpr(CXXConstructorDecl *Constructor,
|
||||
QualType Ty,
|
||||
SourceLocation TyBeginLoc,
|
||||
MultiExprArg Args,
|
||||
SourceLocation RParenLoc) {
|
||||
unsigned NumExprs = Args.size();
|
||||
Expr **Exprs = (Expr **)Args.release();
|
||||
|
||||
MarkDeclarationReferenced(TyBeginLoc, Constructor);
|
||||
return Owned(new (Context) CXXTemporaryObjectExpr(Context, Constructor, Ty,
|
||||
TyBeginLoc, Exprs,
|
||||
NumExprs, RParenLoc));
|
||||
}
|
||||
|
||||
|
||||
bool Sema::InitializeVarWithConstructor(VarDecl *VD,
|
||||
CXXConstructorDecl *Constructor,
|
||||
MultiExprArg Exprs) {
|
||||
|
@ -4218,92 +4202,6 @@ Sema::TryInitializationByConstructor(QualType ClassType,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Perform initialization by constructor (C++ [dcl.init]p14), which
|
||||
/// may occur as part of direct-initialization or copy-initialization.
|
||||
///
|
||||
/// \param ClassType the type of the object being initialized, which must have
|
||||
/// class type.
|
||||
///
|
||||
/// \param ArgsPtr the arguments provided to initialize the object
|
||||
///
|
||||
/// \param Loc the source location where the initialization occurs
|
||||
///
|
||||
/// \param Range the source range that covers the entire initialization
|
||||
///
|
||||
/// \param InitEntity the name of the entity being initialized, if known
|
||||
///
|
||||
/// \param Kind the type of initialization being performed
|
||||
///
|
||||
/// \param ConvertedArgs a vector that will be filled in with the
|
||||
/// appropriately-converted arguments to the constructor (if initialization
|
||||
/// succeeded).
|
||||
///
|
||||
/// \returns the constructor used to initialize the object, if successful.
|
||||
/// Otherwise, emits a diagnostic and returns NULL.
|
||||
CXXConstructorDecl *
|
||||
Sema::PerformInitializationByConstructor(QualType ClassType,
|
||||
MultiExprArg ArgsPtr,
|
||||
SourceLocation Loc, SourceRange Range,
|
||||
DeclarationName InitEntity,
|
||||
InitializationKind Kind,
|
||||
ASTOwningVector<&ActionBase::DeleteExpr> &ConvertedArgs) {
|
||||
|
||||
// Build the overload candidate set
|
||||
Expr **Args = (Expr **)ArgsPtr.get();
|
||||
unsigned NumArgs = ArgsPtr.size();
|
||||
OverloadCandidateSet CandidateSet;
|
||||
AddConstructorInitializationCandidates(*this, ClassType, Args, NumArgs, Kind,
|
||||
CandidateSet);
|
||||
|
||||
OverloadCandidateSet::iterator Best;
|
||||
switch (BestViableFunction(CandidateSet, Loc, Best)) {
|
||||
case OR_Success:
|
||||
// We found a constructor. Break out so that we can convert the arguments
|
||||
// appropriately.
|
||||
break;
|
||||
|
||||
case OR_No_Viable_Function:
|
||||
if (InitEntity)
|
||||
Diag(Loc, diag::err_ovl_no_viable_function_in_init)
|
||||
<< InitEntity << Range;
|
||||
else
|
||||
Diag(Loc, diag::err_ovl_no_viable_function_in_init)
|
||||
<< ClassType << Range;
|
||||
PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
|
||||
return 0;
|
||||
|
||||
case OR_Ambiguous:
|
||||
if (InitEntity)
|
||||
Diag(Loc, diag::err_ovl_ambiguous_init) << InitEntity << Range;
|
||||
else
|
||||
Diag(Loc, diag::err_ovl_ambiguous_init) << ClassType << Range;
|
||||
PrintOverloadCandidates(CandidateSet, OCD_ViableCandidates, Args, NumArgs);
|
||||
return 0;
|
||||
|
||||
case OR_Deleted:
|
||||
if (InitEntity)
|
||||
Diag(Loc, diag::err_ovl_deleted_init)
|
||||
<< Best->Function->isDeleted()
|
||||
<< InitEntity << Range;
|
||||
else {
|
||||
const CXXRecordDecl *RD =
|
||||
cast<CXXRecordDecl>(ClassType->getAs<RecordType>()->getDecl());
|
||||
Diag(Loc, diag::err_ovl_deleted_init)
|
||||
<< Best->Function->isDeleted()
|
||||
<< RD->getDeclName() << Range;
|
||||
}
|
||||
PrintOverloadCandidates(CandidateSet, OCD_AllCandidates, Args, NumArgs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Convert the arguments, fill in default arguments, etc.
|
||||
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(Best->Function);
|
||||
if (CompleteConstructorCall(Constructor, move(ArgsPtr), Loc, ConvertedArgs))
|
||||
return 0;
|
||||
|
||||
return Constructor;
|
||||
}
|
||||
|
||||
/// \brief Given a constructor and the set of arguments provided for the
|
||||
/// constructor, convert the arguments and add any required default arguments
|
||||
/// to form a proper call to this constructor.
|
||||
|
|
|
@ -263,29 +263,18 @@ Sema::ActOnCXXTypeConstructExpr(SourceRange TypeRange, TypeTy *TypeRep,
|
|||
|
||||
if (NumExprs > 1 || !Record->hasTrivialConstructor() ||
|
||||
!Record->hasTrivialDestructor()) {
|
||||
ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(*this);
|
||||
|
||||
CXXConstructorDecl *Constructor
|
||||
= PerformInitializationByConstructor(Ty, move(exprs),
|
||||
TypeRange.getBegin(),
|
||||
SourceRange(TypeRange.getBegin(),
|
||||
RParenLoc),
|
||||
DeclarationName(),
|
||||
InitializationKind::CreateDirect(TypeRange.getBegin(),
|
||||
LParenLoc,
|
||||
RParenLoc),
|
||||
ConstructorArgs);
|
||||
InitializedEntity Entity = InitializedEntity::InitializeTemporary(Ty);
|
||||
InitializationKind Kind
|
||||
= NumExprs ? InitializationKind::CreateDirect(TypeRange.getBegin(),
|
||||
LParenLoc, RParenLoc)
|
||||
: InitializationKind::CreateValue(TypeRange.getBegin(),
|
||||
LParenLoc, RParenLoc);
|
||||
InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs);
|
||||
OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind,
|
||||
move(exprs));
|
||||
|
||||
if (!Constructor)
|
||||
return ExprError();
|
||||
|
||||
OwningExprResult Result =
|
||||
BuildCXXTemporaryObjectExpr(Constructor, Ty, TyBeginLoc,
|
||||
move_arg(ConstructorArgs), RParenLoc);
|
||||
if (Result.isInvalid())
|
||||
return ExprError();
|
||||
|
||||
return MaybeBindToTemporary(Result.takeAs<Expr>());
|
||||
// FIXME: Improve AST representation?
|
||||
return move(Result);
|
||||
}
|
||||
|
||||
// Fall through to value-initialize an object of class type that
|
||||
|
|
Loading…
Reference in New Issue