<html>
    <head>
      <base href="http://llvm.org/bugs/" />
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW --- - clang_equalCursors() invalid result"
   href="http://llvm.org/bugs/show_bug.cgi?id=18410">18410</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>clang_equalCursors() invalid result
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>Macintosh
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>MacOS X
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>libclang
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>lucas.soltic@orange.fr
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvmbugs@cs.uiuc.edu
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Created <span class=""><a href="attachment.cgi?id=11833" name="attach_11833" title="The source of the program used to generate the error">attachment 11833</a> <a href="attachment.cgi?id=11833&action=edit" title="The source of the program used to generate the error">[details]</a></span>
The source of the program used to generate the error

Hello,

I use the C interface of libclang from trunk (revision 198681) and the visitor
API through clang_visitChildren().

In order to maintain a context for each expression (ie. this expression is in a
function which is in a namespace) I heavily rely on clang_equalCursors(). The
context is a stack containing CXCursors. I do as follow:
- I always tell libclang to visit nodes recursively
- Initially, I put the translation unit node in that context
- Each time my visitor callback is called, I look where is the parent in that
context. The parent is given by a parameter:
CXChildVisitResult visitNodeCallback(CXCursor cursor, CXCursor parent,
CXClientData client_data)
- That means that if the parent is the current context head, libclang just went
deeper in the AST
- If the parent is somewhere upper in the context, libclang went back somewhere
in the AST, in this case we remove the CXCursors in the context that are after
our found parent

This algorithm works nicely for most cases. However I have encountered a case
where it doesn't work: with a specific declaration from stl_pair.h. For some
reason, clang_equalCursors() tells that absolutely no CXCursor in the context
is the parent (not even the translation unit) which — according to my algorithm
— means that the current expression is not even in the same translation unit.

I've attached a sample programe code that reproduces the error, and the parsed
source code that generates this case.

Lucas

PS: I don't know how to add 2 attachments so here is the sample code that —
once parsed with the program given as attachment — generates the error:
template<class _T1, class _T2>
struct pair
{
    typedef _T1 first_type;    ///<  @c first_type is the first bound type
    typedef _T2 second_type;   ///<  @c second_type is the second bound type

    _T1 first;                 ///< @c first is a copy of the first object
    _T2 second;                ///< @c second is a copy of the second object

    template<class _U1, class _U2>
    pair(const pair<_U1, _U2>& __p)
    : first(__p.first), second(__p.second) { }
};</pre>
        </div>
      </p>
      <hr>
      <span>You are receiving this mail because:</span>
      
      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>