llvm-project/clang/test/Parser/cxx2c-template-template-param.cpp
Corentin Jabot 28ed57eda8
[Clang] Initial support for P2841 (Variable template and concept template parameters) (#150823)
This is a first pass at implementing
[P2841R7](https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2025/p2841r7.pdf).

The implementation is far from complete; however, I'm aiming to do that
in chunks, to make our lives easier.

In particular, this does not implement
 - Subsumption
 - Mangling
- Satisfaction checking is minimal as we should focus on #141776 first
(note that I'm currently very stuck)

FTM, release notes, status page, etc, will be updated once the feature
is more mature. Given the state of the feature, it is not yet allowed in
older language modes.

Of note: 
- Mismatches between template template arguments and template template
parameters are a bit wonky. This is addressed by #130603
- We use `UnresolvedLookupExpr` to model template-id. While this is
pre-existing, I have been wondering if we want to introduce a different
OverloadExpr subclass for that. I did not make the change in this patch.
2025-08-04 08:51:22 +02:00

80 lines
2.1 KiB
C++

// RUN: %clang_cc1 -std=c++2c -verify %s
template<template<typename> auto Var>
struct A{};
template<template<auto> auto Var>
struct B{};
template<template<typename> auto Var>
struct C{};
template<template<typename> concept C>
struct D{};
template<template<auto> concept C>
struct E{};
template<template<typename> auto Var>
int V1;
template<template<auto> auto Var>
int V2;
template<template<typename> auto Var>
int V3;
template<template<typename> concept C>
int V4;
template<template<auto> concept C>
int V5;
namespace packs {
template<template<typename> auto... Var>
struct A{};
template<template<auto> auto... Var>
struct B{};
template<template<typename> auto... Var>
struct C{};
template<template<typename> concept... C>
struct D{};
template<template<auto> concept... C>
struct E{};
template<template<typename> auto... Var>
int V1;
template<template<auto> auto... Var>
int V2;
template<template<typename> auto... Var>
int V3;
template<template<typename> concept... C>
int V4;
template<template<auto> concept... C>
int V5;
}
namespace concepts {
template<template<auto> concept...>
struct A{};
template<template<auto> concept... C>
struct B{};
template<template<auto> concept& C> // expected-error{{expected identifier}} \
// expected-error {{in declaration of struct 'C'}}
struct C{};
}
namespace vars {
template<template<auto> auto...>
struct A{};
template<template<auto> auto & C> // expected-error {{expected identifier}} \
// expected-error {{extraneous 'template<>'}}
struct B{};
template<template<auto> const auto> // expected-error {{expected identifier}} \
// expected-error {{extraneous 'template<>'}}
struct C{};
}
namespace errors {
template<concept> // expected-error {{expected template parameter}} \
// expected-error {{extraneous 'template<>' in declaration of struct 'A'}}
struct A{};
template<template<concept> auto> // expected-error {{expected template parameter}} \
// expected-error {{template template parameter must have its own template parameters}}
struct B{};
}