| commit | 34ae2265e88c8a04350de5a244d0d888e74a8388 | [log] [tgz] |
|---|---|---|
| author | Krystian Stasiowski <sdkrystian@gmail.com> | Tue May 07 21:41:33 2024 -0400 |
| committer | GitHub <noreply@github.com> | Tue May 07 21:41:33 2024 -0400 |
| tree | ce210841290cde80dd71aa91ceee3ec4e0766df3 | |
| parent | 83f3b1cb480b41e3347035aff14fd4bc2ba21d24 [diff] |
[Clang][Sema] Improve support for explicit specializations of constrained member functions & member function templates (#88963)
Consider the following snippet from the discussion of CWG2847 on the core reflector:
```
template<typename T>
concept C = sizeof(T) <= sizeof(long);
template<typename T>
struct A
{
template<typename U>
void f(U) requires C<U>; // #1, declares a function template
void g() requires C<T>; // #2, declares a function
template<>
void f(char); // #3, an explicit specialization of a function template that declares a function
};
template<>
template<typename U>
void A<short>::f(U) requires C<U>; // #4, an explicit specialization of a function template that declares a function template
template<>
template<>
void A<int>::f(int); // #5, an explicit specialization of a function template that declares a function
template<>
void A<long>::g(); // #6, an explicit specialization of a function that declares a function
```
A number of problems exist:
- Clang rejects `#4` because the trailing _requires-clause_ has `U`
substituted with the wrong template parameter depth when
`Sema::AreConstraintExpressionsEqual` is called to determine whether it
matches the trailing _requires-clause_ of the implicitly instantiated
function template.
- Clang rejects `#5` because the function template specialization
instantiated from `A<int>::f` has a trailing _requires-clause_, but `#5`
does not (nor can it have one as it isn't a templated function).
- Clang rejects `#6` for the same reasons it rejects `#5`.
This patch resolves these issues by making the following changes:
- To fix `#4`, `Sema::AreConstraintExpressionsEqual` is passed
`FunctionTemplateDecl`s when comparing the trailing _requires-clauses_
of `#4` and the function template instantiated from `#1`.
- To fix `#5` and `#6`, the trailing _requires-clauses_ are not compared
for explicit specializations that declare functions.
In addition to these changes, `CheckMemberSpecialization` now considers
constraint satisfaction/constraint partial ordering when determining
which member function is specialized by an explicit specialization of a
member function for an implicit instantiation of a class template (we
previously would select the first function that has the same type as the
explicit specialization). With constraints taken under consideration, we
match EDG's behavior for these declarations.Welcome to the LLVM project!
This repository contains the source code for LLVM, a toolkit for the construction of highly optimized compilers, optimizers, and run-time environments.
The LLVM project has multiple components. The core of the project is itself called “LLVM”. This contains all of the tools, libraries, and header files needed to process intermediate representations and convert them into object files. Tools include an assembler, disassembler, bitcode analyzer, and bitcode optimizer.
C-like languages use the Clang frontend. This component compiles C, C++, Objective-C, and Objective-C++ code into LLVM bitcode -- and from there into object files, using LLVM.
Other components include: the libc++ C++ standard library, the LLD linker, and more.
Consult the Getting Started with LLVM page for information on building and running LLVM.
For information on how to contribute to the LLVM project, please take a look at the Contributing to LLVM guide.
Join the LLVM Discourse forums, Discord chat, LLVM Office Hours or Regular sync-ups.
The LLVM project has adopted a code of conduct for participants to all modes of communication within the project.