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