}
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,
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);
+ }
+}
+