Clang Template Specialization Resugaring

GSoC 2022

Roadmap

Matheus Izvekov <mizvekov@gmail.com>

Overview

  • C++ Template instantiations are performed only considering the canonical template arguments.

  • Any accesses through template specializations, as it currently stands, lose any non-structural parts of the template arguments.

Proposal

Resugar types and expressions accessed through template specializations, replacing the canonical types therein with the sugared types as written in the arguments of the specializations.

In simplest terms, with an example, we want this to work:

template<class T> struct foo { using type = T; };

struct Baz {};

using Bar [[gnu::aligned(64)]] = Baz;

using type = typename foo<Bar>::type;

// Clang as it stands will fail below assert
// as the foo template will only be instantiated
// with the structural part of the argument,
// which the Bar alias is not.
// So it only sees Baz, the aligned attribute is never seen.
static_assert(alignof(type) == 64);

Timeline

May 20 - June 12 (Community bonding period)

Got up to speed with development environment.

Frontloading some of the work, starting with a simpler implementation which resugars eagerly instead of lazily as initially proposed here.

June 13 - July 29 (Phase I)

  1. Investigate design approaches.
    Deliverable: A concise technical document sent as a RFC to clang’s developer mailing lists.

  2. Improve the representation of type information of a ClassTemplateSpecializationDecl.
    Deliverable: Design a new type in clang: MemberSugarType.

  3. Improve the representation of type information of a ClassTemplateSpecializationDecl.
    Deliverable: Connect the MemberSugarType to it.

  1. Extend the test case coverage and demonstrate better diagnostics in several cases.
    Deliverable: Enhanced test cases and improved documentation where required.
  1. Buffer week

July 25 - September 12 (Phase II)

  1. Implement a single-step desugaring based on desguaring a MemberSugarType wrapped around a FunctionProtoType.
    Deliverable: The ability to push the member sugar onto the return type and parameter types of the type.

  2. Implementing a MemberSugarType wrapped around a RecordType representing a member of the type tracked by a MemberSugarType would form an ElaboratedType describing the name of that member as a member of the sugared type.
    Deliverable: The ability to push the member sugar via ElaboratedType.

  1. Enable MemberSugarType wrapped around a SubstTemplateTypeParmType, we can desugar that type to Foo (taking the type sugar for the template argument from the TemplateSpecializationType).
    Deliverable: desugar the type of a call to x.front() to Foo.
  1. Buffer week

  2. Demonstrate the usefulness of the diagnostic and also preserving of type sugar in the AST for I/O purposes (via the CERN Data Analysis Project ROOT).
    Deliverable: Remove the ROOT patch / hack.

  1. Update documentation and prepare a blogpost. Fix bugs.
    Deliverable: A post on LLVM blog.