Implement the C++0x deduced 'auto' feature.
This fixes PR 8738, 9060 and 9132.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@126069 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 0d48741..f9c2c9a 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -759,11 +759,16 @@
Declarator &D, SourceLocation ConstructorLParen,
MultiExprArg ConstructorArgs,
SourceLocation ConstructorRParen) {
+ bool TypeContainsAuto = D.getDeclSpec().getTypeSpecType() == DeclSpec::TST_auto;
+
Expr *ArraySize = 0;
// If the specified type is an array, unwrap it and save the expression.
if (D.getNumTypeObjects() > 0 &&
D.getTypeObject(0).Kind == DeclaratorChunk::Array) {
DeclaratorChunk &Chunk = D.getTypeObject(0);
+ if (TypeContainsAuto)
+ return ExprError(Diag(Chunk.Loc, diag::err_new_array_of_auto)
+ << D.getSourceRange());
if (Chunk.Arr.hasStatic)
return ExprError(Diag(Chunk.Loc, diag::err_static_illegal_in_new)
<< D.getSourceRange());
@@ -793,14 +798,12 @@
}
}
- TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/0);
+ TypeSourceInfo *TInfo = GetTypeForDeclarator(D, /*Scope=*/0, /*OwnedDecl=*/0,
+ /*AllowAuto=*/true);
QualType AllocType = TInfo->getType();
if (D.isInvalidType())
return ExprError();
- if (!TInfo)
- TInfo = Context.getTrivialTypeSourceInfo(AllocType);
-
return BuildCXXNew(StartLoc, UseGlobal,
PlacementLParen,
move(PlacementArgs),
@@ -811,7 +814,8 @@
ArraySize,
ConstructorLParen,
move(ConstructorArgs),
- ConstructorRParen);
+ ConstructorRParen,
+ TypeContainsAuto);
}
ExprResult
@@ -825,9 +829,33 @@
Expr *ArraySize,
SourceLocation ConstructorLParen,
MultiExprArg ConstructorArgs,
- SourceLocation ConstructorRParen) {
+ SourceLocation ConstructorRParen,
+ bool TypeMayContainAuto) {
SourceRange TypeRange = AllocTypeInfo->getTypeLoc().getSourceRange();
+ // C++0x [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
+ if (TypeMayContainAuto && AllocType->getContainedAutoType()) {
+ if (ConstructorArgs.size() == 0)
+ return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
+ << AllocType << TypeRange);
+ if (ConstructorArgs.size() != 1) {
+ Expr *FirstBad = ConstructorArgs.get()[1];
+ return ExprError(Diag(FirstBad->getSourceRange().getBegin(),
+ diag::err_auto_new_ctor_multiple_expressions)
+ << AllocType << TypeRange);
+ }
+ QualType DeducedType;
+ if (!DeduceAutoType(AllocType, ConstructorArgs.get()[0], DeducedType))
+ return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
+ << AllocType
+ << ConstructorArgs.get()[0]->getType()
+ << TypeRange
+ << ConstructorArgs.get()[0]->getSourceRange());
+
+ AllocType = DeducedType;
+ AllocTypeInfo = Context.getTrivialTypeSourceInfo(AllocType, StartLoc);
+ }
+
// Per C++0x [expr.new]p5, the type being constructed may be a
// typedef of an array type.
if (!ArraySize) {