elsteveogrande updated this revision to Diff 128466.
elsteveogrande edited the summary of this revision.
elsteveogrande added a comment.

Fixed local var names.  Using `arc diff` which hopefully submits latest changes 
w/ full context


Repository:
  rC Clang

https://reviews.llvm.org/D38320

Files:
  lib/Serialization/ASTReaderDecl.cpp
  lib/Serialization/ASTWriterDecl.cpp
  test/PCH/cxx-templates.cpp
  test/PCH/cxx-templates.h

Index: test/PCH/cxx-templates.h
===================================================================
--- test/PCH/cxx-templates.h
+++ test/PCH/cxx-templates.h
@@ -361,3 +361,38 @@
 namespace MemberSpecializationLocation {
   template<typename T> struct A { static int n; };
 }
+
+// https://bugs.llvm.org/show_bug.cgi?id=34728
+namespace PR34728 {
+
+// case 1: defaulted `NonTypeTemplateParmDecl`, non-defaulted 2nd tpl param
+template <int foo = 42, class T>
+int func1(T const &);
+
+template <int foo, class T>
+int func1(T const &) {
+  return foo;
+}
+
+// case 2: defaulted `TemplateTypeParmDecl`, non-defaulted 2nd tpl param
+template <class A = int, class B>
+A func2(B const &);
+
+template <class A, class B>
+A func2(B const &) {
+  return 69;
+}
+
+// case 3: defaulted `TemplateTemplateParmDecl`, non-defaulted 2nd tpl param
+template <class T>
+struct Container { T const &item; };
+
+template <template <class> class C = Container, class D>
+C<D> func3(D const &);
+
+template <template <class> class C, class D>
+C<D> func3(D const &d) {
+  return Container<D>{d};
+}
+
+} // end namespace PR34728
Index: test/PCH/cxx-templates.cpp
===================================================================
--- test/PCH/cxx-templates.cpp
+++ test/PCH/cxx-templates.cpp
@@ -116,3 +116,14 @@
 #endif
   int k = A<int>::n;
 }
+
+// https://bugs.llvm.org/show_bug.cgi?id=34728
+namespace PR34728 {
+int test() {
+  int z1 = func1(2.718);
+  int z2 = func2(3.142);
+  int z3 = 12;
+  Container<int> c = func3(z3);
+  return z1 + z2 + c.item;
+}
+} // end namespace PR34728
Index: lib/Serialization/ASTWriterDecl.cpp
===================================================================
--- lib/Serialization/ASTWriterDecl.cpp
+++ lib/Serialization/ASTWriterDecl.cpp
@@ -1542,11 +1542,24 @@
 
   Record.push_back(D->wasDeclaredWithTypename());
 
-  bool OwnsDefaultArg = D->hasDefaultArgument() &&
-                        !D->defaultArgumentWasInherited();
-  Record.push_back(OwnsDefaultArg);
-  if (OwnsDefaultArg)
-    Record.AddTypeSourceInfo(D->getDefaultArgumentInfo());
+  TypeSourceInfo *OwnedDefaultArg = nullptr;
+  Decl const *InheritsFromDecl = nullptr;
+  if (D->hasDefaultArgument()) {
+    if (D->defaultArgumentWasInherited()) {
+      InheritsFromDecl = D->getDefaultArgStorage().getInheritedFrom();
+    } else {
+      OwnedDefaultArg = D->getDefaultArgumentInfo();
+    }
+  }
+
+  Record.push_back(OwnedDefaultArg != nullptr);
+  if (OwnedDefaultArg) {
+    Record.AddTypeSourceInfo(OwnedDefaultArg);
+  }
+  Record.push_back(InheritsFromDecl != nullptr);
+  if (InheritsFromDecl) {
+    Record.AddDeclRef(InheritsFromDecl);
+  }
 
   Code = serialization::DECL_TEMPLATE_TYPE_PARM;
 }
@@ -1573,11 +1586,26 @@
   } else {
     // Rest of NonTypeTemplateParmDecl.
     Record.push_back(D->isParameterPack());
-    bool OwnsDefaultArg = D->hasDefaultArgument() &&
-                          !D->defaultArgumentWasInherited();
-    Record.push_back(OwnsDefaultArg);
-    if (OwnsDefaultArg)
-      Record.AddStmt(D->getDefaultArgument());
+
+    Expr *OwnedDefaultArg = nullptr;
+    Decl const *InheritsFromDecl = nullptr;
+    if (D->hasDefaultArgument()) {
+      if (D->defaultArgumentWasInherited()) {
+        InheritsFromDecl = D->getDefaultArgStorage().getInheritedFrom();
+      } else {
+        OwnedDefaultArg = D->getDefaultArgument();
+      }
+    }
+
+    Record.push_back(OwnedDefaultArg != nullptr);
+    if (OwnedDefaultArg) {
+      Record.AddStmt(OwnedDefaultArg);
+    }
+    Record.push_back(InheritsFromDecl != nullptr);
+    if (InheritsFromDecl) {
+      Record.AddDeclRef(InheritsFromDecl);
+    }
+
     Code = serialization::DECL_NON_TYPE_TEMPLATE_PARM;
   }
 }
