microsoft / ifc-spec

IFC format specification
Creative Commons Attribution 4.0 International
71 stars 7 forks source link

IFC ExprType may be used for a template template argument #86

Closed DarkArc closed 1 year ago

DarkArc commented 1 year ago

Consider the following:

template<template<typename> class Container>
struct HashMap
{
    struct Entry {};
    constexpr HashMap(int val) {}
    using ContainerType = Container<Entry>;
private:
    ContainerType m_entries;
};

template<typename T>
struct Array
{
    T m_data;
};

template<typename T>
struct KeymapBackend : private Array<T>
{
    constexpr KeymapBackend() = default;
private:
    int m_size = 0;
};

When the template class HashMap is supplied with the template template argument KeymapBackend:

constexpr HashMap<KeymapBackend> keymap = { 0 };
                  ^^^^^^^^^^^^^

This is represented in the IFC as an expression ExprType with a denotation of TypeDesignated pointing to a DeclTemplate. This representation is a bit troubling as ExprType implies (in my mind at least) a type template argument.

I don't see an existing IFC node I'd suggest using in place, perhaps a ExprTemplate would be justified(?)

GabrielDosReis commented 1 year ago

What is conventionally called a forall type (or universally quantified type) is represented in the IFC as a TypeSort::Forall, and also in the IPR by a node of type Forall. Template declarations are modeled in the IFC (and in the IPR) as having universally quantified types -- though in full completeness, the representation also encodes compile-time dependent types, as necessary.

Since TypeSort::Forall represents a type, in the IFC, it is only logically necessary that an ExprSort::Type should be expected to also encode a reference to a forall type as one of its alternatives.

Since the representation follows from the logical representation, there does not seem to be a need for a separate node. Each expression in the IFC has a type, so the kind of a template-argument is easily inferred from its type (see the corresponding discussion in the most recent update to the DeclSort::Parameter structure).

There are artificial restrictions in the ISO C++ standards that require a template template-argument to name a declaration, which is why you see a TypeSort::Designated referencing the DeclSort::Template. But, logically, any type expression should be expected.

I created issue #104 to track the more general issue of expected graph patterns.