microsoft / ifc-spec

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

IFC Literals may contain surprising values #77

Open DarkArc opened 1 year ago

DarkArc commented 1 year ago

MSVC produced IFCs have been observed with the following unusual literal representations. These representations require special cased logic to correctly handle due to their surprising semantics.

Template Parameter References

The IFC sometimes represents references to template parameters via an ExprSort::Literal with a value of 0 and type of TypeSort::Designated. This designated type's associated decl can be a DeclSort::Parameter representing a reference to a template parameter:

  template<typename T>
  using x = typename y<sizeof(T)>;
                              ^

Indirect Template Parameter References

Similarly, the IFC sometimes represents references to template parameters indirectly via an ExprSort::Literal with a value of 0 and a type of TypeSort::Syntactic. This syntactic type's associated expr is an ExprSort::TemplateId .

This manifest from code of the ilk:

  template <class T, size_t = sizeof(remove_reference_t<T>)>
  struct y;

  template <typename T>
  using x = typename y<T>;

Where the IFC "inlines" the default template argument representing the latter given declaration as something like (with the underlined type represented as an IFC ExprSort::Literal):

  template <typename T>
  using x = typename y<T, sizeof(remove_reference_t<T>)>;
                                 ^^^^^^^^^^^^^^^^^^^^^

Decltype

The IFC additionally sometimes wraps decltype types (IFC TypeSort::Decltype) in ExprSort::Literal expressions with a value of 0 of the ilk:

  struct x { /* ... */};

  template <x V>
  using x = typename y<sizeof(decltype(V.data[0]))>;
                              ^^^^^^^^^^^^^^^^^^^