@@ -1602,11 +1630,26 @@
   } else {
     // Rest of TemplateTemplateParmDecl.
     Record.push_back(D->isParameterPack());
-    bool OwnsDefaultArg = D->hasDefaultArgument() &&
-                          !D->defaultArgumentWasInherited();
-    Record.push_back(OwnsDefaultArg);
-    if (OwnsDefaultArg)
-      Record.AddTemplateArgumentLoc(D->getDefaultArgument());
+
+    llvm::Optional<TemplateArgumentLoc> OwnedDefaultArg;
+    Decl const *InheritsFromDecl = nullptr;
+    if (D->hasDefaultArgument()) {
+      if (D->defaultArgumentWasInherited()) {
+        InheritsFromDecl = D->getDefaultArgStorage().getInheritedFrom();
+      } else {
+        OwnedDefaultArg = D->getDefaultArgument();
+      }
+    }
+
+    Record.push_back(OwnedDefaultArg.hasValue());
+    if (OwnedDefaultArg.hasValue()) {
+      Record.AddTemplateArgumentLoc(*OwnedDefaultArg);
+    }
+    Record.push_back(InheritsFromDecl != nullptr);
+    if (InheritsFromDecl) {
+      Record.AddDeclRef(InheritsFromDecl);
+    }
+
     Code = serialization::DECL_TEMPLATE_TEMPLATE_PARM;
   }
 }
Index: lib/Serialization/ASTReaderDecl.cpp
===================================================================
--- lib/Serialization/ASTReaderDecl.cpp
+++ lib/Serialization/ASTReaderDecl.cpp
@@ -440,6 +440,14 @@
 };
 } // end anonymous namespace
 
+/// Inherit the default template argument from \p From to \p To. Returns
+/// \c false if there is no default template for \p From.
+/// It is an error to call this method more than once on \p To, with differing
+/// \p From decls.
+template <typename ParmDecl>
+static bool inheritDefaultTemplateArgument(ASTContext &Context, ParmDecl *From,
+                                           Decl *ToD);
+
 template <typename DeclT>
 static llvm::iterator_range<MergedRedeclIterator<DeclT>>
 merged_redecls(DeclT *D) {
@@ -2248,6 +2256,11 @@
 
   if (Record.readInt())
     D->setDefaultArgument(GetTypeSourceInfo());
+
+  if (Record.readInt()) {
+    inheritDefaultTemplateArgument(
+        Reader.getContext(), Record.readDeclAs<TemplateTypeParmDecl>(), D);
+  }
 }
 
 void ASTDeclReader::VisitNonTypeTemplateParmDecl(NonTypeTemplateParmDecl *D) {
@@ -2265,8 +2278,14 @@
   } else {
     // Rest of NonTypeTemplateParmDecl.
     D->ParameterPack = Record.readInt();
+
     if (Record.readInt())
       D->setDefaultArgument(Record.readExpr());
+
+    if (Record.readInt()) {
+      inheritDefaultTemplateArgument(
+          Reader.getContext(), Record.readDeclAs<NonTypeTemplateParmDecl>(), D);
+    }
   }
 }
 
@@ -2284,9 +2303,16 @@
   } else {
     // Rest of TemplateTemplateParmDecl.
     D->ParameterPack = Record.readInt();
+
     if (Record.readInt())
       D->setDefaultArgument(Reader.getContext(),
                             Record.readTemplateArgumentLoc());
+
+    if (Record.readInt()) {
+      inheritDefaultTemplateArgument(
+          Reader.getContext(), Record.readDeclAs<TemplateTemplateParmDecl>(),
+          D);
+    }
   }
 }
 
@@ -3265,12 +3291,20 @@
 
 /// Inherit the default template argument from \p From to \p To. Returns
 /// \c false if there is no default template for \p From.
+/// It is an error to call this method more than once on \p To, with differing
+/// \p From decls.
 template <typename ParmDecl>
 static bool inheritDefaultTemplateArgument(ASTContext &Context, ParmDecl *From,
                                            Decl *ToD) {
   auto *To = cast<ParmDecl>(ToD);
   if (!From->hasDefaultArgument())
     return false;
+  auto const &DA = To->getDefaultArgStorage();
+  if (DA.isSet() && DA.isInherited()) {
+    assert(DA.getInheritedFrom() == From &&
+           "template arg already inherits from a different decl");
+    return true;
+  }
   To->setInheritedDefaultArgument(Context, From);
   return true;
 }
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to