This revision was automatically updated to reflect the committed changes.
Closed by commit rL293473: Revert r293455, which breaks v8 with a spurious 
error. Testcase added. (authored by sammccall).

Changed prior to commit:
  https://reviews.llvm.org/D29271?vs=86257&id=86259#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D29271

Files:
  cfe/trunk/include/clang/AST/DeclTemplate.h
  cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
  cfe/trunk/include/clang/Sema/Sema.h
  cfe/trunk/lib/Sema/SemaDecl.cpp
  cfe/trunk/lib/Sema/SemaTemplate.cpp
  cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
  cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
  cfe/trunk/lib/Sema/TreeTransform.h
  cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp
  cfe/trunk/test/SemaCXX/cxx0x-class.cpp

Index: cfe/trunk/include/clang/AST/DeclTemplate.h
===================================================================
--- cfe/trunk/include/clang/AST/DeclTemplate.h
+++ cfe/trunk/include/clang/AST/DeclTemplate.h
@@ -2946,16 +2946,6 @@
   return P.get<TemplateTemplateParmDecl*>();
 }
 
-inline TemplateDecl *getAsTypeTemplateDecl(Decl *D) {
-  auto *TD = dyn_cast<TemplateDecl>(D);
-  return TD && (isa<ClassTemplateDecl>(TD) ||
-                isa<ClassTemplatePartialSpecializationDecl>(TD) ||
-                isa<TypeAliasTemplateDecl>(TD) ||
-                isa<TemplateTemplateParmDecl>(TD))
-             ? TD
-             : nullptr;
-}
-
 } /* end of namespace clang */
 
 #endif
