inform (loc, "but %qE is a function template", t);
else if (DECL_CLASS_TEMPLATE_P (t))
inform (loc, "but %qE is a class template", t);
+ else if (DECL_ALIAS_TEMPLATE_P (t))
+ inform (loc, "but %qE is an alias template", t);
else if (variable_template_p (t))
inform (loc, "but %qE is a variable template", t);
else if (TREE_CODE (t) == NAMESPACE_DECL)
inform (loc, "but %qE is a namespace", t);
else if (TREE_CODE (t) == CONST_DECL && !DECL_TEMPLATE_PARM_P (t))
inform (loc, "but %qE is an enumerator", t);
+ else if (concept_definition_p (t))
+ inform (loc, "but %qE is a concept", t);
}
/* Disable warnings about missing quoting in GCC diagnostics for
tree r = tsubst (SPLICE_SCOPE_EXPR (t), args, complain, in_decl);
if (r == error_mark_node)
return r;
+ const bool type_p = SPLICE_SCOPE_TYPE_P (t);
if (dependent_splice_p (r))
- return make_splice_scope (r, SPLICE_SCOPE_TYPE_P (t));
- if (SPLICE_SCOPE_TYPE_P (t) && ctad_template_p (r))
+ return make_splice_scope (r, type_p);
+ if (type_p && ctad_template_p (r))
r = make_template_placeholder (r);
- if (SPLICE_SCOPE_TYPE_P (t)
+ if (type_p
? !valid_splice_type_p (r)
: !valid_splice_scope_p (r))
{
if (complain & tf_error)
{
const location_t loc = EXPR_LOCATION (SPLICE_SCOPE_EXPR (t));
- if (SPLICE_SCOPE_TYPE_P (t))
- error_at (loc, "%qE is not usable in a splice type", r);
+ auto_diagnostic_group d;
+ if (type_p)
+ error_at (loc, "expected a reflection of a type");
else
- error_at (loc, "%qE is not usable in a splice scope", r);
+ error_at (loc, "expected a reflection of a class, namespace, or "
+ "enumeration");
+ inform_tree_category (r);
}
return error_mark_node;
}
template<typename>
void foo () { }
+template<typename>
+void foo2 () { }
void bar () { }
namespace N { }
namespace M = N;
template<typename T>
T vt{};
template<typename T>
+T vt2{};
+template<typename T>
concept C = true;
static int i;
enum E { X };
template<typename T>
using Z = D<T>;
-template<info R> void fn1 () { typename [:R:]::X x; } // { dg-error "not usable in a splice scope" }
-template<info R> void fn2 () { typename [:R:]::X x; } // { dg-error "not usable in a splice scope" }
-template<info R> void fn3 () { typename [:R:]::X x; } // { dg-error "not usable in a splice scope" }
-template<info R> void fn4 () { typename [:R:]::X x; } // { dg-error "not usable in a splice scope" }
-template<info R> void fn5 () { typename [:R:]::X x; } // { dg-error "not usable in a splice scope" }
-template<info R> void fn6 () { typename [:R:]::X x; } // { dg-error "not usable in a splice scope" }
-template<info R> void fn7 () { typename [:R:]::X x; } // { dg-error "not usable in a splice scope" }
-template<info R> void fn8 () { typename [:R:]::X x; } // { dg-error "not usable in a splice scope" }
-template<info R> void fn9 () { typename [:R:]::X x; } // { dg-error "not usable in a splice scope" }
-template<info R> void fn10 () { typename [:R:]::X x; } // { dg-error "not usable in a splice scope" }
-template<info R> void fn11 () { typename [:R:]::X x; } // { dg-error "not usable in a splice scope" }
+template<info R> void fn1 () { typename [:R:]::X x; } // { dg-error "expected a reflection of a class, namespace, or enumeration" }
+// { dg-message "but .foo<int>. is a function" "" { target *-*-* } 7 }
+template<info R> void fn2 () { typename [:R:]::X x; } // { dg-error "expected a reflection of a class, namespace, or enumeration" }
+// { dg-message "but .foo2. is a function template" "" { target *-*-* } 9 }
+template<info R> void fn3 () { typename [:R:]::X x; } // { dg-error "expected a reflection of a class, namespace, or enumeration" }
+// { dg-message "but .bar. is a function" "" { target *-*-* } 10 }
+template<info R> void fn4 () { typename [:R:]::X x; } // { dg-error "expected a reflection of a class, namespace, or enumeration" }
+// { dg-message "but .vt<int>. is a variable" "" { target *-*-* } 14 }
+template<info R> void fn5 () { typename [:R:]::X x; } // { dg-error "expected a reflection of a class, namespace, or enumeration" }
+// { dg-message "but .vt2<T>. is a variable template" "" { target *-*-* } 16 }
+template<info R> void fn6 () { typename [:R:]::X x; } // { dg-error "expected a reflection of a class, namespace, or enumeration" }
+// { dg-message "but .C. is a concept" "" { target *-*-* } 18 }
+template<info R> void fn7 () { typename [:R:]::X x; } // { dg-error "expected a reflection of a class, namespace, or enumeration" }
+// { dg-message "but .i. is a variable" "" { target *-*-* } 19 }
+template<info R> void fn8 () { typename [:R:]::X x; } // { dg-error "expected a reflection of a class, namespace, or enumeration" }
+// { dg-message "but .X. is an enumerator" "" { target *-*-* } 20 }
+template<info R> void fn9 () { typename [:R:]::X x; } // { dg-error "expected a reflection of a class, namespace, or enumeration" }
+// { dg-message "but .S::si. is a variable" "" { target *-*-* } 21 }
+template<info R> void fn10 () { typename [:R:]::X x; } // { dg-error "expected a reflection of a class, namespace, or enumeration" }
+// { dg-message "but .D<int>::di. is a variable" "" { target *-*-* } 23 }
+template<info R> void fn11 () { typename [:R:]::X x; } // { dg-error "expected a reflection of a class, namespace, or enumeration" }
+// { dg-message "but .Z. is an alias template" "" { target *-*-* } 25 }
template void fn1<^^foo<int>>(); // { dg-message "required from here" }
-template void fn2<^^foo>(); // { dg-message "required from here" }
+template void fn2<^^foo2>(); // { dg-message "required from here" }
template void fn3<^^bar>(); // { dg-message "required from here" }
template void fn4<^^vt<int>>(); // { dg-message "required from here" }
-template void fn5<^^vt>(); // { dg-message "required from here" }
+template void fn5<^^vt2>(); // { dg-message "required from here" }
template void fn6<^^C>(); // { dg-message "required from here" }
template void fn7<^^i>(); // { dg-message "required from here" }
template void fn8<^^X>(); // { dg-message "required from here" }
template<typename>
void foo () { }
+template<typename>
+void foo2 () { }
void bar () { }
namespace N { }
namespace M = N;
template<typename T>
T vt{};
template<typename T>
+T vt2{};
+template<typename T>
concept C = true;
static int i;
enum E { X };
template<typename T>
using Z = D<T>;
-template<info R> void fn1 () { int n = typename [:R:](42); } // { dg-error "not usable in a splice type" }
-template<info R> void fn2 () { int n = typename [:R:](42); } // { dg-error "not usable in a splice type" }
-template<info R> void fn3 () { int n = typename [:R:](42); } // { dg-error "not usable in a splice type" }
-template<info R> void fn4 () { int n = typename [:R:](42); } // { dg-error "not usable in a splice type" }
-template<info R> void fn5 () { int n = typename [:R:](42); } // { dg-error "not usable in a splice type" }
-template<info R> void fn6 () { int n = typename [:R:](42); } // { dg-error "not usable in a splice type" }
-template<info R> void fn7 () { int n = typename [:R:](42); } // { dg-error "not usable in a splice type" }
-template<info R> void fn8 () { int n = typename [:R:](42); } // { dg-error "not usable in a splice type" }
-template<info R> void fn9 () { int n = typename [:R:](42); } // { dg-error "not usable in a splice type" }
-template<info R> void fn10 () { int n = typename [:R:](42); } // { dg-error "not usable in a splice type" }
-template<info R> void fn11 () { int n = typename [:R:](42); } // { dg-error "not usable in a splice type" }
-template<info R> void fn12 () { int n = typename [:R:](42); } // { dg-error "not usable in a splice type" }
+template<info R> void fn1 () { int n = typename [:R:](42); } // { dg-error "expected a reflection of a type" }
+// { dg-message "but .foo<int>. is a function" "" { target *-*-* } 7 }
+template<info R> void fn2 () { int n = typename [:R:](42); } // { dg-error "expected a reflection of a type" }
+// { dg-message "but .foo2. is a function template" "" { target *-*-* } 9 }
+template<info R> void fn3 () { int n = typename [:R:](42); } // { dg-error "expected a reflection of a type" }
+// { dg-message "but .N. is a namespace" "" { target *-*-* } 11 }
+template<info R> void fn4 () { int n = typename [:R:](42); } // { dg-error "expected a reflection of a type" }
+// { dg-message "but .M. is a namespace" "" { target *-*-* } 12 }
+template<info R> void fn5 () { int n = typename [:R:](42); } // { dg-error "expected a reflection of a type" }
+// { dg-message "but .bar. is a function" "" { target *-*-* } 10 }
+template<info R> void fn6 () { int n = typename [:R:](42); } // { dg-error "expected a reflection of a type" }
+// { dg-message "but .vt<int>. is a variable" "" { target *-*-* } 14 }
+template<info R> void fn7 () { int n = typename [:R:](42); } // { dg-error "expected a reflection of a type" }
+// { dg-message "but .vt2<T>. is a variable template" "" { target *-*-* } 16 }
+template<info R> void fn8 () { int n = typename [:R:](42); } // { dg-error "expected a reflection of a type" }
+// { dg-message "but .C. is a concept" "" { target *-*-* } 18 }
+template<info R> void fn9 () { int n = typename [:R:](42); } // { dg-error "expected a reflection of a type" }
+// { dg-message "but .i. is a variable" "" { target *-*-* } 19 }
+template<info R> void fn10 () { int n = typename [:R:](42); } // { dg-error "expected a reflection of a type" }
+// { dg-message "but .X. is an enumerator" "" { target *-*-* } 20 }
+template<info R> void fn11 () { int n = typename [:R:](42); } // { dg-error "expected a reflection of a type" }
+// { dg-message "but .S::si. is a variable" "" { target *-*-* } 21 }
+template<info R> void fn12 () { int n = typename [:R:](42); } // { dg-error "expected a reflection of a type" }
+// { dg-message "but .D<int>::di. is a variable" "" { target *-*-* } 23 }
template<info R> void fn13 () { int n = typename [:R:](42); } // { dg-error "class template argument deduction failed|no matching" }
template void fn1<^^foo<int>>(); // { dg-message "required from here" }
-template void fn2<^^foo>(); // { dg-message "required from here" }
+template void fn2<^^foo2>(); // { dg-message "required from here" }
template void fn3<^^N>(); // { dg-message "required from here" }
template void fn4<^^M>(); // { dg-message "required from here" }
template void fn5<^^bar>(); // { dg-message "required from here" }
template void fn6<^^vt<int>>(); // { dg-message "required from here" }
-template void fn7<^^vt>(); // { dg-message "required from here" }
+template void fn7<^^vt2>(); // { dg-message "required from here" }
template void fn8<^^C>(); // { dg-message "required from here" }
template void fn9<^^i>(); // { dg-message "required from here" }
template void fn10<^^X>(); // { dg-message "required from here" }