switch (DS.getTypeSpecType()) {
case DeclSpec::TST_typename:
case DeclSpec::TST_typeofType:
- case DeclSpec::TST_decltype:
case DeclSpec::TST_underlyingType:
case DeclSpec::TST_atomic: {
// Grab the type from the parser.
break;
}
+ case DeclSpec::TST_decltype:
case DeclSpec::TST_typeofExpr: {
Expr *E = DS.getRepAsExpr();
ExprResult Result = S.RebuildExprInCurrentInstantiation(E);
void f(int); // expected-note{{possible target for call}}
};
S<K> b; // expected-note{{in instantiation of template class 'S<K>' requested here}}
+
+namespace PR13978 {
+ template<typename T> struct S { decltype(1) f(); };
+ template<typename T> decltype(1) S<T>::f() { return 1; }
+
+ // This case is ill-formed (no diagnostic required) because the decltype
+ // expressions are functionally equivalent but not equivalent. It would
+ // be acceptable for us to reject this case.
+ template<typename T> struct U { struct A {}; decltype(A{}) f(); };
+ template<typename T> decltype(typename U<T>::A{}) U<T>::f() {}
+
+ // This case is valid.
+ template<typename T> struct V { struct A {}; decltype(typename V<T>::A{}) f(); };
+ template<typename T> decltype(typename V<T>::A{}) V<T>::f() {}
+}