aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaExprCXX.cpp
diff options
context:
space:
mode:
authorSebastian Redl <sebastian.redl@getdesigned.at>2012-02-12 18:41:05 +0000
committerSebastian Redl <sebastian.redl@getdesigned.at>2012-02-12 18:41:05 +0000
commit6dc00f6e98a00bd1c332927c3e04918d7e8b0d4f (patch)
tree89c48828f1a3db02f895af002fea1b3202670def /lib/Sema/SemaExprCXX.cpp
parent215e4e17d00e12c38687a95502506d8f2ca3e646 (diff)
Proper initializer list support for new expressions and type construct expressions. Array new still missing.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@150346 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaExprCXX.cpp')
-rw-r--r--lib/Sema/SemaExprCXX.cpp64
1 files changed, 50 insertions, 14 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index c16d7e2282..c29f8c90aa 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -767,7 +767,6 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
unsigned NumExprs = exprs.size();
Expr **Exprs = (Expr**)exprs.get();
SourceLocation TyBeginLoc = TInfo->getTypeLoc().getBeginLoc();
- SourceRange FullRange = SourceRange(TyBeginLoc, RParenLoc);
if (Ty->isDependentType() ||
CallExpr::hasAnyTypeDependentArguments(Exprs, NumExprs)) {
@@ -779,6 +778,12 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo,
RParenLoc));
}
+ bool ListInitialization = LParenLoc.isInvalid();
+ assert((!ListInitialization || (NumExprs == 1 && isa<InitListExpr>(Exprs[0])))
+ && "List initialization must have initializer list as expression.");
+ SourceRange FullRange = SourceRange(TyBeginLoc,
+ ListInitialization ? Exprs[0]->getSourceRange().getEnd() : RParenLoc);
+
if (Ty->isArrayType())
return ExprError(Diag(TyBeginLoc,
diag::err_value_init_for_array_type) << FullRange);
@@ -872,11 +877,24 @@ static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc,
return (del->getNumParams() == 2);
}
-/// ActOnCXXNew - Parsed a C++ 'new' expression (C++ 5.3.4), as in e.g.:
+/// \brief Parsed a C++ 'new' expression (C++ 5.3.4).
+
+/// E.g.:
/// @code new (memory) int[size][4] @endcode
/// or
/// @code ::new Foo(23, "hello") @endcode
-/// For the interpretation of this heap of arguments, consult the base version.
+///
+/// \param StartLoc The first location of the expression.
+/// \param UseGlobal True if 'new' was prefixed with '::'.
+/// \param PlacementLParen Opening paren of the placement arguments.
+/// \param PlacementArgs Placement new arguments.
+/// \param PlacementRParen Closing paren of the placement arguments.
+/// \param TypeIdParens If the type is in parens, the source range.
+/// \param D The type to be allocated, as well as array dimensions.
+/// \param ConstructorLParen Opening paren of the constructor args, empty if
+/// initializer-list syntax is used.
+/// \param ConstructorArgs Constructor/initialization arguments.
+/// \param ConstructorRParen Closing paren of the constructor args.
ExprResult
Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal,
SourceLocation PlacementLParen, MultiExprArg PlacementArgs,
@@ -968,21 +986,25 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
diag::err_auto_new_ctor_multiple_expressions)
<< AllocType << TypeRange);
}
+ Expr *Deduce = ConstructorArgs.get()[0];
+ if (ConstructorLParen.isInvalid()) {
+ return ExprError(Diag(Deduce->getSourceRange().getBegin(),
+ diag::err_auto_new_requires_parens)
+ << AllocType << TypeRange);
+ }
TypeSourceInfo *DeducedType = 0;
- if (DeduceAutoType(AllocTypeInfo, ConstructorArgs.get()[0], DeducedType) ==
+ if (DeduceAutoType(AllocTypeInfo, Deduce, DeducedType) ==
DAR_Failed)
return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
- << AllocType
- << ConstructorArgs.get()[0]->getType()
- << TypeRange
- << ConstructorArgs.get()[0]->getSourceRange());
+ << AllocType << Deduce->getType()
+ << TypeRange << Deduce->getSourceRange());
if (!DeducedType)
return ExprError();
AllocTypeInfo = DeducedType;
AllocType = AllocTypeInfo->getType();
}
-
+
// Per C++0x [expr.new]p5, the type being constructed may be a
// typedef of an array type.
if (!ArraySize) {
@@ -998,6 +1020,17 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
if (CheckAllocatedType(AllocType, TypeRange.getBegin(), TypeRange))
return ExprError();
+ bool ListInitialization = ConstructorLParen.isInvalid() &&
+ ConstructorArgs.size() > 0;
+ assert((!ListInitialization || (ConstructorArgs.size() == 1 &&
+ isa<InitListExpr>(ConstructorArgs.get()[0])))
+ && "List initialization means a braced-init-list for arguments.");
+ if (ListInitialization && isStdInitializerList(AllocType, 0)) {
+ Diag(AllocTypeInfo->getTypeLoc().getBeginLoc(),
+ diag::warn_dangling_std_initializer_list)
+ << /*at end of FE*/0 << ConstructorArgs.get()[0]->getSourceRange();
+ }
+
// In ARC, infer 'retaining' for the allocated
if (getLangOptions().ObjCAutoRefCount &&
AllocType.getObjCLifetime() == Qualifiers::OCL_None &&
@@ -1153,7 +1186,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
}
}
- bool Init = ConstructorLParen.isValid();
+ bool Init = ConstructorLParen.isValid() || ConstructorArgs.size() > 0;
// --- Choosing a constructor ---
CXXConstructorDecl *Constructor = 0;
bool HadMultipleCandidates = false;
@@ -1172,7 +1205,7 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
if (!AllocType->isDependentType() &&
!Expr::hasAnyTypeDependentArguments(ConsArgs, NumConsArgs)) {
- // C++0x [expr.new]p15:
+ // C++11 [expr.new]p15:
// A new-expression that creates an object of type T initializes that
// object as follows:
InitializationKind Kind
@@ -1182,9 +1215,12 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
= !Init? InitializationKind::CreateDefault(TypeRange.getBegin())
// - Otherwise, the new-initializer is interpreted according to the
// initialization rules of 8.5 for direct-initialization.
- : InitializationKind::CreateDirect(TypeRange.getBegin(),
- ConstructorLParen,
- ConstructorRParen);
+ : ListInitialization ? InitializationKind::CreateDirectList(
+ TypeRange.getBegin())
+ : InitializationKind::CreateDirect(
+ TypeRange.getBegin(),
+ ConstructorLParen,
+ ConstructorRParen);
InitializedEntity Entity
= InitializedEntity::InitializeNew(StartLoc, AllocType);