Index: cfe/trunk/include/clang/Sema/Sema.h
===================================================================
--- cfe/trunk/include/clang/Sema/Sema.h
+++ cfe/trunk/include/clang/Sema/Sema.h
@@ -7359,8 +7359,7 @@
 
   TypeSourceInfo *SubstType(TypeSourceInfo *T,
                             const MultiLevelTemplateArgumentList &TemplateArgs,
-                            SourceLocation Loc, DeclarationName Entity,
-                            bool AllowDeducedTST = false);
+                            SourceLocation Loc, DeclarationName Entity);
 
   QualType SubstType(QualType T,
                      const MultiLevelTemplateArgumentList &TemplateArgs,
Index: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1884,11 +1884,6 @@
   "|in conversion function type|here|in lambda parameter"
   "|in type allocated by 'new'|in K&R-style function parameter"
   "|in template parameter|in friend declaration}1">;
-def err_dependent_deduced_tst : Error<
-  "typename specifier refers to "
-  "%select{class template|function template|variable template|alias template|"
-  "template template parameter|template}0 member in %1; "
-  "argument deduction not allowed here">;
 def err_auto_not_allowed_var_inst : Error<
   "'auto' variable template instantiation is not allowed">;
 def err_auto_var_requires_init : Error<
Index: cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp
===================================================================
--- cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp
+++ cfe/trunk/test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -std=c++1z -fcxx-exceptions -verify %s
 
-template<typename T> struct A {}; // expected-note 35{{declared here}}
+template<typename T> struct A {}; // expected-note 31{{declared here}}
 
 // Make sure we still correctly parse cases where a template can appear without arguments.
 namespace template_template_arg {
@@ -101,8 +101,6 @@
     (void)reinterpret_cast<A*>(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
     (void)const_cast<A>(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
     (void)*(A*)(&n); // expected-error{{requires template arguments; argument deduction not allowed here}}
-    (void)(A)(n); // expected-error{{requires template arguments; argument deduction not allowed here}}
-    (void)(A){n}; // expected-error{{requires template arguments; argument deduction not allowed here}}
 
     (void)A(n); // expected-error {{not yet supported}}
     (void)A{n}; // expected-error {{not yet supported}}
@@ -123,66 +121,11 @@
 
   A a; // expected-error {{requires an initializer}}
   A b = 0; // expected-error {{not yet supported}}
-  const A c = 0; // expected-error {{not yet supported}}
   A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
   A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
   A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
   A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
   A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
   A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
   A [x, y] = 0; // expected-error {{cannot be declared with type 'A'}} expected-error {{not yet supported}}
 }
-
-namespace typename_specifier {
-  struct F {};
-
-  void e() {
-    (void) typename ::A(0); // expected-error {{not yet supported}}
-    (void) typename ::A{0}; // expected-error {{not yet supported}}
-    new typename ::A(0); // expected-error {{not yet supported}}
-    new typename ::A{0}; // expected-error {{not yet supported}}
-    typename ::A a = 0; // expected-error {{not yet supported}}
-    const typename ::A b = 0; // expected-error {{not yet supported}}
-    if (typename ::A a = 0) {} // expected-error {{not yet supported}}
-    for (typename ::A a = 0; typename ::A b = 0; /**/) {} // expected-error 2{{not yet supported}}
-
-    (void)(typename ::A)(0); // expected-error{{requires template arguments; argument deduction not allowed here}}
-    (void)(typename ::A){0}; // expected-error{{requires template arguments; argument deduction not allowed here}}
-  }
-  typename ::A a = 0; // expected-error {{not yet supported}}
-  const typename ::A b = 0; // expected-error {{not yet supported}}
-  typename ::A (parens) = 0; // expected-error {{cannot use parentheses when declaring variable with deduced class template specialization type}}
-  typename ::A *p = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
-  typename ::A &r = *p; // expected-error {{cannot form reference to deduced class template specialization type}}
-  typename ::A arr[3] = 0; // expected-error {{cannot form array of deduced class template specialization type}}
-  typename ::A F::*pm = 0; // expected-error {{cannot form pointer to deduced class template specialization type}}
-  typename ::A (*fp)() = 0; // expected-error {{cannot form function returning deduced class template specialization type}}
-  typename ::A [x, y] = 0; // expected-error {{cannot be declared with type 'typename ::A'}} expected-error {{not yet supported}}
-
-  struct X { template<typename T> struct A {}; }; // expected-note 8{{template}}
-
-  template<typename T> void f() {
-    (void) typename T::A(0); // expected-error {{not yet supported}}
-    (void) typename T::A{0}; // expected-error {{not yet supported}}
-    new typename T::A(0); // expected-error {{not yet supported}}
-    new typename T::A{0}; // expected-error {{not yet supported}}
-    typename T::A a = 0; // expected-error {{not yet supported}}
-    const typename T::A b = 0; // expected-error {{not yet supported}}
-    if (typename T::A a = 0) {} // expected-error {{not yet supported}}
-    for (typename T::A a = 0; typename T::A b = 0; /**/) {} // expected-error 2{{not yet supported}}
-
-    {(void)(typename T::A)(0);} // expected-error{{refers to class template member}}
-    {(void)(typename T::A){0};} // expected-error{{refers to class template member}}
-    {typename T::A (parens) = 0;} // expected-error {{refers to class template member in 'typename_specifier::X'; argument deduction not allowed here}}
-    {typename T::A *p = 0;} // expected-error {{refers to class template member}}
-    {typename T::A &r = *p;} // expected-error {{refers to class template member}}
-    {typename T::A arr[3] = 0;} // expected-error {{refers to class template member}}
-    {typename T::A F::*pm = 0;} // expected-error {{refers to class template member}}
-    {typename T::A (*fp)() = 0;} // expected-error {{refers to class template member}}
-    {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{not yet supported}}
-  }
-  template void f<X>(); // expected-note {{instantiation of}}
-
-  template<typename T> void g(typename T::A = 0); // expected-note {{refers to class template member}}
-  void h() { g<X>(); } // expected-error {{no matching function}}
-}
Index: cfe/trunk/test/SemaCXX/cxx0x-class.cpp
===================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-class.cpp
+++ cfe/trunk/test/SemaCXX/cxx0x-class.cpp
@@ -45,3 +45,11 @@
   DefaultMemberTemplate<int> t = {};
   int *p = &t.n;
 };
+
+namespace composed_templates {
+  // Regression test -- obtaining the type from composed templates should not
+  // require out-of-line definition.
+  template <typename T> struct Zero { static const typename T::type value = 0; };
+  struct Integer { using type = int; };
+  template struct Zero<Integer>;
+}
Index: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1490,16 +1490,12 @@
 /// a cast expression) or that the entity has no name (e.g., an
 /// unnamed function parameter).
 ///
-/// \param AllowDeducedTST Whether a DeducedTemplateSpecializationType is
-/// acceptable as the top level type of the result.
-///
 /// \returns If the instantiation succeeds, the instantiated
 /// type. Otherwise, produces diagnostics and returns a NULL type.
 TypeSourceInfo *Sema::SubstType(TypeSourceInfo *T,
                                 const MultiLevelTemplateArgumentList &Args,
                                 SourceLocation Loc,
-                                DeclarationName Entity,
-                                bool AllowDeducedTST) {
+                                DeclarationName Entity) {
   assert(!ActiveTemplateInstantiations.empty() &&
          "Cannot perform an instantiation without some context on the "
          "instantiation stack");
@@ -1509,8 +1505,7 @@
     return T;
 
   TemplateInstantiator Instantiator(*this, Args, Loc, Entity);
-  return AllowDeducedTST ? Instantiator.TransformTypeWithDeducedTST(T)
-                         : Instantiator.TransformType(T);
+  return Instantiator.TransformType(T);
 }
 
 TypeSourceInfo *Sema::SubstType(TypeLoc TL,
Index: cfe/trunk/lib/Sema/SemaTemplate.cpp
===================================================================
--- cfe/trunk/lib/Sema/SemaTemplate.cpp
+++ cfe/trunk/lib/Sema/SemaTemplate.cpp
@@ -8792,18 +8792,8 @@
                                        Context.getTypeDeclType(Type));
     }
 
-    // C++ [dcl.type.simple]p2:
-    //   A type-specifier of the form
-    //     typename[opt] nested-name-specifier[opt] template-name
-    //   is a placeholder for a deduced class type [...].
-    if (getLangOpts().CPlusPlus1z) {
-      if (auto *TD = getAsTypeTemplateDecl(Result.getFoundDecl())) {
-        return Context.getElaboratedType(
-            Keyword, QualifierLoc.getNestedNameSpecifier(),
-            Context.getDeducedTemplateSpecializationType(TemplateName(TD),
-                                                         QualType(), false));
-      }
-    }
+    // FIXME: Form a deduced template specialization type if we get a template
+    // declaration here.
 
     DiagID = diag::err_typename_nested_not_type;
     Referenced = Result.getFoundDecl();
Index: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
===================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -657,9 +657,10 @@
                                              ArrayRef<BindingDecl*> *Bindings) {
 
   // Do substitution on the type of the declaration
-  TypeSourceInfo *DI = SemaRef.SubstType(
-      D->getTypeSourceInfo(), TemplateArgs, D->getTypeSpecStartLoc(),
-      D->getDeclName(), /*AllowDeducedTST*/true);
+  TypeSourceInfo *DI = SemaRef.SubstType(D->getTypeSourceInfo(),
+                                         TemplateArgs,
+                                         D->getTypeSpecStartLoc(),
+                                         D->getDeclName());
   if (!DI)
     return nullptr;
 
Index: cfe/trunk/lib/Sema/SemaDecl.cpp
===================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp
+++ cfe/trunk/lib/Sema/SemaDecl.cpp
@@ -60,6 +60,11 @@
   return DeclGroupPtrTy::make(DeclGroupRef(Ptr));
 }
 
