diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 67 | ||||
-rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 8 |
3 files changed, 41 insertions, 36 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 2d86b5e1b67..87a33642a0f 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1985,7 +1985,7 @@ public: /// non-empty, will create a new CXXExprWithTemporaries expression. /// Otherwise, just returs the passed in expression. Expr *MaybeCreateCXXExprWithTemporaries(Expr *SubExpr); - + OwningExprResult MaybeCreateCXXExprWithTemporaries(OwningExprResult SubExpr); FullExpr CreateFullExpr(Expr *SubExpr); virtual OwningExprResult ActOnFinishFullExpr(ExprArg Expr); diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index dfb35328105..9e30af8f187 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -3927,53 +3927,50 @@ void Sema::AddCXXDirectInitializerToDecl(DeclPtrTy Dcl, if (const ArrayType *Array = Context.getAsArrayType(DeclInitType)) DeclInitType = Context.getBaseElementType(Array); - // FIXME: This isn't the right place to complete the type. if (RequireCompleteType(VDecl->getLocation(), VDecl->getType(), diag::err_typecheck_decl_incomplete_type)) { VDecl->setInvalidDecl(); return; } - if (VDecl->getType()->isRecordType()) { - ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(*this); - - CXXConstructorDecl *Constructor - = PerformInitializationByConstructor(DeclInitType, - move(Exprs), - VDecl->getLocation(), - SourceRange(VDecl->getLocation(), - RParenLoc), - VDecl->getDeclName(), - InitializationKind::CreateDirect(VDecl->getLocation(), - LParenLoc, - RParenLoc), - ConstructorArgs); - if (!Constructor) - RealDecl->setInvalidDecl(); - else { - VDecl->setCXXDirectInitializer(true); - if (InitializeVarWithConstructor(VDecl, Constructor, - move_arg(ConstructorArgs))) - RealDecl->setInvalidDecl(); - FinalizeVarWithDestructor(VDecl, DeclInitType); - } + // The variable can not have an abstract class type. + if (RequireNonAbstractType(VDecl->getLocation(), VDecl->getType(), + diag::err_abstract_type_in_decl, + AbstractVariableType)) + VDecl->setInvalidDecl(); + + const VarDecl *Def = 0; + if (VDecl->getDefinition(Def)) { + Diag(VDecl->getLocation(), diag::err_redefinition) + << VDecl->getDeclName(); + Diag(Def->getLocation(), diag::note_previous_definition); + VDecl->setInvalidDecl(); return; } - - if (NumExprs > 1) { - Diag(CommaLocs[0], diag::err_builtin_direct_init_more_than_one_arg) - << SourceRange(VDecl->getLocation(), RParenLoc); - RealDecl->setInvalidDecl(); + + // Capture the variable that is being initialized and the style of + // initialization. + InitializedEntity Entity = InitializedEntity::InitializeVariable(VDecl); + + // FIXME: Poor source location information. + InitializationKind Kind + = InitializationKind::CreateDirect(VDecl->getLocation(), + LParenLoc, RParenLoc); + + InitializationSequence InitSeq(*this, Entity, Kind, + (Expr**)Exprs.get(), Exprs.size()); + OwningExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(Exprs)); + if (Result.isInvalid()) { + VDecl->setInvalidDecl(); return; } - - // Let clients know that initialization was done with a direct initializer. + + Result = MaybeCreateCXXExprWithTemporaries(move(Result)); + VDecl->setInit(Context, Result.takeAs<Expr>()); VDecl->setCXXDirectInitializer(true); - assert(NumExprs == 1 && "Expected 1 expression"); - // Set the init expression, handles conversions. - AddInitializerToDecl(Dcl, ExprArg(*this, Exprs.release()[0]), - /*DirectInit=*/true); + if (VDecl->getType()->getAs<RecordType>()) + FinalizeVarWithDestructor(VDecl, DeclInitType); } /// \brief Add the applicable constructor candidates for an initialization diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 92a94daea6f..dd3d2ea2ce4 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -2097,6 +2097,14 @@ Expr *Sema::MaybeCreateCXXExprWithTemporaries(Expr *SubExpr) { return E; } +Sema::OwningExprResult +Sema::MaybeCreateCXXExprWithTemporaries(OwningExprResult SubExpr) { + if (SubExpr.isInvalid()) + return ExprError(); + + return Owned(MaybeCreateCXXExprWithTemporaries(SubExpr.takeAs<Expr>())); +} + FullExpr Sema::CreateFullExpr(Expr *SubExpr) { unsigned FirstTemporary = ExprEvalContexts.back().NumTemporaries; assert(ExprTemporaries.size() >= FirstTemporary); |