<div dir="ltr"><div class="gmail_default"><font face="verdana, sans-serif">Hi, Everyone.</font><br></div><div class="gmail_default"><font face="verdana, sans-serif"><br></font></div><div class="gmail_default"><font face="verdana, sans-serif">Current implementation of CPlusPlusLanguage::MethodName:<wbr>:Parse() doesn't cover full extent of possible function declarations, </font></div><div class="gmail_default"><font face="verdana, sans-serif">or even declarations returned by abi::__cxa_demangle. </font></div><div class="gmail_default"><font face="verdana, sans-serif"><br></font></div><div class="gmail_default"><font face="verdana, sans-serif">Consider this code:</font></div><div class="gmail_default"><font face="verdana, sans-serif">------------------------------<wbr>--------------------<br></font></div><div class="gmail_default"><pre style="font-size:11.726px;white-space:pre-wrap;max-width:80em;padding-left:0.7em;color:rgb(0,0,0)"><font face="verdana, sans-serif">#include <stdio.h>
#include <functional>
#include <vector>

void func() {
  printf("func() was called\n");
}

struct Class
{
  Class() {
    printf("ctor was called\n");
  }

  Class(const Class& c) {
    printf("copy ctor was called\n");
  }

  ~Class() {
    printf("dtor was called\n");
  }
};


int main() {
  std::function<void()> f = func;
  f();

  Class c;
  std::vector<Class> v;
  v.push_back(c);

  return 0;
}
</font></pre><div><font face="verdana, sans-serif">------------------------------<wbr>--------------------<br></font></div><div><font face="verdana, sans-serif"><br></font></div><div><font face="verdana, sans-serif">When compiled It has at least two symbols that currently cannot be correctly parsed by MethodName::Parse() .</font></div><div><pre style="font-size:11.726px;white-space:pre-wrap;max-width:80em;padding-left:0.7em;color:rgb(0,0,0)"><font face="verdana, sans-serif">void std::vector<Class, std::allocator<Class> >::_M_emplace_back_aux<Class const&>(Class const&)
void (* const&std::_Any_data::_M_<wbr>access<void (*)()>() const)() - a template function that returns a reference to a function pointer.
</font></pre></div><div><font face="verdana, sans-serif">It causes incorrect behavior in avoid-stepping and sometimes messes printing of thread backtrace.</font></div><div><font face="verdana, sans-serif"><br></font></div><div><font face="verdana, sans-serif">I would like to solve this issue, but current implementation of method name parsing doesn't seem sustainable. </font></div><div><font face="verdana, sans-serif">Clever substrings and regexs are fine for trivial cases, but they become a nightmare once we consider more complex cases.</font></div><div><font face="verdana, sans-serif">That's why I'd like to have code that follows some kind of grammar describing function declarations.</font></div><div><font face="verdana, sans-serif"><br></font></div><div><font face="verdana, sans-serif">As I see it, choices for new implementation of </font><span style="font-family:verdana,sans-serif">MethodName::Parse() </span><span style="font-family:verdana,sans-serif">are</span></div><div><font face="verdana, sans-serif">1. Reuse clang parsing code.</font></div><div><font face="verdana, sans-serif">2. Parser generated by bison.</font></div><div><font face="verdana, sans-serif">3. Handwritten recursive descent parser.</font></div><div><font face="verdana, sans-serif"><br></font></div><div><font face="verdana, sans-serif">I looked at the option #1, at it appears to be impossible to reuse clang parser for this kind of zero-context parsing. </font></div><div><font face="verdana, sans-serif">Especially given that we care about performance of this code. </font><span style="font-family:verdana,sans-serif">Clang C++ lexer on the other hand can be reused.</span></div><div><span style="font-family:verdana,sans-serif"><br></span></div><div><span style="font-family:verdana,sans-serif">Option #2. Using bison is tempting, but it would require introduction of new compile time dependency. </span></div><div><span style="font-family:verdana,sans-serif">That might be especially inconvenient on Windows.</span></div><div><span style="font-family:verdana,sans-serif"><br></span></div><div><span style="font-family:verdana,sans-serif">That's why I think option #3 is the way to go. Recursive descent parser that reuses a C++ lexer from clang. </span></div><div><span style="font-family:verdana,sans-serif"><br></span></div><div><span style="font-family:verdana,sans-serif">LLDB doesn't need to parse everything (</span><span style="font-family:verdana,sans-serif">e.g. we don't care about details of function arguments), but it needs to be able to handle tricky return types and base names.</span></div><div><font face="verdana, sans-serif">Eventually new implementation should be able to parse signature of every method generated by STL.  </font></div><div><span style="font-family:verdana,sans-serif"><br></span></div><div><font face="verdana, sans-serif">Before starting implementation, I'd love to get some feedback. It might be that my overlooking something important.</font></div><div><br></div></div><div><font face="verdana, sans-serif">-- <br></font></div><div class="gmail-m_-1339871576848199557gmail_signature"><div dir="ltr"><font face="verdana, sans-serif">Thanks,</font><div><font face="verdana, sans-serif">Eugene Zemtsov.</font></div></div></div>
</div>