+static bool isTypeTemplate(NamedDecl *ND) {
+  return isa<ClassTemplateDecl>(ND) || isa<TypeAliasTemplateDecl>(ND) ||
+         isa<TemplateTemplateParmDecl>(ND);
+}
+
 namespace {
 
 class TypeNameValidatorCCC : public CorrectionCandidateCallback {
@@ -76,7 +81,7 @@
   bool ValidateCandidate(const TypoCorrection &candidate) override {
     if (NamedDecl *ND = candidate.getCorrectionDecl()) {
       bool IsType = isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
-      bool AllowedTemplate = AllowTemplates && getAsTypeTemplateDecl(ND);
+      bool AllowedTemplate = AllowTemplates && isTypeTemplate(ND);
       return (IsType || AllowedTemplate) &&
              (AllowInvalidDecl || !ND->isInvalidDecl());
     }
@@ -400,7 +405,7 @@
     for (LookupResult::iterator Res = Result.begin(), ResEnd = Result.end();
          Res != ResEnd; ++Res) {
       if (isa<TypeDecl>(*Res) || isa<ObjCInterfaceDecl>(*Res) ||
-          (AllowDeducedTemplate && getAsTypeTemplateDecl(*Res))) {
+          (AllowDeducedTemplate && isTypeTemplate(*Res))) {
         if (!IIDecl ||
             (*Res)->getLocation().getRawEncoding() <
               IIDecl->getLocation().getRawEncoding())
@@ -453,10 +458,9 @@
     (void)DiagnoseUseOfDecl(IDecl, NameLoc);
     if (!HasTrailingDot)
       T = Context.getObjCInterfaceType(IDecl);
-  } else if (AllowDeducedTemplate) {
-    if (auto *TD = getAsTypeTemplateDecl(IIDecl))
-      T = Context.getDeducedTemplateSpecializationType(TemplateName(TD),
-                                                       QualType(), false);
+  } else if (AllowDeducedTemplate && isTypeTemplate(IIDecl)) {
+    T = Context.getDeducedTemplateSpecializationType(
+        TemplateName(cast<TemplateDecl>(IIDecl)), QualType(), false);
   }
 
   if (T.isNull()) {
Index: cfe/trunk/lib/Sema/TreeTransform.h
===================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h
+++ cfe/trunk/lib/Sema/TreeTransform.h
@@ -307,17 +307,6 @@
   ///
   QualType TransformType(TypeLocBuilder &TLB, TypeLoc TL);
 
-  /// \brief Transform a type that is permitted to produce a
-  /// DeducedTemplateSpecializationType.
-  ///
-  /// This is used in the (relatively rare) contexts where it is acceptable
-  /// for transformation to produce a class template type with deduced
-  /// template arguments.
-  /// @{
-  QualType TransformTypeWithDeducedTST(QualType T);
-  TypeSourceInfo *TransformTypeWithDeducedTST(TypeSourceInfo *DI);
-  /// @}
-
   /// \brief Transform the given statement.
   ///
   /// By default, this routine transforms a statement by delegating to the
@@ -909,7 +898,7 @@
   /// By default, builds a new ParenType type from the inner type.
   /// Subclasses may override this routine to provide different behavior.
   QualType RebuildParenType(QualType InnerType) {
-    return SemaRef.BuildParenType(InnerType);
+    return SemaRef.Context.getParenType(InnerType);
   }
 
   /// \brief Build a new qualified name type.
@@ -979,8 +968,7 @@
                                     SourceLocation KeywordLoc,
                                     NestedNameSpecifierLoc QualifierLoc,
                                     const IdentifierInfo *Id,
-                                    SourceLocation IdLoc,
-                                    bool DeducedTSTContext) {
+                                    SourceLocation IdLoc) {
     CXXScopeSpec SS;
     SS.Adopt(QualifierLoc);
 
@@ -992,25 +980,9 @@
                                                     Id);
     }
 
-    if (Keyword == ETK_None || Keyword == ETK_Typename) {
-      QualType T = SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
-                                             *Id, IdLoc);
-      // If a dependent name resolves to a deduced template specialization type,
-      // check that we're in one of the syntactic contexts permitting it.
-      if (!DeducedTSTContext) {
-        if (auto *Deduced = dyn_cast_or_null<DeducedTemplateSpecializationType>(
-                T.isNull() ? nullptr : T->getContainedDeducedType())) {
-          SemaRef.Diag(IdLoc, diag::err_dependent_deduced_tst)
-            << (int)SemaRef.getTemplateNameKindForDiagnostics(
-                   Deduced->getTemplateName())
-            << QualType(QualifierLoc.getNestedNameSpecifier()->getAsType(), 0);
-          if (auto *TD = Deduced->getTemplateName().getAsTemplateDecl())
-            SemaRef.Diag(TD->getLocation(), diag::note_template_decl_here);
-          return QualType();
-        }
-      }
-      return T;
-    }
+    if (Keyword == ETK_None || Keyword == ETK_Typename)
+      return SemaRef.CheckTypenameType(Keyword, KeywordLoc, QualifierLoc,
+                                       *Id, IdLoc);
 
     TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
 
@@ -3185,10 +3157,6 @@
   TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
                                             NamedDecl *FirstQualifierInScope,
                                             CXXScopeSpec &SS);
-
-  QualType TransformDependentNameType(TypeLocBuilder &TLB,
-                                      DependentNameTypeLoc TL,
-                                      bool DeducibleTSTContext);
 };
 
 template<typename Derived>
