I've just committed support for class templates into Clang's ASTImporter, which 
is a necessary step toward teaching LLDB's expression parser to properly handle 
C++ class templates. In particular, it should make it possible for the 
expression parser to handle code like

        ((vector<int> *)ptr)->push_back(17)

where we're naming a class template specialization. This can work assuming that 
vector<int> and vector<int>::push_back were instantiated in some translation 
unit and we have DWARF describing them.

Here are some notes on how class templates are represented within Clang and how 
LLDB will need to represent class templates and their 
specializations/instantiations to make expression parsing work. As our example, 
let's take:

  template<typename T>
  struct vector {
   void push_back(const T&);
  };

  void func_to_debug(vector<int> &v) {
     v.push_back(17);
  }

Here, the 'vector' class template is represented as a ClassTemplateDecl node, 
which encodes the template parameter list containing a single type parameter. 
That ClassTemplateDecl also stores a "templated" declaration, which contains 
the definition of the class that will be created if the class template is 
instantiated. In this case, it's a CXXRecordDecl describing a class named 
"vector", which  has a push_back member.

vector<int> is a class template specialization, which is represented by a 
ClassTemplateSpecializationDecl. A ClassTemplateSpecializationDecl is a special 
kind of CXXRecordDecl that has information describing how it specializes a 
ClassTemplateDecl, i.e., the set of template arguments that was used in the 
specialization. In this case, the ClassTemplateSpecializationDecl for 
vector<int> refers to the ClassTemplateDecl for 'vector' and has a set of 
template arguments containing just 'int'. Other than that, however, a 
ClassTemplateSpecializationDecl is like any other CXXRecordDecl, with bases, 
members, etc.

It's important to note that class template specializations are never found by 
name lookup. Rather, name lookup finds the ClassTemplateDecl ('vector'), and 
then looks up the appropriate specialization based on the template arguments. 
So, both the class template and its specializations need to be extracted from 
DWARF for expression parsing. Specifically, LLDB will have to go through the 
following steps when a class template specialization is encountered:

        1) If it doesn't already exist, create a ClassTemplateDecl to represent 
the template. Using DW_TAG_template_type_parameter and 
DW_TAG_template_value_parameter, it should be possible to reconstruct the 
template parameter list. That, along with the name, context, and kind of class 
template (class/struct/union) is enough to build a forward declaration of the 
ClassTemplateDecl, which is enough for expression parsing to work [*].

        2) Determine the template arguments used to generate the  template 
instantiation/specialization based on the DW_AT_type/DW_AT_const_value/etc. 
tags. At this point, we've identified the core components of the class template 
instantiation/specialization.

        3) Use the ClassTemplateDecl's findSpecialization() method to find the 
specialization; if it isn't there already, create a 
ClassTemplateSpecializationDecl and add it with AddSpecialization. The 
definition of the ClassTemplateSpecializationDecl can be read in the same way 
as any other CXXRecordDecl.

I suspect we'll have to add another callback to ExternalASTSource that lets 
LLDB look for specializations when one is requested, e.g., when Clang parses 
"vector<int>", LLDB needs to get the chance to look for that specialization in 
the DWARF entries. 

        - Doug

[*] DWARF doesn't have enough information to actually recreate the template 
definition, so template *instantiation* won't be possible. However, being able 
to use specializations/instantiations that were written out to DWARF would be 
very helpful.
_______________________________________________
lldb-dev mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev

Reply via email to