[cfe-dev] template instantiation, typedef used as template argument and dependent type for data members.

Richard Smith richard at metafoo.co.uk
Mon Jun 25 13:02:08 PDT 2012


On Mon, Jun 25, 2012 at 9:52 AM, Philippe Canal <pcanal at fnal.gov> wrote:

> In the context of ROOT (<http://root.cern.ch>), it's automated I/O of C++
> objects, and of the cling Interpreter (<http://root.cern.ch/drupal/**
> content/cling <http://root.cern.ch/drupal/content/cling>>,
> we are strongly hindered by the fact that template instantiations that have
> a typedef as template parameter 'forget' about it in the AST (at least
> as far as the data members and member functions of the template instance
> are concerned).
>
[...]

> In addition to our use case, having access to this type
> of information could be useful for a document generator
> or to clarify/simplify some error messages.   For example:
>
>   // start of stringError.C
>   #include <string>
>   #include <vector>
>   void test ()
>   {
>      std::vector<std::string> vec;
>      vec.push_back("abc");
>      vec.push_back(1.3);
>   }
>   // end of stringError.C
>
> when compiled with clang, the output currently contains the error message:
>
> stringError.C:8:18: error: reference to type 'const value_type' (aka
> 'const std::basic_string<char>') could not bind to an rvalue of type
> 'double'
>   vec.push_back(1);
>                 ^
>
> which would be even nicer, if reading:
>
>
> stringError.C:8:18: error: reference to type 'const value_type' (aka
> 'const std::string') could not bind to an rvalue of type 'int'
>   vec.push_back(1);
>                 ^
>
> where 'std::basic_string<char>' has been replaced by 'std::string'.
>

Yes, this is a real problem which is affecting more people than just you.
IIRC, there are several bugs in bugzilla with this as the root cause (see
for instance llvm.org/PR12853).


> In first approximation, one plausible step could be to generate a distinct
> template instantiations for each of the cases with distinct typedef
> as a template argument and a template instantiation for the case
> without typedef as a template argument (i.e. the primary template
> instantiation).   And then make sure that for the rest of the semantic
> analysis vector<Double32_t> and vector<double> are
> treated as equivalent/interchangeable/**aliases.
>

I do not think this is the right approach: it could be extremely expensive
to perform all the redundant template instantiations for
canonically-equivalent-but-not-identical template arguments, and would
significantly complicate the AST to have multiple definitions for the same
declaration.

Any ideas/thoughts on if and how being able to access the intended
> type of a template instantiation's members whose type depends on the
> template parameter(s) could be supported in any way?


I think we should address this by adding type sugar for references to
instantiated entities. For instance, in this case:

  template<typename U> struct T { template<typename V> decltype(U()+V())
get(V); };
  T<IntTypedef> x;
  FloatTypedef d;
  int a = x.get(d);

... we can track that the type of 'get' is equivalent to substituting
U=IntTypedef, V=FloatTypedef into the type in the primary template, and
then instantiate (and cache) the type of that member. That should be
significantly cheaper (and simpler) than instantiating the declaration, and
would provide the same benefits.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20120625/f0c500ca/attachment.html>


More information about the cfe-dev mailing list