@@ -4080,52 +4048,6 @@
   llvm_unreachable("unhandled type loc!");
 }
 
-template<typename Derived>
-QualType TreeTransform<Derived>::TransformTypeWithDeducedTST(QualType T) {
-  if (!isa<DependentNameType>(T))
-    return TransformType(T);
-
-  if (getDerived().AlreadyTransformed(T))
-    return T;
-  TypeSourceInfo *DI = getSema().Context.getTrivialTypeSourceInfo(T,
-                                                getDerived().getBaseLocation());
-  TypeSourceInfo *NewDI = getDerived().TransformTypeWithDeducedTST(DI);
-  return NewDI ? NewDI->getType() : QualType();
-}
-
-template<typename Derived>
-TypeSourceInfo *
-TreeTransform<Derived>::TransformTypeWithDeducedTST(TypeSourceInfo *DI) {
-  if (!isa<DependentNameType>(DI->getType()))
-    return TransformType(DI);
-
-  // Refine the base location to the type's location.
-  TemporaryBase Rebase(*this, DI->getTypeLoc().getBeginLoc(),
-                       getDerived().getBaseEntity());
-  if (getDerived().AlreadyTransformed(DI->getType()))
-    return DI;
-
-  TypeLocBuilder TLB;
-
-  TypeLoc TL = DI->getTypeLoc();
-  TLB.reserve(TL.getFullDataSize());
-
-  Qualifiers Quals;
-  if (auto QTL = TL.getAs<QualifiedTypeLoc>()) {
-    Quals = QTL.getType().getLocalQualifiers();
-    TL = QTL.getUnqualifiedLoc();
-  }
-
-  auto DNTL = TL.castAs<DependentNameTypeLoc>();
-
-  QualType Result = getDerived().TransformDependentNameType(
-      TLB, DNTL, /*DeducedTSTContext*/true);
-  if (Result.isNull())
-    return nullptr;
-
-  return TLB.getTypeSourceInfo(SemaRef.Context, Result);
-}
-
 /// FIXME: By default, this routine adds type qualifiers only to types
 /// that can have qualifiers, and silently suppresses those qualifiers
 /// that are not permitted (e.g., qualifiers on reference or function
