diff options
-rw-r--r-- | clang/lib/Serialization/ASTReaderDecl.cpp | 11 | ||||
-rw-r--r-- | clang/test/PCH/cxx-templates.h | 47 |
2 files changed, 54 insertions, 4 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 70fb062b2c5..c2e286814bc 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -356,11 +356,14 @@ void ASTDeclReader::Visit(Decl *D) { } void ASTDeclReader::VisitDecl(Decl *D) { - if (D->isTemplateParameter()) { + if (D->isTemplateParameter() || D->isTemplateParameterPack() || + isa<ParmVarDecl>(D)) { // We don't want to deserialize the DeclContext of a template - // parameter immediately, because the template parameter might be - // used in the formulation of its DeclContext. Use the translation - // unit DeclContext as a placeholder. + // parameter or of a parameter of a function template immediately. These + // entities might be used in the formulation of its DeclContext (for + // example, a function parameter can be used in decltype() in trailing + // return type of the function). Use the translation unit DeclContext as a + // placeholder. GlobalDeclID SemaDCIDForTemplateParmDecl = ReadDeclID(Record, Idx); GlobalDeclID LexicalDCIDForTemplateParmDecl = ReadDeclID(Record, Idx); Reader.addPendingDeclContextInfo(D, diff --git a/clang/test/PCH/cxx-templates.h b/clang/test/PCH/cxx-templates.h index 992f478e33e..c4a84472769 100644 --- a/clang/test/PCH/cxx-templates.h +++ b/clang/test/PCH/cxx-templates.h @@ -311,3 +311,50 @@ namespace local_extern { return sizeof(arr); } } + +namespace rdar15468709a { + template<typename> struct decay {}; + + template<typename FooParamTy> auto foo(FooParamTy fooParam) -> decltype(fooParam); + template<typename BarParamTy> auto bar(BarParamTy barParam) -> decay<decltype(barParam)>; + + struct B {}; + + void crash() { + B some; + bar(some); + } +} + +namespace rdar15468709b { + template<typename> struct decay {}; + + template<typename... Foos> int returnsInt(Foos... foos); + + template<typename... FooParamTy> auto foo(FooParamTy... fooParam) -> decltype(returnsInt(fooParam...)); + template<typename... BarParamTy> auto bar(BarParamTy... barParam) -> decay<decltype(returnsInt(barParam...))>; + + struct B {}; + + void crash() { + B some; + bar(some); + } +} + +namespace rdar15468709c { + template<typename> struct decay {}; + + template<class... Foos> int returnsInt(Foos... foos); + + template<typename FooParamTy> void foo(FooParamTy fooParam) { decltype(fooParam) a; } + template<typename BarParamTy> auto bar(BarParamTy barParam) -> decay<decltype(barParam)>; + + struct B {}; + + void crash() { + B some; + bar(some); + } +} + |