CXChildVisitResult visitor(
        CXCursor cursor, CXCursor parent, CXClientData client_data)
{
    ClangTools::TranslationUnit::AstWalker * astWalker =
        reinterpret_cast<ClangTools::TranslationUnit::AstWalker *>(client_data);
    std::vector<std::string> & funcNames =
        *(reinterpret_cast<std::vector<std::string> *>(astWalker->getClientData()));

    auto sourceLocation = clang_getCursorLocation(cursor);
    CXFile file;
    clang_getFileLocation(sourceLocation, &file, 0, 0, 0);
    auto fileName = clang_getFileName(file);
    auto fileNameStr = ClangTools::String(fileName);

    if (fileNameStr != astWalker->getFileName())
    {
        return CXChildVisit_Recurse;
    }

    auto func = std::string{};
    auto def = bool{false};

    if (clang_isCursorDefinition(cursor))
    {
        def = true;
    }

    switch (clang_getCursorKind(cursor))
    {
        case CXCursor_FunctionDecl:
            func = "Function ";
            break;
        case CXCursor_FunctionTemplate:
            func = "FunctionTemplate ";
            break;
        case CXCursor_CXXMethod:
            func = "CXXMethod ";
            break;
        default:
            return CXChildVisit_Recurse;
            break;
    }

    func += clang_isCursorDefinition(cursor) ? "definition: " : "declaration: ";

    auto semanticParent = clang_getCursorSemanticParent(cursor);
    auto semanticParentSpelling = clang_getCursorSpelling(semanticParent);
    func += ClangTools::String(semanticParentSpelling) + "::";

    auto cursorSpelling = clang_getCursorSpelling(cursor);
    func += ClangTools::String(cursorSpelling);

    auto lexicalParent = clang_getCursorLexicalParent(cursor);
    auto lexicalParentSpelling = clang_getCursorSpelling(lexicalParent);
    func += " found in: " + ClangTools::String(lexicalParentSpelling);

    funcNames.push_back(func);

    return CXChildVisit_Recurse;
}
示例#2
0
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)");
  }
}
示例#3
0
static enum CXChildVisitResult FunctionScanVisitor(CXCursor Cursor,
                                                   CXCursor Parent,
                                                   CXClientData ClientData) {
  const char *startBuf, *endBuf;
  unsigned startLine, startColumn, endLine, endColumn, curLine, curColumn;
  CXCursor Ref;
  VisitorData *Data = (VisitorData *)ClientData;

  if (Cursor.kind != CXCursor_FunctionDecl ||
      !clang_isCursorDefinition(Cursor))
    return CXChildVisit_Continue;

  clang_getDefinitionSpellingAndExtent(Cursor, &startBuf, &endBuf,
                                       &startLine, &startColumn,
                                       &endLine, &endColumn);
  /* Probe the entire body, looking for both decls and refs. */
  curLine = startLine;
  curColumn = startColumn;

  while (startBuf < endBuf) {
    CXSourceLocation Loc;
    CXFile file;
    CXString source;

    if (*startBuf == '\n') {
      startBuf++;
      curLine++;
      curColumn = 1;
    } else if (*startBuf != '\t')
      curColumn++;

    Loc = clang_getCursorLocation(Cursor);
    clang_getInstantiationLocation(Loc, &file, 0, 0, 0);

    source = clang_getFileName(file);
    if (clang_getCString(source)) {
      CXSourceLocation RefLoc
        = clang_getLocation(Data->TU, file, curLine, curColumn);
      Ref = clang_getCursor(Data->TU, RefLoc);
      if (Ref.kind == CXCursor_NoDeclFound) {
        /* Nothing found here; that's fine. */
      } else if (Ref.kind != CXCursor_FunctionDecl) {
        printf("// %s: %s:%d:%d: ", FileCheckPrefix, GetCursorSource(Ref),
               curLine, curColumn);
        PrintCursor(Ref);
        printf("\n");
      }
    }
    clang_disposeString(source);
    startBuf++;
  }

  return CXChildVisit_Continue;
}
bool ClangWorkerThread::DoGotoDefinition(CXTranslationUnit& TU, ClangThreadRequest* request, ClangThreadReply* reply)
{
    // Test to see if we are pointing a function
    CXCursor cur;
    if(ClangUtils::GetCursorAt(TU, request->GetFileName(), request->GetLine(), request->GetColumn(), cur)) {

        if(request->GetContext() == CTX_GotoImpl && !clang_isCursorDefinition(cur)) {
            cur = clang_getCursorDefinition(cur);
        }

        ClangUtils::GetCursorLocation(cur, reply->filename, reply->line, reply->col);
        return true;
    }
    return false;
}
示例#5
0
Location TranslationUnit::GetDefinitionOrDeclarationLocation(
  const std::string &filename,
  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( filename, line, column );

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

  // Return the definition or the declaration of a symbol under the cursor
  // according to the following logic:
  //  - if the cursor is already on the definition, return the location of the
  //    declaration;
  //  - otherwise, search for the definition and return its location;
  //  - if no definition is found, return the location of the declaration.
  if ( clang_isCursorDefinition( cursor ) ) {
    return GetDeclarationLocationForCursor( cursor );
  }

  Location location = GetDefinitionLocationForCursor( cursor );

  if ( location.IsValid() ) {
    return location;
  }

  return GetDeclarationLocationForCursor( cursor );
}
示例#6
0
std::string libclang_vim::stringize_cursor_extra_info(CXCursor const& cursor) {
    std::string result;

    if (clang_isCursorDefinition(cursor)) {
        result += "'is_definition':1,";
    }
    if (clang_Cursor_isDynamicCall(cursor)) {
        result += "'is_dynamic_call':1,";
    }
    if (clang_Cursor_isVariadic(cursor)) {
        result += "'is_variadic':1,";
    }
    if (clang_CXXMethod_isVirtual(cursor)) {
        result += "'is_virtual_member_function':1,";
    }
    if (clang_CXXMethod_isPureVirtual(cursor)) {
        result += "'is_pure_virtual_member_function':1,";
    }
    if (clang_CXXMethod_isStatic(cursor)) {
        result += "'is_static_member_function':1,";
    }

    auto const access_specifier = clang_getCXXAccessSpecifier(cursor);
    switch (access_specifier) {
    case CX_CXXPublic:
        result += "'access_specifier':'public',";
        break;
    case CX_CXXPrivate:
        result += "'access_specifier':'private',";
        break;
    case CX_CXXProtected:
        result += "'access_specifier':'protected',";
        break;
    case CX_CXXInvalidAccessSpecifier:
        break;
    }

    return result;
}
示例#7
0
static void printCursor(CXCursor cursor)
{
    CXFile file;
    unsigned int off, line, col;
    CXSourceLocation location = clang_getCursorLocation(cursor);
    clang_getSpellingLocation(location, &file, &line, &col, &off);
    CXString fileName = clang_getFileName(file);
    const char *fileNameCStr = clang_getCString(fileName);
    if (fileNameCStr) {
        CXSourceRange range = clang_getCursorExtent(cursor);
        unsigned int start, end;
        clang_getSpellingLocation(clang_getRangeStart(range), 0, 0, 0, &start);
        clang_getSpellingLocation(clang_getRangeEnd(range), 0, 0, 0, &end);
        printf("%s:%d:%d (%d, %d-%d) ", fileNameCStr, line, col, off, start, end);
    }
    clang_disposeString(fileName);
    printString("kind", clang_getCursorKindSpelling(clang_getCursorKind(cursor)));
    printString("display name", clang_getCursorDisplayName(cursor));
    printString("usr", clang_getCursorUSR(cursor));
    if (clang_isCursorDefinition(cursor))
        printf("definition ");
    printf("\n");
}
示例#8
0
bool IndexerJob::handleCursor(const CXCursor &cursor, CXCursorKind kind, const Location &location)
{
    CursorInfo &info = mData->symbols[location];
    if (!info.symbolLength || !RTags::isCursor(info.kind)) {
        CXStringScope name = clang_getCursorSpelling(cursor);
        const char *cstr = name.data();
        info.symbolLength = cstr ? strlen(cstr) : 0;
        info.type = clang_getCursorType(cursor).kind;
        if (!info.symbolLength) {
            // this is for these constructs:
            // typedef struct {
            //    int a;
            // } foobar;
            //
            // We end up not getting a spelling for the cursor

            switch (kind) {
            case CXCursor_ClassDecl:
                info.symbolLength = 5;
                info.symbolName = "class";
                break;
            case CXCursor_UnionDecl:
                info.symbolLength = 5;
                info.symbolName = "union";
                break;
            case CXCursor_StructDecl:
                info.symbolLength = 6;
                info.symbolName = "struct";
                break;
            default:
                mData->symbols.remove(location);
                return false;
            }
        } else {
            info.symbolName = addNamePermutations(cursor, location);
        }

        CXSourceRange range = clang_getCursorExtent(cursor);
        unsigned start, end;
        clang_getSpellingLocation(clang_getRangeStart(range), 0, 0, 0, &start);
        clang_getSpellingLocation(clang_getRangeEnd(range), 0, 0, 0, &end);
        info.start = start;
        info.end = end;

        if (kind == CXCursor_EnumConstantDecl) {
#if CLANG_VERSION_MINOR > 1
            info.enumValue = clang_getEnumConstantDeclValue(cursor);
#else
            info.definition = clang_isCursorDefinition(cursor);
#endif
        } else{
            info.definition = clang_isCursorDefinition(cursor);
        }
        info.kind = kind;
        const String usr = RTags::eatString(clang_getCursorUSR(cursor));
        if (!usr.isEmpty())
            mData->usrMap[usr].insert(location);

        switch (info.kind) {
        case CXCursor_Constructor:
        case CXCursor_Destructor: {
            Location parentLocation = createLocation(clang_getCursorSemanticParent(cursor));
            // consider doing this for only declaration/inline definition since
            // declaration and definition should know of one another
            if (parentLocation.isValid()) {
                CursorInfo &parent = mData->symbols[parentLocation];
                parent.references.insert(location);
                info.references.insert(parentLocation);
            }
            break; }
        case CXCursor_CXXMethod: {
            List<CursorInfo*> infos;
            infos.append(&info);
            addOverriddenCursors(cursor, location, infos);
            break; }
        default:
            break;
        }
    }

    return true;
}
示例#9
0
bool cursor::isDefinition()
{
    return clang_isCursorDefinition(cur);
}
示例#10
0
 bool Cursor::IsDefinition() const
 {
     return clang_isCursorDefinition(cursor_) != 0;
 }