@@ -5932,14 +5854,8 @@
 }
 
 template<typename Derived>
-QualType TreeTransform<Derived>::TransformDependentNameType(
-    TypeLocBuilder &TLB, DependentNameTypeLoc TL) {
-  return TransformDependentNameType(TLB, TL, false);
-}
-
-template<typename Derived>
-QualType TreeTransform<Derived>::TransformDependentNameType(
-    TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
+QualType TreeTransform<Derived>::TransformDependentNameType(TypeLocBuilder &TLB,
+                                                      DependentNameTypeLoc TL) {
   const DependentNameType *T = TL.getTypePtr();
 
   NestedNameSpecifierLoc QualifierLoc
@@ -5952,8 +5868,7 @@
                                             TL.getElaboratedKeywordLoc(),
                                             QualifierLoc,
                                             T->getIdentifier(),
-                                            TL.getNameLoc(),
-                                            DeducedTSTContext);
+                                            TL.getNameLoc());
   if (Result.isNull())
     return QualType();
 
@@ -9559,8 +9474,7 @@
 ExprResult
 TreeTransform<Derived>::TransformCXXFunctionalCastExpr(
                                                      CXXFunctionalCastExpr *E) {
-  TypeSourceInfo *Type =
-      getDerived().TransformTypeWithDeducedTST(E->getTypeInfoAsWritten());
+  TypeSourceInfo *Type = getDerived().TransformType(E->getTypeInfoAsWritten());
   if (!Type)
     return ExprError();
 
@@ -9749,8 +9663,8 @@
 ExprResult
 TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
   // Transform the type that we're allocating
-  TypeSourceInfo *AllocTypeInfo =
-      getDerived().TransformTypeWithDeducedTST(E->getAllocatedTypeSourceInfo());
+  TypeSourceInfo *AllocTypeInfo
+    = getDerived().TransformType(E->getAllocatedTypeSourceInfo());
   if (!AllocTypeInfo)
     return ExprError();
 
@@ -10461,8 +10375,7 @@
 ExprResult
 TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
                                                     CXXTemporaryObjectExpr *E) {
-  TypeSourceInfo *T =
-      getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
+  TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
   if (!T)
     return ExprError();
 
@@ -10759,8 +10672,7 @@
 ExprResult
 TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
                                                   CXXUnresolvedConstructExpr *E) {
-  TypeSourceInfo *T =
-      getDerived().TransformTypeWithDeducedTST(E->getTypeSourceInfo());
+  TypeSourceInfo *T = getDerived().TransformType(E->getTypeSourceInfo());
   if (!T)
     return ExprError();
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to