Esempio n. 1
0
Location TranslationUnit::GetDefinitionLocation(
  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 definition_cursor = clang_getCursorDefinition( cursor );

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

  return Location( clang_getCursorLocation( definition_cursor ) );
}
Esempio n. 2
0
Location TranslationUnit::GetDefinitionLocationForCursor( CXCursor cursor ) {
  CXCursor definition_cursor = clang_getCursorDefinition( cursor );

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

  return Location( clang_getCursorLocation( definition_cursor ) );
}
Esempio n. 3
0
Cursor Cursor::get_definition() const
{
	CXCursor cx_cursor(clang_getCursorDefinition(m_cx_cursor));
	if ( is_null(cx_cursor) ) {
		if ( is_null(m_cx_cursor) ) {
			CLANGXX_THROW_LogicError("Error retrieving a cursor that points to the definition of that entity.");
		}
		return Cursor();
	}

	return Cursor(std::move(cx_cursor), m_translation_unit);
}
Esempio n. 4
0
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;
    }
    location translation_unit::definition_location_at(uint32_t row, uint32_t col) {
        CXCursor cursor = get_cursor_at(row, col);
        CXCursor ref = clang_getCursorDefinition( 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 };
    }
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;
}
Esempio n. 7
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);
}
Esempio n. 8
0
cursor cursor::getCursorDefinition()
{
    return { clang_getCursorDefinition(cur) };
}
Esempio n. 9
0
// 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);
    }
Esempio n. 10
0
Cursor Cursor::definition() const
{
    return clang_getCursorDefinition(cxCursor);
}