コード例 #1
0
ファイル: sniper.cpp プロジェクト: samvv/clang-faces
int main(int argc, char *argv[])
{
  auto index = clang_createIndex(0, 0);
  auto options = clang_defaultEditingTranslationUnitOptions();
  char const *args[] = { "-x", "c++", "-std=c++11" };
  auto arg_count = sizeof( args ) / sizeof( *args );
  filename = argv[1];
  
  CXUnsavedFile *unsaved_files = NULL;
  auto unsaved_file_count = 0;
  
  tu = clang_parseTranslationUnit(index, filename.c_str(), args, arg_count,
				  unsaved_files, unsaved_file_count,
				  options );
  
  if ( !tu ) {
    std::cout << "Translation Unit Parse Failed!\n";
    return -1;
  }

  std::stringstream ss( argv[2] );
  int line, col;

  ss >> line;
  ss.get();
  ss >> col;
  std::cout << "Hello " << line << ":" << col << "\n";

  auto file = clang_getFile( tu, filename.c_str() );
  auto location = clang_getLocation( tu, file, line, col );

  
  clang_visitChildren( clang_getTranslationUnitCursor( tu ), visitor,
		       reinterpret_cast<CXClientData>(0) );
  
  auto cursor = clang_getCursor( tu, location );
  auto refcursor = clang_getCursorReferenced( cursor );
  auto rrefcursor = clang_getCursorReferenced( refcursor );
  auto arf = clang_getTypeKindSpelling( clang_getCursorType( cursor ).kind );
  auto foo = clang_getCanonicalCursor( cursor );
  auto semparent = clang_getCursorSemanticParent( cursor );
  auto lexparent = clang_getCursorLexicalParent( cursor );

  std::cout << cursor << "\n";
  std::cout << refcursor << "\n";
  std::cout << rrefcursor << "\n";
  std::cout << clang_getCString(arf) << "\n";
  std::cout << foo << "\n";
  std::cout << "Parent: " << semparent << "\n";
  std::cout << "LexParent: " << lexparent << "\n";
  
  //clang_visitChildren( semparent, visitor, reinterpret_cast<CXClientData>(0) );
  clang_disposeString( arf );

  return 0;
}
コード例 #2
0
ファイル: IndexerJob.cpp プロジェクト: jbulow/rtags
static inline CXCursor findDestructorForDelete(const CXCursor &deleteStatement)
{
    const CXCursor child = RTags::findFirstChild(deleteStatement);
    CXCursorKind kind = clang_getCursorKind(child);
    switch (kind) {
    case CXCursor_UnexposedExpr:
    case CXCursor_CallExpr:
        break;
    default:
        return nullCursor;
    }

    const CXCursor var = clang_getCursorReferenced(child);
    kind = clang_getCursorKind(var);
    switch (kind) {
    case CXCursor_VarDecl:
    case CXCursor_FieldDecl:
    case CXCursor_ParmDecl:
    case CXCursor_CXXMethod:
    case CXCursor_FunctionDecl:
        break;
    default:
        if (!clang_isInvalid(kind)) {
            error() << "Got unexpected cursor" << deleteStatement << var;
            // assert(0);
        }
        return nullCursor;
    }

    CXCursor ref = RTags::findChild(var, CXCursor_TypeRef);
    if (ref != CXCursor_TypeRef)
        ref = RTags::findChild(var, CXCursor_TemplateRef);
    kind = clang_getCursorKind(ref);
    switch (kind) {
    case CXCursor_TypeRef:
    case CXCursor_TemplateRef:
        break;
    default:
        return nullCursor;
    }

    const CXCursor referenced = clang_getCursorReferenced(ref);
    kind = clang_getCursorKind(referenced);
    switch (kind) {
    case CXCursor_StructDecl:
    case CXCursor_ClassDecl:
    case CXCursor_ClassTemplate:
        break;
    default:
        return nullCursor;
    }
    const CXCursor destructor = RTags::findChild(referenced, CXCursor_Destructor);
    return destructor;
}
コード例 #3
0
Location TranslationUnit::GetDeclarationLocation(
  int line,
  int column,
  const std::vector< UnsavedFile > &unsaved_files,
  bool reparse ) {
  if ( reparse )
    Reparse( unsaved_files );

  unique_lock< mutex > lock( clang_access_mutex_ );

  if ( !clang_translation_unit_ )
    return Location();

  CXCursor cursor = GetCursor( line, column );

  if ( !CursorIsValid( cursor ) )
    return Location();

  CXCursor referenced_cursor = clang_getCursorReferenced( cursor );

  if ( !CursorIsValid( referenced_cursor ) )
    return Location();

  CXCursor canonical_cursor = clang_getCanonicalCursor( referenced_cursor );

  if ( !CursorIsValid( canonical_cursor ) )
    return Location( clang_getCursorLocation( referenced_cursor ) );

  return Location( clang_getCursorLocation( canonical_cursor ) );
}
コード例 #4
0
ファイル: c-index-test.c プロジェクト: albertz/clang
static void PrintCursor(CXCursor Cursor) {
  if (clang_isInvalid(Cursor.kind)) {
    CXString ks = clang_getCursorKindSpelling(Cursor.kind);
    printf("Invalid Cursor => %s", clang_getCString(ks));
    clang_disposeString(ks);
  }
  else {
    CXString string, ks;
    CXCursor Referenced;
    unsigned line, column;

    ks = clang_getCursorKindSpelling(Cursor.kind);
    string = clang_getCursorSpelling(Cursor);
    printf("%s=%s", clang_getCString(ks),
                    clang_getCString(string));
    clang_disposeString(ks);
    clang_disposeString(string);

    Referenced = clang_getCursorReferenced(Cursor);
    if (!clang_equalCursors(Referenced, clang_getNullCursor())) {
      CXSourceLocation Loc = clang_getCursorLocation(Referenced);
      clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
      printf(":%d:%d", line, column);
    }

    if (clang_isCursorDefinition(Cursor))
      printf(" (Definition)");
  }
}
コード例 #5
0
ファイル: clic_add.cpp プロジェクト: gurjeet/clang_indexer
    virtual enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent) {
        CXFile file;
        unsigned int line, column, offset;
        clang_getInstantiationLocation(
                clang_getCursorLocation(cursor),
                &file, &line, &column, &offset);
        CXCursorKind kind = clang_getCursorKind(cursor);
        const char* cursorFilename = clang_getCString(clang_getFileName(file));

        if (!clang_getFileName(file).data || strcmp(cursorFilename, translationUnitFilename) != 0) {
            return CXChildVisit_Continue;
        }

        CXCursor refCursor = clang_getCursorReferenced(cursor);
        if (!clang_equalCursors(refCursor, clang_getNullCursor())) {
            CXFile refFile;
            unsigned int refLine, refColumn, refOffset;
            clang_getInstantiationLocation(
                    clang_getCursorLocation(refCursor),
                    &refFile, &refLine, &refColumn, &refOffset);

            if (clang_getFileName(refFile).data) {
                std::string referencedUsr(clang_getCString(clang_getCursorUSR(refCursor)));
                if (!referencedUsr.empty()) {
                    std::stringstream ss;
                    ss << cursorFilename
                       << ":" << line << ":" << column << ":" << kind;
                    std::string location(ss.str());
                    usrToReferences[referencedUsr].insert(location);
                }
            }
        }
        return CXChildVisit_Recurse;
    }
