summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp4
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp52
-rw-r--r--clang/lib/Sema/SemaStmt.cpp2
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp40
4 files changed, 85 insertions, 13 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 0e99f704768..61e104fd1d2 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -5976,9 +5976,7 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
TypeSourceInfo *DeducedType = 0;
if (!DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType))
- Diag(VDecl->getLocation(), diag::err_auto_var_deduction_failure)
- << VDecl->getDeclName() << VDecl->getType() << Init->getType()
- << Init->getSourceRange();
+ DiagnoseAutoDeductionFailure(VDecl, Init);
if (!DeducedType) {
RealDecl->setInvalidDecl();
return;
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 13face95e95..2d47e0e3e89 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -5829,6 +5829,54 @@ bool Sema::isStdInitializerList(QualType Ty, QualType *Element) {
return true;
}
+static ClassTemplateDecl *LookupStdInitializerList(Sema &S, SourceLocation Loc){
+ NamespaceDecl *Std = S.getStdNamespace();
+ if (!Std) {
+ S.Diag(Loc, diag::err_implied_std_initializer_list_not_found);
+ return 0;
+ }
+
+ LookupResult Result(S, &S.PP.getIdentifierTable().get("initializer_list"),
+ Loc, Sema::LookupOrdinaryName);
+ if (!S.LookupQualifiedName(Result, Std)) {
+ S.Diag(Loc, diag::err_implied_std_initializer_list_not_found);
+ return 0;
+ }
+ ClassTemplateDecl *Template = Result.getAsSingle<ClassTemplateDecl>();
+ if (!Template) {
+ Result.suppressDiagnostics();
+ // We found something weird. Complain about the first thing we found.
+ NamedDecl *Found = *Result.begin();
+ S.Diag(Found->getLocation(), diag::err_malformed_std_initializer_list);
+ return 0;
+ }
+
+ // We found some template called std::initializer_list. Now verify that it's
+ // correct.
+ TemplateParameterList *Params = Template->getTemplateParameters();
+ if (Params->size() != 1 || !isa<TemplateTypeParmDecl>(Params->getParam(0))) {
+ S.Diag(Template->getLocation(), diag::err_malformed_std_initializer_list);
+ return 0;
+ }
+
+ return Template;
+}
+
+QualType Sema::BuildStdInitializerList(QualType Element, SourceLocation Loc) {
+ if (!StdInitializerList) {
+ StdInitializerList = LookupStdInitializerList(*this, Loc);
+ if (!StdInitializerList)
+ return QualType();
+ }
+
+ TemplateArgumentListInfo Args(Loc, Loc);
+ Args.addArgument(TemplateArgumentLoc(TemplateArgument(Element),
+ Context.getTrivialTypeSourceInfo(Element,
+ Loc)));
+ return Context.getCanonicalType(
+ CheckTemplateIdType(TemplateName(StdInitializerList), Loc, Args));
+}
+
/// \brief Determine whether a using statement is in a context where it will be
/// apply in all contexts.
static bool IsUsingDirectiveInToplevelContext(DeclContext *CurContext) {
@@ -9027,9 +9075,7 @@ void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl,
Expr *Init = Exprs.get()[0];
TypeSourceInfo *DeducedType = 0;
if (!DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType))
- Diag(VDecl->getLocation(), diag::err_auto_var_deduction_failure)
- << VDecl->getDeclName() << VDecl->getType() << Init->getType()
- << Init->getSourceRange();
+ DiagnoseAutoDeductionFailure(VDecl, Init);
if (!DeducedType) {
RealDecl->setInvalidDecl();
return;
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 78a58964db3..23dc7e9d20a 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -1164,7 +1164,7 @@ static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init,
// Deduce the type for the iterator variable now rather than leaving it to
// AddInitializerToDecl, so we can produce a more suitable diagnostic.
TypeSourceInfo *InitTSI = 0;
- if (Init->getType()->isVoidType() ||
+ if ((!isa<InitListExpr>(Init) && Init->getType()->isVoidType()) ||
!SemaRef.DeduceAutoType(Decl->getTypeSourceInfo(), Init, InitTSI))
SemaRef.Diag(Loc, diag) << Init->getType();
if (!InitTSI) {
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 738e596ef38..4fff827206c 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3422,19 +3422,36 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init,
return false;
TemplateDeductionInfo Info(Context, Loc);
- if (DeduceTemplateArgumentsByTypeMatch(*this, &TemplateParams, FuncParam,
- InitType, Info, Deduced, TDF))
- return false;
+
+ InitListExpr * InitList = dyn_cast<InitListExpr>(Init);
+ if (InitList) {
+ for (unsigned i = 0, e = InitList->getNumInits(); i < e; ++i) {
+ if (DeduceTemplateArgumentsByTypeMatch(*this, &TemplateParams, FuncParam,
+ InitList->getInit(i)->getType(),
+ Info, Deduced, TDF))
+ return false;
+ }
+ } else {
+ if (DeduceTemplateArgumentsByTypeMatch(*this, &TemplateParams, FuncParam,
+ InitType, Info, Deduced, TDF))
+ return false;
+ }
QualType DeducedType = Deduced[0].getAsType();
if (DeducedType.isNull())
return false;
-
+
+ if (InitList) {
+ DeducedType = BuildStdInitializerList(DeducedType, Loc);
+ if (DeducedType.isNull())
+ return false;
+ }
+
Result = SubstituteAutoTransform(*this, DeducedType).TransformType(Type);
-
+
// Check that the deduced argument type is compatible with the original
// argument type per C++ [temp.deduct.call]p4.
- if (Result &&
+ if (!InitList && Result &&
CheckOriginalCallArgDeduction(*this,
Sema::OriginalCallArg(FuncParam,0,InitType),
Result->getType())) {
@@ -3445,6 +3462,17 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init,
return true;
}
+void Sema::DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init) {
+ if (isa<InitListExpr>(Init))
+ Diag(VDecl->getLocation(),
+ diag::err_auto_var_deduction_failure_from_init_list)
+ << VDecl->getDeclName() << VDecl->getType() << Init->getSourceRange();
+ else
+ Diag(VDecl->getLocation(), diag::err_auto_var_deduction_failure)
+ << VDecl->getDeclName() << VDecl->getType() << Init->getType()
+ << Init->getSourceRange();
+}
+
static void
MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
bool OnlyDeduced,
OpenPOWER on IntegriCloud