diff options
| author | Douglas Gregor <dgregor@apple.com> | 2009-12-16 01:38:02 +0000 |
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2009-12-16 01:38:02 +0000 |
| commit | 85dabae6ad94925a9ec99cdf375c4e8768ea0e03 (patch) | |
| tree | b7b5c40acc05b847924ea8b58179a4ba2d309963 /clang/lib/Sema/SemaExprCXX.cpp | |
| parent | 1be62860283ce4e138f73476be6a7a03c488ae3d (diff) | |
| download | bcm5719-llvm-85dabae6ad94925a9ec99cdf375c4e8768ea0e03.tar.gz bcm5719-llvm-85dabae6ad94925a9ec99cdf375c4e8768ea0e03.zip | |
Switch the C++ new expression over to InitializationSequence, rather
than using its own partial implementation of initialization.
Switched CheckInitializerTypes over to
InitializedEntity/InitializationKind, to help move us closer to
InitializationSequence.
Added InitializedEntity::getName() to retrieve the name of the entity,
for diagnostics that care about such things.
Implemented support for default initialization in
InitializationSequence.
Clean up the determination of the "source expressions" for an
initialization sequence in InitializationSequence::Perform.
Taught CXXConstructExpr to store more location information.
llvm-svn: 91492
Diffstat (limited to 'clang/lib/Sema/SemaExprCXX.cpp')
| -rw-r--r-- | clang/lib/Sema/SemaExprCXX.cpp | 112 |
1 files changed, 54 insertions, 58 deletions
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index d119350a6f5..80b64306540 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -425,74 +425,70 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal, bool Init = ConstructorLParen.isValid(); // --- Choosing a constructor --- - // C++ 5.3.4p15 - // 1) If T is a POD and there's no initializer (ConstructorLParen is invalid) - // the object is not initialized. If the object, or any part of it, is - // const-qualified, it's an error. - // 2) If T is a POD and there's an empty initializer, the object is value- - // initialized. - // 3) If T is a POD and there's one initializer argument, the object is copy- - // constructed. - // 4) If T is a POD and there's more initializer arguments, it's an error. - // 5) If T is not a POD, the initializer arguments are used as constructor - // arguments. - // - // Or by the C++0x formulation: - // 1) If there's no initializer, the object is default-initialized according - // to C++0x rules. - // 2) Otherwise, the object is direct-initialized. CXXConstructorDecl *Constructor = 0; Expr **ConsArgs = (Expr**)ConstructorArgs.get(); - const RecordType *RT; unsigned NumConsArgs = ConstructorArgs.size(); ASTOwningVector<&ActionBase::DeleteExpr> ConvertedConstructorArgs(*this); - if (AllocType->isDependentType() || - Expr::hasAnyTypeDependentArguments(ConsArgs, NumConsArgs)) { - // Skip all the checks. - } else if ((RT = AllocType->getAs<RecordType>()) && - !AllocType->isAggregateType()) { - InitializationKind InitKind = InitializationKind::CreateDefault(TypeLoc); - if (NumConsArgs > 0) - InitKind = InitializationKind::CreateDirect(TypeLoc, - PlacementLParen, - PlacementRParen); - Constructor = PerformInitializationByConstructor( - AllocType, move(ConstructorArgs), - TypeLoc, - SourceRange(TypeLoc, ConstructorRParen), - RT->getDecl()->getDeclName(), - InitKind, - ConvertedConstructorArgs); - if (!Constructor) + if (!AllocType->isDependentType() && + !Expr::hasAnyTypeDependentArguments(ConsArgs, NumConsArgs)) { + // C++0x [expr.new]p15: + // A new-expression that creates an object of type T initializes that + // object as follows: + InitializationKind Kind + // - If the new-initializer is omitted, the object is default- + // initialized (8.5); if no initialization is performed, + // the object has indeterminate value + = !Init? InitializationKind::CreateDefault(TypeLoc) + // - Otherwise, the new-initializer is interpreted according to the + // initialization rules of 8.5 for direct-initialization. + : InitializationKind::CreateDirect(TypeLoc, + ConstructorLParen, + ConstructorRParen); + + // FIXME: We shouldn't have to fake this. + TypeSourceInfo *TInfo + = Context.getTrivialTypeSourceInfo(AllocType, TypeLoc); + InitializedEntity Entity + = InitializedEntity::InitializeTemporary(TInfo->getTypeLoc()); + InitializationSequence InitSeq(*this, Entity, Kind, ConsArgs, NumConsArgs); + + if (!InitSeq) { + InitSeq.Diagnose(*this, Entity, Kind, ConsArgs, NumConsArgs); return ExprError(); + } - // Take the converted constructor arguments and use them for the new - // expression. - NumConsArgs = ConvertedConstructorArgs.size(); - ConsArgs = (Expr **)ConvertedConstructorArgs.take(); - } else { - if (!Init) { - // FIXME: Check that no subpart is const. - if (AllocType.isConstQualified()) - return ExprError(Diag(StartLoc, diag::err_new_uninitialized_const) - << TypeRange); - } else if (NumConsArgs == 0) { - // Object is value-initialized. Do nothing. - } else if (NumConsArgs == 1) { - // Object is direct-initialized. - // FIXME: What DeclarationName do we pass in here? - if (CheckInitializerTypes(ConsArgs[0], AllocType, StartLoc, - DeclarationName() /*AllocType.getAsString()*/, - /*DirectInit=*/true)) - return ExprError(); + OwningExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, + move(ConstructorArgs)); + if (FullInit.isInvalid()) + return ExprError(); + + // FullInit is our initializer; walk through it to determine if it's a + // constructor call, which CXXNewExpr handles directly. + if (Expr *FullInitExpr = (Expr *)FullInit.get()) { + if (CXXBindTemporaryExpr *Binder + = dyn_cast<CXXBindTemporaryExpr>(FullInitExpr)) + FullInitExpr = Binder->getSubExpr(); + if (CXXConstructExpr *Construct + = dyn_cast<CXXConstructExpr>(FullInitExpr)) { + Constructor = Construct->getConstructor(); + for (CXXConstructExpr::arg_iterator A = Construct->arg_begin(), + AEnd = Construct->arg_end(); + A != AEnd; ++A) + ConvertedConstructorArgs.push_back(A->Retain()); + } else { + // Take the converted initializer. + ConvertedConstructorArgs.push_back(FullInit.release()); + } } else { - return ExprError(Diag(StartLoc, - diag::err_builtin_direct_init_more_than_one_arg) - << SourceRange(ConstructorLParen, ConstructorRParen)); + // No initialization required. } + + // Take the converted arguments and use them for the new expression. + NumConsArgs = ConvertedConstructorArgs.size(); + ConsArgs = (Expr **)ConvertedConstructorArgs.take(); } - + // FIXME: Also check that the destructor is accessible. (C++ 5.3.4p16) PlacementArgs.release(); |