コード例 #6
0
ファイル: clang_utils.cpp プロジェクト: AndrianDTR/codelite
bool ClangUtils::GetCursorAt(CXTranslationUnit &unit, const wxString &filename, int line, int col, CXCursor &cur)
{
	CXFile file1;
	CXCursor cursor;
	CXSourceLocation loc;
	file1  = clang_getFile    (unit, filename.mb_str(wxConvUTF8).data());
	loc    = clang_getLocation(unit, file1, line, col);
	cursor = clang_getCursor  (unit, loc);
	
	if(clang_isInvalid(cursor.kind))
		return false;

	if(cursor.kind == CXCursor_MemberRef     ||
	   cursor.kind == CXCursor_MemberRefExpr ||
	   cursor.kind == CXCursor_TypeRef       ||
	   cursor.kind == CXCursor_DeclRefExpr   ||
	   cursor.kind == CXCursor_TemplateRef   ||
	   cursor.kind == CXCursor_NamespaceRef  
	)
	{
		cursor = clang_getCursorReferenced(cursor);
	}
	cur = cursor;
	return true;
}
コード例 #7
0
DocumentationData TranslationUnit::GetDocsForLocationInFile(
  int line,
  int column,
  const std::vector< UnsavedFile > &unsaved_files,
  bool reparse ) {

  if ( reparse )
    Reparse( unsaved_files );

  unique_lock< mutex > lock( clang_access_mutex_ );

  if ( !clang_translation_unit_ )
    return DocumentationData();

  CXCursor cursor = GetCursor( line, column );

  if ( !CursorIsValid( cursor ) )
    return DocumentationData();

  // If the original cursor is a reference, then we return the documentation
  // for the type/method/etc. that is referenced
  CXCursor referenced_cursor = clang_getCursorReferenced( cursor );

  if ( CursorIsValid( referenced_cursor ) )
    cursor = referenced_cursor;

  // We always want the documentation associated with the canonical declaration
  CXCursor canonical_cursor = clang_getCanonicalCursor( cursor );

  if ( !CursorIsValid( canonical_cursor ) )
    return DocumentationData();

  return DocumentationData( canonical_cursor );
}
コード例 #8
0
ファイル: DumpThread.cpp プロジェクト: powen-l/emacs.d
CXChildVisitResult DumpThread::visitor(CXCursor cursor, CXCursor, CXClientData userData)
{
    DumpThread *that = reinterpret_cast<DumpThread*>(userData);
    assert(that);
    CXSourceLocation location = clang_getCursorLocation(cursor);
    if (!clang_equalLocations(location, nullLocation)) {
        CXString file;
        unsigned line, col;
        clang_getPresumedLocation(location, &file, &line, &col);
        Path path = RTags::eatString(file);
        if (!path.isEmpty()) {
            uint32_t &fileId = that->mFiles[path];
            if (!fileId) {
                const Path resolved = path.resolved();
                fileId = Location::insertFile(resolved);
                that->mFiles[path] = that->mFiles[resolved] = fileId;
            }
            if (that->mQueryFlags & QueryMessage::DumpIncludeHeaders || fileId == that->mSource.fileId) {
                const Location loc(fileId, line, col);
                String message;
                message.reserve(256);
                if (!(that->mQueryFlags & QueryMessage::NoContext))
                    message += loc.context();

                CXSourceRange range = clang_getCursorExtent(cursor);
                CXSourceLocation rangeEnd = clang_getRangeEnd(range);
                unsigned endLine, endColumn;
                clang_getPresumedLocation(rangeEnd, 0, &endLine, &endColumn);
                if (endLine == line) {
                    message += String::format<32>(" // %d-%d, %d: ", col, endColumn, that->mIndentLevel);
                } else {
                    message += String::format<32>(" // %d-%d:%d, %d: ", col, endLine, endColumn, that->mIndentLevel);
                }
                message += RTags::cursorToString(cursor, RTags::AllCursorToStringFlags);
                message.append(" " + RTags::typeName(cursor) + " ");
                CXCursor ref = clang_getCursorReferenced(cursor);
                if (clang_equalCursors(ref, cursor)) {
                    message.append("refs self");
                } else if (!clang_equalCursors(ref, nullCursor)) {
                    message.append("refs ");
                    message.append(RTags::cursorToString(ref, RTags::AllCursorToStringFlags));
                }

                CXCursor canonical = clang_getCanonicalCursor(cursor);
                if (!clang_equalCursors(canonical, cursor) && !clang_equalCursors(canonical, nullCursor)) {
                    message.append("canonical ");
                    message.append(RTags::cursorToString(canonical, RTags::AllCursorToStringFlags));
                }

                that->writeToConnetion(message);
            }
        }
    }
    ++that->mIndentLevel;
    clang_visitChildren(cursor, DumpThread::visitor, userData);
    --that->mIndentLevel;
    return CXChildVisit_Continue;
}
コード例 #9
0
ファイル: ClangIndexer.cpp プロジェクト: clapautius/rtags
void ClangIndexer::superclassTemplateMemberFunctionUgleHack(const CXCursor &cursor, CXCursorKind kind,
                                                            const Location &location, const CXCursor &ref,
                                                            const CXCursor &parent)
{
    // This is for references to superclass template functions. Awful awful
    // shit. See https://github.com/Andersbakken/rtags/issues/62 and commit
    // for details. I really should report this as a bug.
    if (kind == CXCursor_MemberRefExpr && clang_getCursorKind(parent) == CXCursor_CallExpr) {
        const CXCursor templateRef = RTags::findChild(cursor, CXCursor_TemplateRef);
        if (templateRef == CXCursor_TemplateRef) {
            const CXCursor classTemplate = clang_getCursorReferenced(templateRef);
            if (classTemplate == CXCursor_ClassTemplate) {
                FILE *f = fopen(location.path().constData(), "r");
                if (f) {
                    const CXSourceRange range = clang_getCursorExtent(cursor);
                    const CXSourceLocation end = clang_getRangeEnd(range);
                    unsigned offset;
                    clang_getSpellingLocation(end, 0, 0, 0, &offset);

                    String name;
                    while (offset > 0) {
                        fseek(f, --offset, SEEK_SET);
                        char ch = static_cast<char>(fgetc(f));
                        if (isalnum(ch) || ch == '_' || ch == '~') {
                            name.prepend(ch);
                        } else {
                            break;
                        }
                    }
                    fclose(f);
                    if (!name.isEmpty()) {
                        RTags::Filter out;
                        out.kinds.insert(CXCursor_MemberRefExpr);
                        const int argCount = RTags::children(parent, RTags::Filter(), out).size();
                        RTags::Filter in(RTags::Filter::And);
                        in.names.insert(name);
                        in.argumentCount = argCount;
                        const List<CXCursor> alternatives = RTags::children(classTemplate, in);
                        switch (alternatives.size()) {
                        case 1:
                            // ### not sure this is correct with line/col
                            handleReference(cursor, kind, Location(location.fileId(), location.line(), location.column() + 1), alternatives.first(), parent);
                            break;
                        case 0:
                            break;
                        default:
                            warning() << "Can't decide which of these cursors are right for me"
                                      << cursor << alternatives
                                      << "Need to parse types";
                            break;
                        }
                    }
                }
            }
        }
    }
}
コード例 #10
0
ファイル: DumpThread.cpp プロジェクト: vporpo/rtags
void DumpThread::checkIncludes(const Location &location, const CXCursor &cursor)
{
    if (clang_getCursorKind(cursor) == CXCursor_InclusionDirective) {
        handleInclude(location, cursor);
    } else {
        const CXCursor ref = clang_getCursorReferenced(cursor);
        if (!clang_equalCursors(cursor, nullCursor) && !clang_equalCursors(cursor, ref)) {
            handleReference(location, ref);
        }
    }
}
コード例 #11
0
ファイル: main.cpp プロジェクト: styxyang/clang-faces
std::string AdvancedCallExprHandler( CXCursor cursor )
{
    auto newcursor = clang_getCursorReferenced( cursor );
    std::string result = "Function";
  
    if ( newcursor.kind == CXCursor_Constructor )
	result = "Identifier";
    else 
	clang_visitChildren( cursor, CallExprVisitor,
			     reinterpret_cast<std::string *>(&result) );
    return result;
}
コード例 #12
0
ファイル: Highlighter.cpp プロジェクト: animatedb/oovaide
void Tokenizer::getMethodNameAtLocation(size_t origOffset, OovString &className,
        OovString &methodName)
    {
    CLangAutoLock lock(mCLangLock, __LINE__, this);
    CXCursor startCursor = getCursorAtOffset(mTransUnit, mSourceFile, origOffset);
    std::string method = getDisposedString(clang_getCursorDisplayName(startCursor));
    size_t pos = method.find('(');
    if(pos != std::string::npos)
        {
        method.erase(pos);
        }
    methodName = method;

    // Attempt to go to the definition from the following places:
    //  A header file method declaration or inline definition.
    //  A source file where the method is defined.
    //  A call to a method through a pointer, or directly (self)

    // Attempt to go directly to the definition, it will work if it is in this
    // translation unit.
    CXCursor methodDefCursor = clang_getCursorDefinition(startCursor);
    CXCursor classCursor = startCursor;         // Just default to something.

    // Method call can return invalid file when the definition is not in this
    // translation unit.
    if(clang_getCursorKind(methodDefCursor) != CXCursor_InvalidFile)
        {
        // In this translation unit (either header or source)
        // At this point, the semantic parent of the method definition is
        // the class.
        classCursor = clang_getCursorSemanticParent(methodDefCursor);
        }
    else
        {
        // In a file that isn't in this translation unit
        if(startCursor.kind == CXCursor_CXXMethod)
            {
            classCursor = clang_getCursorSemanticParent(startCursor);
            }
        else    // Handle a call - The cursor is usually a compound statement?
            {
            // The definition was not available, so instead, look for the
            // declaration and class from through the referenced cursor.
            CXCursor refCursor = clang_getCursorReferenced(startCursor);
            classCursor = clang_getCursorSemanticParent(refCursor);
            }
        }

    std::string classCursorStr = getDisposedString(clang_getCursorDisplayName(classCursor));
    className = classCursorStr;
    }
