]> granicus.if.org Git - clang/commitdiff
Minor fixups for auto deduction of initializer lists.
authorSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 23 Jan 2012 22:09:39 +0000 (22:09 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 23 Jan 2012 22:09:39 +0000 (22:09 +0000)
Fix some review comments.
Add a test for deduction when std::initializer_list isn't available yet.
Fix redundant error messages. This fixes and outstanding FIXME too.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@148735 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Sema/Sema.h
lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
lib/Sema/SemaExprCXX.cpp
lib/Sema/SemaOverload.cpp
lib/Sema/SemaStmt.cpp
lib/Sema/SemaTemplateDeduction.cpp
test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
test/SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
test/SemaObjCXX/properties.mm

index 754b2906b3ef3ebdafd4b8768ed5aaedb300b0db..309d191aa9444cb92f645bd4e3c6568a61015855 100644 (file)
@@ -4644,8 +4644,15 @@ public:
                           FunctionDecl *&Specialization,
                           sema::TemplateDeductionInfo &Info);
 
-  bool DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer,
-                      TypeSourceInfo *&Result);
+  /// \brief Result type of DeduceAutoType.
+  enum DeduceAutoResult {
+    DAR_Succeeded,
+    DAR_Failed,
+    DAR_FailedAlreadyDiagnosed
+  };
+
+  DeduceAutoResult DeduceAutoType(TypeSourceInfo *AutoType, Expr *&Initializer,
+                                  TypeSourceInfo *&Result);
   void DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init);
 
   FunctionTemplateDecl *getMoreSpecializedTemplate(FunctionTemplateDecl *FT1,
index 696e84234cd2f66f0c7f39fbfb045da5ebca55c3..980c59c4c94b12261d34b6a79b0fe455819162f5 100644 (file)
@@ -6011,7 +6011,8 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
   // C++11 [decl.spec.auto]p6. Deduce the type which 'auto' stands in for.
   if (TypeMayContainAuto && VDecl->getType()->getContainedAutoType()) {
     TypeSourceInfo *DeducedType = 0;
-    if (!DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType))
+    if (DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType) ==
+            DAR_Failed)
       DiagnoseAutoDeductionFailure(VDecl, Init);
     if (!DeducedType) {
       RealDecl->setInvalidDecl();
index 983e815f60441f6f7856cd50fc49883e3d66ce02..b706cdc9fba86ed6a9416b8e10362d6450b48304 100644 (file)
@@ -5809,12 +5809,13 @@ bool Sema::isStdInitializerList(QualType Ty, QualType *Element) {
     CXXRecordDecl *TemplateClass = Template->getTemplatedDecl();
     if (TemplateClass->getIdentifier() !=
             &PP.getIdentifierTable().get("initializer_list") ||
-        !TemplateClass->getDeclContext()->Equals(getStdNamespace()))
+        !getStdNamespace()->InEnclosingNamespaceSetOf(
+            TemplateClass->getDeclContext()))
       return false;
     // This is a template called std::initializer_list, but is it the right
     // template?
     TemplateParameterList *Params = Template->getTemplateParameters();
-    if (Params->size() != 1)
+    if (Params->getMinRequiredArguments() != 1)
       return false;
     if (!isa<TemplateTypeParmDecl>(Params->getParam(0)))
       return false;
@@ -5857,7 +5858,8 @@ static ClassTemplateDecl *LookupStdInitializerList(Sema &S, SourceLocation Loc){
   // 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))) {
+  if (Params->getMinRequiredArguments() != 1 ||
+      !isa<TemplateTypeParmDecl>(Params->getParam(0))) {
     S.Diag(Template->getLocation(), diag::err_malformed_std_initializer_list);
     return 0;
   }
@@ -9102,7 +9104,8 @@ void Sema::AddCXXDirectInitializerToDecl(Decl *RealDecl,
 
     Expr *Init = Exprs.get()[0];
     TypeSourceInfo *DeducedType = 0;
-    if (!DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType))
+    if (DeduceAutoType(VDecl->getTypeSourceInfo(), Init, DeducedType) ==
+            DAR_Failed)
       DiagnoseAutoDeductionFailure(VDecl, Init);
     if (!DeducedType) {
       RealDecl->setInvalidDecl();
index 3d155a5cf3a7323d0b8a467c3add94bac6de7dc3..bea0954c6f099ce377cd58d9c5efa35b7fc8f128 100644 (file)
@@ -952,7 +952,8 @@ Sema::BuildCXXNew(SourceLocation StartLoc, bool UseGlobal,
                        << AllocType << TypeRange);
     }
     TypeSourceInfo *DeducedType = 0;
-    if (!DeduceAutoType(AllocTypeInfo, ConstructorArgs.get()[0], DeducedType))
+    if (DeduceAutoType(AllocTypeInfo, ConstructorArgs.get()[0], DeducedType) ==
+            DAR_Failed)
       return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
                        << AllocType
                        << ConstructorArgs.get()[0]->getType()
index 931573bb296864a496bf43406977533182be0683..fac3c26d0e3abced2761d65f9b1a21c21b816d45 100644 (file)
@@ -4111,7 +4111,7 @@ TryListConversion(Sema &S, InitListExpr *From, QualType ToType,
   Result.setBad(BadConversionSequence::no_conversion, From, ToType);
   Result.setListInitializationSequence();
 
-  // We need a complete type for what follows. Incomplete types can bever be
+  // We need a complete type for what follows. Incomplete types can never be
   // initialized from init lists.
   if (S.RequireCompleteType(From->getLocStart(), ToType, S.PDiag()))
     return Result;
index 2d843393a2ee22be31a2b6998ed36feb331d46f9..86bb74040ae51adff620e58945a60246531b92f1 100644 (file)
@@ -1201,7 +1201,8 @@ static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init,
   // AddInitializerToDecl, so we can produce a more suitable diagnostic.
   TypeSourceInfo *InitTSI = 0;
   if ((!isa<InitListExpr>(Init) && Init->getType()->isVoidType()) ||
-      !SemaRef.DeduceAutoType(Decl->getTypeSourceInfo(), Init, InitTSI))
+      SemaRef.DeduceAutoType(Decl->getTypeSourceInfo(), Init, InitTSI) ==
+          Sema::DAR_Failed)
     SemaRef.Diag(Loc, diag) << Init->getType();
   if (!InitTSI) {
     Decl->setInvalidDecl();
index 0d74f24f4d75ba447d2e14052e1206e848a18d9e..adc6994fb0d56a5f19dd31a8adc1c61225eb1085 100644 (file)
@@ -3376,20 +3376,18 @@ namespace {
 /// dependent. This will be set to null if deduction succeeded, but auto
 /// substitution failed; the appropriate diagnostic will already have been
 /// produced in that case.
-///
-/// \returns true if deduction succeeded, false if it failed.
-bool
+Sema::DeduceAutoResult
 Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init,
                      TypeSourceInfo *&Result) {
   if (Init->getType()->isNonOverloadPlaceholderType()) {
     ExprResult result = CheckPlaceholderExpr(Init);
-    if (result.isInvalid()) return false;
+    if (result.isInvalid()) return DAR_FailedAlreadyDiagnosed;
     Init = result.take();
   }
 
   if (Init->isTypeDependent()) {
     Result = Type;
-    return true;
+    return DAR_Succeeded;
   }
 
   SourceLocation Loc = Init->getExprLoc();
@@ -3418,7 +3416,7 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init,
   if (AdjustFunctionParmAndArgTypesForDeduction(*this, &TemplateParams,
                                                 FuncParam, InitType, Init,
                                                 TDF))
-    return false;
+    return DAR_Failed;
 
   TemplateDeductionInfo Info(Context, Loc);
 
@@ -3428,22 +3426,22 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init,
       if (DeduceTemplateArgumentsByTypeMatch(*this, &TemplateParams, FuncParam,
                                              InitList->getInit(i)->getType(),
                                              Info, Deduced, TDF))
-        return false;
+        return DAR_Failed;
     }
   } else {
     if (DeduceTemplateArgumentsByTypeMatch(*this, &TemplateParams, FuncParam,
                                            InitType, Info, Deduced, TDF))
-      return false;
+      return DAR_Failed;
   }
 
   QualType DeducedType = Deduced[0].getAsType();
   if (DeducedType.isNull())
-    return false;
+    return DAR_Failed;
 
   if (InitList) {
     DeducedType = BuildStdInitializerList(DeducedType, Loc);
     if (DeducedType.isNull())
-      return false;
+      return DAR_FailedAlreadyDiagnosed;
   }
 
   Result = SubstituteAutoTransform(*this, DeducedType).TransformType(Type);
@@ -3455,10 +3453,10 @@ Sema::DeduceAutoType(TypeSourceInfo *Type, Expr *&Init,
                                     Sema::OriginalCallArg(FuncParam,0,InitType),
                                     Result->getType())) {
     Result = 0;
-    return false;
+    return DAR_Failed;
   }
 
-  return true;
+  return DAR_Succeeded;
 }
 
 void Sema::DiagnoseAutoDeductionFailure(VarDecl *VDecl, Expr *Init) {
index aa22b8f56bb94884fe16e0245b79ac4d1544c4fb..d327efcc20df5d6deceb0997d88658243f994714 100644 (file)
@@ -92,8 +92,7 @@ namespace PR10939 {
   template<typename T> T g(T);
 
   void f(X *x) {
-    // FIXME: we should really only get the first diagnostic here.
-    auto value = x->method; // expected-error {{reference to non-static member function must be called}} expected-error{{variable 'value' with type 'auto' has incompatible initializer of type '<bound member function type>'}}
+    auto value = x->method; // expected-error {{reference to non-static member function must be called}}
     if (value) { }
 
     auto funcptr = &g<int>;
@@ -101,4 +100,5 @@ namespace PR10939 {
   }
 }
 
-// TODO: if the initializer is a braced-init-list, deduce auto as std::initializer_list<T>.
+// if the initializer is a braced-init-list, deduce auto as std::initializer_list<T>:
+// see SemaCXX/cxx0x-initializer-stdinitializerlist.cpp
index 47ceaf0b83c813623491a18392beaa553d4dc50f..fe3cd8fc3a13c4f2a369f7f4d7f476f2aabf1984 100644 (file)
@@ -1,5 +1,10 @@
 // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
 
+// This must obviously come before the definition of std::initializer_list.
+void missing_initializerlist() {
+  auto l = {1, 2, 3, 4}; // expected-error {{std::initializer_list was not found}}
+}
+
 namespace std {
   typedef decltype(sizeof(int)) size_t;
 
index d8d92e568796519262f0e307f27243f3bc4fb947..ac780c023bf5bf2bc02a7c4ae562103d9e71583c 100644 (file)
@@ -28,7 +28,7 @@ struct X {
 - (int) z;
 @end
 void test2(Test2 *a) {
-  auto y = a.y; // expected-error {{expected getter method not found on object of type 'Test2 *'}} expected-error {{variable 'y' with type 'auto' has incompatible initializer of type}}
+  auto y = a.y; // expected-error {{expected getter method not found on object of type 'Test2 *'}}
   auto z = a.z;
 }