Why do this
While working on D128750, it is found that AutoType is not uniqued as expected in the partial ordering. This is because
AutoType contains the constraints for the NTTP and the NTTP itself has a reference to the constraint in AutoType.
Due to this restriction, the partial ordering between template<C auto> and template<D auto> could not be handled the same way
as the partial ordering between template<int> and template<int>. By P2113, they should work the same way and if it doesn't,
the implementation of P2113 would be much harder if at all possible. After this patch, NTTP constraints operate the same way as
TTP constraints, which is to say, constraints are represented separately from the type. This is also easier to understand and maintain.
Note that this patch only changes how constrained auto is represented in NTTP. Nothing is changed when
constrained auto is used as function parameters, as variable declarations, etc.
Implementation strategy
- Add a TypeConstraint to NonTypeTemplateParmDecl in the same way as TemplateTypeParmDecl
- During parsing, parse the constraint as a part of NTTP. This also means the constraint inside AutoType would be empty (and later in partial ordering, AutoType uniquing would work due to this).
- Looking at how the constraint for TemplateTypeParmDecl is handled, add similar/same handling for the constraint for NonTypeTemplateParmDecl.
AST change
For (TTP W is added for comparison purposes.)
template <typename T> concept C = true; template<C auto V, C W> struct A;
AST before this patch:
`-ClassTemplateDecl 0x9091c60 <line:2:1, col:32> col:32 A |-NonTypeTemplateParmDecl 0x9091818 <col:10, col:17> col:17 referenced 'C auto' depth 0 index 0 V ========> C is part of AutoType | `-ConceptSpecializationExpr 0x9091948 <col:10> 'bool' Concept 0x90916e8 'C' | `-TemplateArgument <col:17> type 'decltype(V)' | `-DecltypeType 0x90918e0 'decltype(V)' dependent | `-DeclRefExpr 0x9091878 <col:17> 'C auto' NonTypeTemplateParm 0x9091818 'V' 'C auto' |-TemplateTypeParmDecl 0x90919d0 <col:20, col:22> col:22 Concept 0x90916e8 'C' depth 0 index 1 W | `-ConceptSpecializationExpr 0x9091b08 <col:20> 'bool' Concept 0x90916e8 'C' | `-TemplateArgument <col:22> type 'W' | `-TemplateTypeParmType 0x9091aa0 'W' dependent depth 0 index 1 | `-TemplateTypeParm 0x90919d0 'W' `-CXXRecordDecl 0x9091bb0 <col:25, col:32> col:32 struct A
AST after this patch:
`-ClassTemplateDecl 0x887dd40 <line:2:1, col:32> col:32 A |-NonTypeTemplateParmDecl 0x887d8b8 <col:12, col:17> col:17 referenced Concept 0x887d788 'C' 'auto' depth 0 index 0 V ========> C is part of NTTP | `-ConceptSpecializationExpr 0x887da28 <col:10> 'bool' Concept 0x887d788 'C' | `-TemplateArgument <col:17> type 'decltype(V)' | `-DecltypeType 0x887d9c0 'decltype(V)' dependent | `-DeclRefExpr 0x887d960 <col:17> 'auto' NonTypeTemplateParm 0x887d8b8 'V' 'auto' |-TemplateTypeParmDecl 0x887dab0 <col:20, col:22> col:22 Concept 0x887d788 'C' depth 0 index 1 W | `-ConceptSpecializationExpr 0x887dbe8 <col:20> 'bool' Concept 0x887d788 'C' | `-TemplateArgument <col:22> type 'W' | `-TemplateTypeParmType 0x887db80 'W' dependent depth 0 index 1 | `-TemplateTypeParm 0x887dab0 'W' `-CXXRecordDecl 0x887dc90 <col:25, col:32> col:32 struct A