コード例 #13
0
Location TranslationUnit::GetDeclarationLocationForCursor( CXCursor cursor ) {
  CXCursor referenced_cursor = clang_getCursorReferenced( cursor );

  if ( !CursorIsValid( referenced_cursor ) ) {
    return Location();
  }

  CXCursor canonical_cursor = clang_getCanonicalCursor( referenced_cursor );

  if ( !CursorIsValid( canonical_cursor ) ) {
    return Location( clang_getCursorLocation( referenced_cursor ) );
  }

  return Location( clang_getCursorLocation( canonical_cursor ) );
}
コード例 #14
0
    location translation_unit::declaration_location_at(uint32_t row, uint32_t col) {
        CXCursor cursor = get_cursor_at(row, col);
        CXCursor ref = clang_getCursorReferenced( cursor );

        if (clang_Cursor_isNull(ref) || clang_isInvalid(clang_getCursorKind(ref)))
            return {"", 0, 0};

        CXSourceLocation loc = clang_getCursorLocation(ref);

        CXFile file;
        uint32_t nrow, ncol, offset = 0;

        clang_getExpansionLocation( loc, &file, &nrow, &ncol, &offset );
        return { cx2std(clang_getFileName(file)), nrow, ncol };
    }
コード例 #15
0
ファイル: Cursor.cpp プロジェクト: pegacorn/libclang-cpp
Cursor Cursor::referenced() const
{
	if ( !m_referenced ) {
		CXCursor cx_cursor(clang_getCursorReferenced(m_cx_cursor));
		if ( is_null(cx_cursor) ) {
			if ( is_null(m_cx_cursor) ) {
				CLANGXX_THROW_LogicError("Error retrieving a cursor representing the entity that this cursor references.");
			}
			m_referenced.reset(new Cursor());
		}
		else {
			m_referenced.reset(new Cursor(std::move(cx_cursor), m_translation_unit));
		}
	}
	return *m_referenced;
}
コード例 #16
0
ファイル: clangparser.cpp プロジェクト: bithium/doxygen
void ClangParser::linkIdentifier(CodeOutputInterface &ol,FileDef *fd,
    uint &line,uint &column,const char *text,int tokenIndex)
{
  CXCursor c = p->cursors[tokenIndex];
  CXCursor r = clang_getCursorReferenced(c);
  if (!clang_equalCursors(r, c))
  {
    c=r; // link to referenced location
  }
  CXCursor t = clang_getSpecializedCursorTemplate(c);
  if (!clang_Cursor_isNull(t) && !clang_equalCursors(t,c))
  {
    c=t; // link to template 
  }
  CXString usr = clang_getCursorUSR(c);
  const char *usrStr = clang_getCString(usr);

  Definition *d = usrStr ? Doxygen::clangUsrMap->find(usrStr) : 0;
  //CXCursorKind kind = clang_getCursorKind(c);
  //if (d==0)
  //{
  //  printf("didn't find definition for '%s' usr='******' kind=%d\n",
  //      text,usrStr,kind);
  //}
  //else
  //{
  //  printf("found definition for '%s' usr='******' name='%s'\n",
  //      text,usrStr,d->name().data());
  //}
  if (d && d->isLinkable())
  {
    if (g_insideBody &&
        g_currentMemberDef && d->definitionType()==Definition::TypeMember && 
        (g_currentMemberDef!=d || g_currentLine<line)) // avoid self-reference
    {
      addDocCrossReference(g_currentMemberDef,(MemberDef*)d);
    }
    writeMultiLineCodeLink(ol,fd,line,column,d,text);
  }
  else
  {
    codifyLines(ol,fd,text,line,column);
  }
  clang_disposeString(usr);
}
コード例 #17
0
ファイル: main.cpp プロジェクト: styxyang/clang-faces
std::ostream& operator<<( std::ostream &os, CXCursor cursor )
{
    auto spelling = clang_getCursorKindSpelling( cursor.kind );
    auto morespell = clang_getCursorSpelling( cursor );
  
    os << clang_getCString( spelling ) << ":"
       << clang_getCString( morespell ) << " ";

    clang_disposeString( spelling );
    clang_disposeString( morespell );

    auto refcursor = clang_getCursorReferenced( cursor );
    if ( clang_equalCursors( refcursor, clang_getNullCursor() )||
	 clang_equalCursors( refcursor, cursor ) )
	return os;
    
    return os << " [ " << refcursor << " ] ";
}
コード例 #18
0
void ClangParser::linkIdentifier(CodeOutputInterface &ol, QSharedPointer<FileDef> fd,
                                 uint &line, uint &column, const QString &text, int tokenIndex)
{
   CXCursor c = p->cursors[tokenIndex];
   CXCursor r = clang_getCursorReferenced(c);

   if (! clang_equalCursors(r, c)) {
      // link to referenced location
      c = r; 
   }

   CXCursor t = clang_getSpecializedCursorTemplate(c);
  
   if (! clang_Cursor_isNull(t) && !clang_equalCursors(t, c)) {
      // link to template
      c = t; 
   }

   CXString usr = clang_getCursorUSR(c);
   const char *usrStr = clang_getCString(usr);

   QSharedPointer<Definition> d;

   if (usrStr) {
      d = Doxy_Globals::clangUsrMap.value(usrStr);
   }
   
   if (d && d->isLinkable()) {
      if (g_insideBody && g_currentMemberDef && d->definitionType() == Definition::TypeMember &&
            (g_currentMemberDef != d || g_currentLine < line)) { 

         // avoid self-reference
         addDocCrossReference(g_currentMemberDef, d.dynamicCast<MemberDef>());
      }

      writeMultiLineCodeLink(ol, fd, line, column, d, text);

   } else {
      codifyLines(ol, fd, text, line, column, "");
   }

   clang_disposeString(usr);
}
コード例 #19
0
ファイル: ClangIndexer.cpp プロジェクト: nurpax/rtags
static CXChildVisitResult resolveAutoTypeRefVisitor(CXCursor cursor, CXCursor, CXClientData data)
{
    ResolveAutoTypeRefUserData *userData = reinterpret_cast<ResolveAutoTypeRefUserData*>(data);
    const CXCursorKind kind = clang_getCursorKind(cursor);
    // userData->chain.append(kind);
    // error() << "Got here" << cursor << userData->chain;
    ++userData->index;
    switch (kind) {
    case CXCursor_TypeRef:
    case CXCursor_TemplateRef:
        // error() << "Found typeRef" << cursor;
        userData->ref = cursor;
        return CXChildVisit_Break;
    case CXCursor_UnexposedExpr: {
        CXCursor ref = clang_getCursorReferenced(cursor);
        // error() << "got unexposed expr ref" << ref;
        switch (clang_getCursorKind(ref)) {
        case CXCursor_VarDecl:
        case CXCursor_FunctionDecl:
        case CXCursor_CXXMethod: {
            ResolveAutoTypeRefUserData u = { nullCursor, 0 };
            clang_visitChildren(ref, resolveAutoTypeRefVisitor, &u);
            // error() << "Visited for typeRef" << u.ref
            //         << clang_isInvalid(clang_getCursorKind(u.ref))
            //         << u.chain;
            if (!clang_equalCursors(u.ref, nullCursor)) {
                userData->ref = u.ref;
                return CXChildVisit_Break;
            }
            break; }
        default:
            break;
        }
        break; }
    case CXCursor_ParmDecl:
        // nothing to find here
        return CXChildVisit_Break;
    default:
        break;
    }
    return CXChildVisit_Recurse;
}
コード例 #20
0
ファイル: clangtest.c プロジェクト: HackerFoo/rtags
static enum CXChildVisitResult visit(CXCursor cursor, CXCursor parent, CXClientData userData)
{
    (void)parent;
    int indent = *(int*)userData;
    int i;
    for (i=0; i<indent; ++i) {
        printf("  ");
    }
    printCursor(cursor);
    CXCursor ref = clang_getCursorReferenced(cursor);
    if (!clang_isInvalid(clang_getCursorKind(ref)) && !clang_equalCursors(ref, cursor)) {
        for (i=0; i<indent; ++i) {
            printf("  ");
        }
        printf("-> ");
        printCursor(ref);
    }
    ++indent;
    clang_visitChildren(cursor, visit, &indent);
    return CXChildVisit_Continue;
}
コード例 #21
0
ファイル: main.cpp プロジェクト: styxyang/clang-faces
std::string CursorKindSpelling( CXCursor cursor )
{
    auto kind = cursor.kind;
    CXCursor newcursor;
  
    switch( kind ) {
	case CXCursor_DeclRefExpr:
	case CXCursor_MemberRefExpr:
	    newcursor = clang_getCursorReferenced( cursor );
	    std::cout << "NEW CURSOR: " << newcursor << "\n";
	    return CursorKindSpelling( newcursor );

	case CXCursor_CallExpr:
	    return AdvancedCallExprHandler( cursor );
    
	case CXCursor_CXXMethod:
	case CXCursor_FunctionDecl:
	case CXCursor_Constructor:
	case CXCursor_Destructor:
	case CXCursor_OverloadedDeclRef:
	    return "Function";

	case CXCursor_ParmDecl:
	case CXCursor_VarDecl:
	case CXCursor_FieldDecl:
	case CXCursor_MemberRef:
	case CXCursor_VariableRef:
	case CXCursor_NonTypeTemplateParameter:
	    return "Variable";

	case CXCursor_NamespaceRef:
	    return "Namespace";
    
	default:
	    return "Identifier";
    }

    return {};
}
コード例 #22
0
ファイル: IndexerJob.cpp プロジェクト: jbulow/rtags
CXChildVisitResult IndexerJob::verboseVisitor(CXCursor cursor, CXCursor, CXClientData userData)
{
    VerboseVisitorUserData *u = reinterpret_cast<VerboseVisitorUserData*>(userData);
    Location loc = u->job->createLocation(cursor);
    if (loc.fileId()) {
        CXCursor ref = clang_getCursorReferenced(cursor);

        VerboseVisitorUserData *u = reinterpret_cast<VerboseVisitorUserData*>(userData);
        if (u->indent >= 0)
            u->out += String(u->indent, ' ');
        u->out += RTags::cursorToString(cursor);
        if (clang_equalCursors(ref, cursor)) {
            u->out += " refs self";
        } else if (!clang_equalCursors(ref, nullCursor)) {
            u->out += " refs " + RTags::cursorToString(ref);
        }

        if (loc.fileId() && u->job->mVisitedFiles.contains(loc.fileId())) {
            if (u->job->mData->references.contains(loc)) {
                u->out += " used as reference\n";
            } else if (u->job->mData->symbols.contains(loc)) {
                u->out += " used as cursor\n";
            } else {
                u->out += " not used\n";
            }
        } else {
            u->out += " not indexed\n";
        }
    }
    if (u->indent >= 0) {
        u->indent += 2;
        clang_visitChildren(cursor, IndexerJob::verboseVisitor, userData);
        u->indent -= 2;
        return CXChildVisit_Continue;
    } else {
        return CXChildVisit_Recurse;
    }
}
コード例 #23
0
ファイル: IndexerJob.cpp プロジェクト: jbulow/rtags
CXChildVisitResult IndexerJob::dumpVisitor(CXCursor cursor, CXCursor, CXClientData userData)
{
    DumpUserData *dump = reinterpret_cast<DumpUserData*>(userData);
    assert(dump);
    assert(dump->job);
    Location loc = dump->job->createLocation(cursor);
    if (loc.fileId()) {
        CXCursor ref = clang_getCursorReferenced(cursor);
        String out;
        out.reserve(256);
        int col = -1;
        if (dump->showContext) {
            out.append(loc.context(&col));
            if (col != -1) {
                out.append(String::format<32>(" // %d, %d: ", col, dump->indentLevel));
            } else {
                out.append(String::format<32>(" // %d: ", dump->indentLevel));
            }
        } else {
            out.append(String(dump->indentLevel * 2, ' '));
        }
        out.append(RTags::cursorToString(cursor, RTags::AllCursorToStringFlags));
        out.append(" " + typeName(cursor) + " ");
        if (clang_equalCursors(ref, cursor)) {
            out.append("refs self");
        } else if (!clang_equalCursors(ref, nullCursor)) {
            out.append("refs ");
            out.append(RTags::cursorToString(ref, RTags::AllCursorToStringFlags));
        }
        dump->job->write(out);
    }
    ++dump->indentLevel;
    clang_visitChildren(cursor, IndexerJob::dumpVisitor, userData);
    --dump->indentLevel;
    return CXChildVisit_Continue;
}
コード例 #24
0
ファイル: DumpThread.cpp プロジェクト: vporpo/rtags
CXChildVisitResult DumpThread::visit(const CXCursor &cursor)
{
    if (isAborted())
        return CXChildVisit_Break;
    const Location location = createLocation(cursor);
    if (!location.isNull()) {
        if (mQueryFlags & QueryMessage::DumpCheckIncludes) {
            checkIncludes(location, cursor);
            return CXChildVisit_Recurse;
        } else {
            Flags<Location::ToStringFlag> locationFlags;
            if (mQueryFlags & QueryMessage::NoColor)
                locationFlags |= Location::NoColor;

            CXSourceRange range = clang_getCursorExtent(cursor);
            CXSourceLocation rangeEnd = clang_getRangeEnd(range);
            unsigned int endLine, endColumn;
            clang_getPresumedLocation(rangeEnd, 0, &endLine, &endColumn);
            if (!(mQueryFlags & QueryMessage::DumpIncludeHeaders) && location.fileId() != mSource.fileId) {
                return CXChildVisit_Continue;
            }

            String message;
            message.reserve(256);

            if (!(mQueryFlags & QueryMessage::NoContext)) {
                message = location.context(locationFlags);
            }

            if (endLine == location.line()) {
                message += String::format<32>(" // %d-%d, %d: ", location.column(), endColumn, mIndentLevel);
            } else {
                message += String::format<32>(" // %d-%d:%d, %d: ", location.column(), endLine, endColumn, mIndentLevel);
            }
            message += RTags::cursorToString(cursor, RTags::AllCursorToStringFlags);
            message.append(" " + RTags::typeName(cursor));;
            if (clang_getCursorKind(cursor) == CXCursor_VarDecl) {
                const std::shared_ptr<RTags::Auto> autoResolved = RTags::resolveAuto(cursor);
                if (autoResolved && !clang_equalCursors(autoResolved->cursor, nullCursor)) {
                    message += "auto resolves to " + RTags::cursorToString(autoResolved->cursor, RTags::AllCursorToStringFlags);
                }
            }
            CXCursor ref = clang_getCursorReferenced(cursor);
            if (clang_equalCursors(ref, cursor)) {
                message.append("refs self");
            } else if (!clang_equalCursors(ref, nullCursor)) {
                message.append("refs ");
                message.append(RTags::cursorToString(ref, RTags::AllCursorToStringFlags));
            }

            CXCursor canonical = clang_getCanonicalCursor(cursor);
            if (!clang_equalCursors(canonical, cursor) && !clang_equalCursors(canonical, nullCursor)) {
                message.append("canonical ");
                message.append(RTags::cursorToString(canonical, RTags::AllCursorToStringFlags));
            }

            CXCursor specialized = clang_getSpecializedCursorTemplate(cursor);
            if (!clang_equalCursors(specialized, cursor) && !clang_equalCursors(specialized, nullCursor)) {
                message.append("specialized ");
                message.append(RTags::cursorToString(specialized, RTags::AllCursorToStringFlags));
            }

            writeToConnetion(message);
        }
    }
    ++mIndentLevel;
    clang_visitChildren(cursor, DumpThread::visitor, this);
    if (isAborted())
        return CXChildVisit_Break;
    --mIndentLevel;
    return CXChildVisit_Continue;
}
コード例 #25
0
ファイル: IndexerJob.cpp プロジェクト: jbulow/rtags
CXChildVisitResult IndexerJob::indexVisitor(CXCursor cursor, CXCursor parent, CXClientData data)
{
    IndexerJob *job = static_cast<IndexerJob*>(data);
    {
        MutexLocker lock(&job->mMutex);
        if (job->mAborted)
            return CXChildVisit_Break;
    }

    const LastCursorUpdater updater(job->mLastCursor, cursor);

    const CXCursorKind kind = clang_getCursorKind(cursor);
    const RTags::CursorType type = RTags::cursorType(kind);
    if (type == RTags::Other)
        return CXChildVisit_Recurse;

    bool blocked = false;
    Location loc = job->createLocation(cursor, &blocked);
    if (blocked) {
        return CXChildVisit_Continue;
    } else if (loc.isNull()) {
        return CXChildVisit_Recurse;
    }

    if (testLog(VerboseDebug)) {
        Log log(VerboseDebug);
        log << cursor;
        CXCursor ref = clang_getCursorReferenced(cursor);
        if (!clang_isInvalid(clang_getCursorKind(ref)) && !clang_equalCursors(ref, cursor)) {
            log << "refs" << ref;
        }
    }
    switch (type) {
    case RTags::Cursor:
        job->handleCursor(cursor, kind, loc);
        break;
    case RTags::Include:
        job->handleInclude(cursor, kind, loc);
        break;
    case RTags::Reference:
        switch (kind) {
        case CXCursor_OverloadedDeclRef: {
            const int count = clang_getNumOverloadedDecls(cursor);
            for (int i=0; i<count; ++i) {
                const CXCursor ref = clang_getOverloadedDecl(cursor, i);
                job->handleReference(cursor, kind, loc, ref, parent);
            }
            break; }
        case CXCursor_CXXDeleteExpr:
            job->handleReference(cursor, kind, loc, findDestructorForDelete(cursor), parent);
            break;
        default:
            job->handleReference(cursor, kind, loc, clang_getCursorReferenced(cursor), parent);
            break;
        }
        break;
    case RTags::Other:
        assert(0);
        break;
    }
    return CXChildVisit_Recurse;
}
コード例 #26
0
ファイル: index-api-test.c プロジェクト: colgur/gaius
static void PrintCursor(CXCursor Cursor) {
  if (clang_isInvalid(Cursor.kind)) {
    CXString ks = clang_getCursorKindSpelling(Cursor.kind);
    printf("Invalid Cursor => %s", clang_getCString(ks));
    clang_disposeString(ks);
  }
  else {
    CXString string, ks;
    CXCursor Referenced;
    unsigned line, column;
    CXCursor SpecializationOf;
    
    ks = clang_getCursorKindSpelling(Cursor.kind);
    string = clang_getCursorSpelling(Cursor);
    printf("%s=%s", clang_getCString(ks),
                    clang_getCString(string));
    clang_disposeString(ks);
    clang_disposeString(string);

    Referenced = clang_getCursorReferenced(Cursor);
    if (!clang_equalCursors(Referenced, clang_getNullCursor())) {
      CXSourceLocation Loc = clang_getCursorLocation(Referenced);
      clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
      printf(":%d:%d", line, column);
    }

    if (clang_isCursorDefinition(Cursor))
      printf(" (Definition)");
    
    switch (clang_getCursorAvailability(Cursor)) {
      case CXAvailability_Available:
        break;
        
      case CXAvailability_Deprecated:
        printf(" (deprecated)");
        break;
        
      case CXAvailability_NotAvailable:
        printf(" (unavailable)");
        break;
    }
    
    if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
      CXType T =
        clang_getCanonicalType(clang_getIBOutletCollectionType(Cursor));
      CXString S = clang_getTypeKindSpelling(T.kind);
      printf(" [IBOutletCollection=%s]", clang_getCString(S));
      clang_disposeString(S);
    }
    
    if (Cursor.kind == CXCursor_CXXBaseSpecifier) {
      enum CX_CXXAccessSpecifier access = clang_getCXXAccessSpecifier(Cursor);
      unsigned isVirtual = clang_isVirtualBase(Cursor);
      const char *accessStr = 0;

      switch (access) {
        case CX_CXXInvalidAccessSpecifier:
          accessStr = "invalid"; break;
        case CX_CXXPublic:
          accessStr = "public"; break;
        case CX_CXXProtected:
          accessStr = "protected"; break;
        case CX_CXXPrivate:
          accessStr = "private"; break;
      }      
      
      printf(" [access=%s isVirtual=%s]", accessStr,
             isVirtual ? "true" : "false");
    }
    
    SpecializationOf = clang_getSpecializedCursorTemplate(Cursor);
    if (!clang_equalCursors(SpecializationOf, clang_getNullCursor())) {
      CXSourceLocation Loc = clang_getCursorLocation(SpecializationOf);
      CXString Name = clang_getCursorSpelling(SpecializationOf);
      clang_getInstantiationLocation(Loc, 0, &line, &column, 0);
      printf(" [Specialization of %s:%d:%d]", 
             clang_getCString(Name), line, column);
      clang_disposeString(Name);
    }
  }
}
コード例 #27
0
void
Html_File::write_token(FILE* f,
                       CXFile file,
                       CXToken tok,
                       const char* str,
                       unsigned line,
                       unsigned column)
{
  static bool preprocessor = false;
  static bool include = false;

  CXSourceLocation tloc = clang_getTokenLocation(tu_file_->tu(), tok);
  CXCursor c = clang_getCursor(tu_file_->tu(), tloc);

  if (cur_line_ <= line) cur_column_ = 1;

  for (; cur_line_ <= line; ++cur_line_)
    fprintf (f, "\n<a name=\"l%05i\"></a>%05i", cur_line_, cur_line_);

  for (; cur_column_ <= column; ++cur_column_)
    fprintf (f , " ");

  switch (clang_getTokenKind(tok)) {
  case (CXToken_Punctuation):
    if (str[0] == '#')
      preprocessor = true;
    fprintf(f, "%s", str);
    break;
  case (CXToken_Keyword):
    fprintf(f, "<span class=\"keyword\">%s</span>", str);
    break;
  case (CXToken_Comment):
    fprintf(f, "<span class=\"comment\">%s</span>", str);
    break;
  case (CXToken_Literal): {
    //include = false; // disable include links for now
    if (include) {
      include = false;
      // found an include file
      std::string t;
      const char* p = str;
      while (*p) {
        if (*p != '"')
          t += *p;
        ++p;
      }

      // first, use this file's path, then all the include paths
      bool found_include = false;
      char path[PATH_MAX];
      std::string includefile = realpath(dirname(tu_file_->source_filename()), path);
      includefile += "/" + t;
      struct stat st;
      if (stat(includefile.c_str(), &st) == 0) {
        found_include = true;
      } else {
        for (std::vector<std::string>::const_iterator i = includes_.begin(),
               e = includes_.end(); i != e; ++i) {
          includefile = realpath((*i).c_str(), path);
          includefile += "/" + t;
          if (stat(includefile.c_str(), &st) == 0) {
            found_include = true;
            break;
          }
        }
      }
      if (found_include) {
        if (files_.find(includefile) != files_.end()) {
          t = make_filename(includefile, html_dir_, prefix_, ".html", false);
          fprintf(f, "<a class=\"code\" href=\"%s\" title="">%s</a>",
                  t.c_str(), str);
          break;
        }
        std::map<std::string, Definition>::iterator i = defmap_.find(includefile);
        if (i != defmap_.end()) {
          t = i->second.file.c_str();
          fprintf(f, "<a class=\"code\" href=\"%s\" title="">%s</a>",
                  t.c_str(), str);
          break;
        }
      }
    }
    // not an include or include not found
    std::string s = fix(str);
    fprintf(f, "%s",  s.c_str() );
    break;
  }
  case (CXToken_Identifier): {
    if (preprocessor) {
      preprocessor = false;
      if (strcmp(str, "include") == 0)
        include = true;
      fprintf(f, "<span class=\"code\">%s</span>", str);
      break;
    }

    if (clang_isUnexposed(c.kind)) {
      fprintf(f, "<span class=\"code\">%s</span>", str);
      fprintf(f, "<!-- origin line: %i : %s : kind = %i -->",
              __LINE__, str, c.kind);
      break;
    }

    // Calling clang_getCursorDefinition() does not work properly
    // for template classes, i.e., it will find the method
    // declaration, not the definition, if they differ.  However,
    // once you have the declaration's location, you can use it
    // get that cursor, and find the definition that way.
    CXSourceLocation decloc =
      clang_getCursorLocation(clang_getCursorDefinition(c));
    CXCursor cref =
      clang_getCursorDefinition(clang_getCursor(tu_file_->tu(),
                                                decloc));

    if (clang_isUnexposed(cref.kind)) {
      fprintf(f, "<span class=\"code\">%s</span>", str);
          fprintf(f, "<!-- origin line: %i : (ref) %s : kind = %i -->",
                  __LINE__, str, cref.kind);
      break;
    }

    std::string rfile;
    std::string html_dir;
    unsigned refl = line;
    bool found = false;

    if (!clang_Cursor_isNull(cref) && cref.kind != CXCursor_Namespace) {
      CXSourceLocation refloc = clang_getCursorLocation(cref);
      if (!clang_equalLocations(tloc, refloc)) {
        CXFile cxfile;
        unsigned col;
        unsigned off;
        clang_getExpansionLocation(refloc, &cxfile, &refl, &col, &off);
        if (cxfile == file) {
          found = true;
          fprintf(f, "<!-- origin line: %i : (ref) %s : kind = %i -->",
                  __LINE__, str, cref.kind);
        }
        else {
          CXString cxfn = clang_getFileName(cxfile);
          const char* fn = clang_getCString(cxfn);
          if (fn) {
            if (files_.find(fn) != files_.end()) {
              rfile = fn;
              found = true;
              fprintf(f, "<!-- origin line: %i : (ref) %s : kind = %i -->",
                      __LINE__, str, cref.kind);
            }
          }
          clang_disposeString(cxfn);
        }
      }
    }
    else if (!clang_isDeclaration(c.kind) && c.kind != CXCursor_Namespace) {
      CXCursor ref = clang_getCursorReferenced(c);
      if (ref.kind != CXCursor_Namespace) {
        std::string fsn = munge_fullyscopedname(fullyScopedName(ref));
        if (fsn.empty()) {
            fprintf(f, "<!-- origin line: %i : (fsn empty) %s : kind = %i -->",
                    __LINE__, str, c.kind);
        } else {
          std::map<std::string, Definition>::iterator r = defmap_.find(fsn);
          if (r != defmap_.end()) {
            found = true;
            fprintf(f, "<!-- origin line: %i : %s : kind = %i -->",
                    __LINE__, fsn.c_str(), c.kind);
            rfile = r->second.file.c_str();
            html_dir = r->second.html_path.c_str();
            refl = r->second.line;
          }
        }
      }
    }

    // since we are linking to lines, no need to link to same line
    if (found && (!rfile.empty() || refl != line)) {
      if (!rfile.empty())
        rfile = make_filename(rfile, html_dir, prefix_, ".html", !html_dir.empty());
      fprintf(f, "<a class=\"code\" href=\"%s#l%05i\" title="">%s</a>",
              rfile.c_str(), refl , str);
      break;
    }
    fprintf(f, "<span class=\"code\">%s</span>", str);
    break;
  }
  }
  cur_column_ += strlen(str);
}
コード例 #28
0
ファイル: clang++.cpp プロジェクト: mythagel/cxxide
cursor cursor::getCursorReferenced()
{
    return { clang_getCursorReferenced(cur) };
}
コード例 #29
0
ファイル: ClangIndexer.cpp プロジェクト: clapautius/rtags
CXChildVisitResult ClangIndexer::indexVisitor(CXCursor cursor, CXCursor parent, CXClientData data)
{
    ClangIndexer *indexer = static_cast<ClangIndexer*>(data);
    // error() << "indexVisitor" << cursor;
    // FILE *f = fopen("/tmp/clangindex.log", "a");
    // String str;
    // Log(&str) << cursor;
    // fwrite(str.constData(), 1, str.size(), f);
    // fwrite("\n", 1, 1, f);
    // fclose(f);
    const LastCursorUpdater updater(indexer->mLastCursor, cursor);

    const CXCursorKind kind = clang_getCursorKind(cursor);
    const RTags::CursorType type = RTags::cursorType(kind);
    if (type == RTags::Other)
        return CXChildVisit_Recurse;

    bool blocked = false;

    Location loc = indexer->createLocation(cursor, &blocked);
    if (blocked) {
        // error() << "blocked" << cursor;
        ++indexer->mBlocked;
        return CXChildVisit_Continue;
    } else if (loc.isNull()) {
        // error() << "Got null" << cursor;
        return CXChildVisit_Recurse;
    }
    ++indexer->mAllowed;
    if (indexer->mLogFile) {
        String out;
        Log(&out) << cursor;
        fwrite(out.constData(), 1, out.size(), indexer->mLogFile);
        fwrite("\n", 1, 1, indexer->mLogFile);
    }

    if (testLog(VerboseDebug)) {
        Log log(VerboseDebug);
        log << cursor;
        CXCursor ref = clang_getCursorReferenced(cursor);
        if (!clang_isInvalid(clang_getCursorKind(ref)) && !clang_equalCursors(ref, cursor)) {
            log << "refs" << ref;
        }
    }
    switch (type) {
    case RTags::Cursor:
        indexer->handleCursor(cursor, kind, loc);
        break;
    case RTags::Include:
        indexer->handleInclude(cursor, kind, loc);
        break;
    case RTags::Reference:
        switch (kind) {
        case CXCursor_OverloadedDeclRef: {
            const int count = clang_getNumOverloadedDecls(cursor);
            for (int i=0; i<count; ++i) {
                const CXCursor ref = clang_getOverloadedDecl(cursor, i);
                indexer->handleReference(cursor, kind, loc, ref, parent);
            }
            break; }
        case CXCursor_CXXDeleteExpr:
            indexer->handleReference(cursor, kind, loc, findDestructorForDelete(cursor), parent);
            break;
        case CXCursor_CallExpr: {
            // uglehack, see rtags/tests/nestedClassConstructorCallUgleHack/
            const CXCursor ref = clang_getCursorReferenced(cursor);
            if (clang_getCursorKind(ref) == CXCursor_Constructor
                && clang_getCursorKind(indexer->mLastCursor) == CXCursor_TypeRef
                && clang_getCursorKind(parent) != CXCursor_VarDecl) {
                loc = indexer->createLocation(indexer->mLastCursor);
                indexer->handleReference(indexer->mLastCursor, kind, loc, ref, parent);
            } else {
                indexer->handleReference(cursor, kind, loc, ref, parent);
            }
            break; }
        default:
            indexer->handleReference(cursor, kind, loc, clang_getCursorReferenced(cursor), parent);
            break;
        }
        break;
    case RTags::Other:
        assert(0);
        break;
    }
    return CXChildVisit_Recurse;
}
コード例 #30
0
ファイル: Highlighter.cpp プロジェクト: animatedb/oovaide
// Desired functions:
//      Go to definition of variable/function
//      Go to declaration of function/class
bool Tokenizer::findToken(eFindTokenTypes ft, size_t origOffset, std::string &fn,
        size_t &line)
    {
    CLangAutoLock lock(mCLangLock, __LINE__, this);
    CXCursor startCursor = getCursorAtOffset(mTransUnit, mSourceFile, origOffset);
    DUMP_PARSE("find:start cursor", startCursor);
    // Instantiating type - <class> <type> - CXCursor_TypeRef
    // Method declaration - <class> { <method>(); }; CXCursor_NoDeclFound
    // Method definition - <class>::<method>(){} - CXCursor_CXXMethod
    // Class/method usage - <class>.<method>()
    // Instance usage - method(){ int v = typename[4]; } - CXCursor_DeclStmt
    //          clang_getCursorSemanticParent returns method
    //          clang_getCursorDefinition returns invalid
    if(startCursor.kind == CXCursor_InclusionDirective)
        {
        CXFile file = clang_getIncludedFile(startCursor);
        if(file)
            {
            fn = getDisposedString(clang_getFileName(file));
            line = 1;
            }
        else
            {
            /// @todo - need to get the full path.
    //      CXStringDisposer cfn = clang_getCursorSpelling(cursor);
    //      fn = cfn;
            line = 1;
            }
        }
    else
        {
        CXCursor cursor = startCursor;
        switch(ft)
            {
            case FT_FindDecl:
                cursor = clang_getCursorReferenced(startCursor);
                DUMP_PARSE("find:decl", cursor);
                break;

            case FT_FindDef:
                // If instantiating a type (CXCursor_TypeRef), this goes to the type declaration.
                cursor = clang_getCursorDefinition(startCursor);
                // Method call can return invalid file when the definition is not in this
                // translation unit.
                if(clang_getCursorKind(cursor) == CXCursor_InvalidFile)
                    {
                    DUMP_PARSE("find:def-invalid", cursor);
                    cursor = clang_getCursorReferenced(startCursor);
                    }
                DUMP_PARSE("find:def", cursor);
            //      cursor = clang_getCursor(mTransUnit, clang_getCursorLocation(cursor));
            //      cursor = clang_getCursorDefinition(cursor);
                break;

            //          cursor = clang_getCursorReferenced(cursor);
            //  cursor = clang_getCanonicalCursor(cursor);
            //  cursor = clang_getCursorSemanticParent(cursor);
            //  cursor = clang_getCursorLexicalParent(cursor);
            }
        if(!clang_Cursor_isNull(cursor))
            {
            CXSourceLocation loc = clang_getCursorLocation(cursor);

            CXFile file;
            unsigned int uline;
            clang_getFileLocation(loc, &file, &uline, nullptr, nullptr);
            if(file)
                {
                line = uline;
                fn = getDisposedString(clang_getFileName(file));
                }
            }
        }
    return(fn.size() > 0);
    }