示例#11
0
String cursorToString(CXCursor cursor, unsigned flags)
{
    const CXCursorKind kind = clang_getCursorKind(cursor);
    String ret;
    ret.reserve(256);
    ret += eatString(clang_getCursorKindSpelling(kind));
    if (clang_isInvalid(kind))
        return ret;

    switch (RTags::cursorType(kind)) {
    case Reference:
        ret += " r";
        break;
    case Cursor:
        ret += " c";
        break;
    case Other:
        ret += " o";
        break;
    case Include:
        ret += " i";
        break;
    }

    const String name = eatString(clang_getCursorDisplayName(cursor));
    const String other = eatString(clang_getCursorSpelling(cursor));
    if (!name.isEmpty())
        ret += " " + name;
    if (other != name && !other.isEmpty())
        ret += " " + other;

    if (clang_isCursorDefinition(cursor))
        ret += " def";

    if (flags & IncludeUSR)
        ret += " " + eatString(clang_getCursorUSR(cursor));

    CXFile file;
    unsigned off, line, col; //presumedLine, presumedCol, instantiationLoc, expansionLoc;
    CXSourceLocation location = clang_getCursorLocation(cursor);
    clang_getSpellingLocation(location, &file, &line, &col, &off);
    // clang_getPresumedLocation(location, 0, &presumedLine, &presumedCol);
    // clang_getInstantiationLocation(location, 0, 0, 0, &instantiationLoc);
    // clang_getExpansionLocation(location, 0, 0, 0, &expansionLoc);

    const Str fileName(clang_getFileName(file));
    if (fileName.data() && *fileName.data()) {
        ret += ' ';
        ret += fileName.data();
        ret += ',';
        ret += String::number(off);

        if (flags & IncludeRange) {
            ret += " (";
            CXSourceRange range = clang_getCursorExtent(cursor);
            unsigned start, end;
            clang_getSpellingLocation(clang_getRangeStart(range), 0, 0, 0, &start);
            clang_getSpellingLocation(clang_getRangeEnd(range), 0, 0, 0, &end);
            ret += String::number(start);
            ret += '-';
            ret += String::number(end);
            ret += ')';
        }

        // if (presumedLine != line || presumedCol != col)
        //     ret += String::snprintf<32>("presumed: %d:%d", presumedLine, presumedCol);
        // if (instantiationLoc != off)
        //     ret += String::snprintf<32>("instantiation: %d", instantiationLoc);
        // if (expansionLoc != off)
        //     ret += String::snprintf<32>("expansion: %d", expansionLoc);

    }
    return ret;
}
示例#12
0
bool ClangIndexer::handleCursor(const CXCursor &cursor, CXCursorKind kind, const Location &location)
{
    // error() << "Got a cursor" << cursor;
    std::shared_ptr<CursorInfo> &info = mData->symbols[location];
    if (!info)
        info = std::make_shared<CursorInfo>();

    if (!info->symbolLength) {
        // if (mLogFile) {
        //     String out;
        //     Log(&out) << cursor << a;
        //     fwrite(out.constData(), 1, out.size(), mLogFile);
        //     fwrite("\n", 1, 1, mLogFile);
        // }
        CXStringScope name = clang_getCursorSpelling(cursor);
        const char *cstr = name.data();
        info->symbolLength = cstr ? strlen(cstr) : 0;
        info->type = clang_getCursorType(cursor).kind;
        if (!info->symbolLength) {
            // this is for these constructs:
            // typedef struct {
            //    int a;
            // } foobar;
            //
            // We end up not getting a spelling for the cursor

            switch (kind) {
            case CXCursor_ClassDecl:
                info->symbolLength = 5;
                info->symbolName = "class";
                break;
            case CXCursor_UnionDecl:
                info->symbolLength = 5;
                info->symbolName = "union";
                break;
            case CXCursor_StructDecl:
                info->symbolLength = 6;
                info->symbolName = "struct";
                break;
            default:
                mData->symbols.remove(location);
                return false;
            }
        } else {
            info->symbolName = addNamePermutations(cursor, location);
        }

        CXSourceRange range = clang_getCursorExtent(cursor);
        CXSourceLocation rangeStart = clang_getRangeStart(range);
        CXSourceLocation rangeEnd = clang_getRangeEnd(range);
        unsigned startLine, startColumn, endLine, endColumn;
        clang_getPresumedLocation(rangeStart, 0, &startLine, &startColumn);
        clang_getPresumedLocation(rangeEnd, 0, &endLine, &endColumn);
        info->startLine = startLine;
        info->startColumn = startColumn;
        info->endLine = endLine;
        info->endColumn = endColumn;

        if (kind == CXCursor_EnumConstantDecl) {
#if CINDEX_VERSION_MINOR > 1
            info->enumValue = clang_getEnumConstantDeclValue(cursor);
#else
            info->definition = 1;
#endif
        } else {
            info->definition = clang_isCursorDefinition(cursor);
        }
        info->kind = kind;
        // apparently some function decls will give a different usr for
        // their definition and their declaration.  Using the canonical
        // cursor's usr allows us to join them. Check JSClassRelease in
        // JavaScriptCore for an example.
        const String usr = RTags::eatString(clang_getCursorUSR(clang_getCanonicalCursor(cursor)));
        if (!usr.isEmpty())
            mData->usrMap[usr].insert(location);

        switch (info->kind) {
        case CXCursor_Constructor:
        case CXCursor_Destructor: {
            Location parentLocation = createLocation(clang_getCursorSemanticParent(cursor));
            // consider doing this for only declaration/inline definition since
            // declaration and definition should know of one another
            if (parentLocation.isValid()) {
                std::shared_ptr<CursorInfo> &parent = mData->symbols[parentLocation];
                if (!parent)
                    parent = std::make_shared<CursorInfo>();
                parent->references.insert(location);
                info->references.insert(parentLocation);
            }
            break; }
        case CXCursor_CXXMethod: {
            List<CursorInfo*> infos;
            infos.append(info.get());
            addOverriddenCursors(cursor, location, infos);
            break; }
        default:
            break;
        }
    }

    return true;
}
示例#13
0
bool Cursor::is_definition() const
{
	return clang_isCursorDefinition(m_cx_cursor) == 0;
}
示例#14
0
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);
    }
  }
}
示例#15
0
bool Cursor::isDefinition() const
{
    return clang_isCursorDefinition(cxCursor);
}