Exemplo n.º 1
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 );
}
Exemplo n.º 2
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 ) );
}
Exemplo n.º 3
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 ) );
}
Exemplo n.º 4
0
DocumentationData TranslationUnit::GetDocsForLocation(
  const Location &location,
  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( location.filename_,
                               location.line_number_,
                               location.column_number_ );

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

  return DocumentationData( cursor );
}
Exemplo n.º 5
0
std::string TranslationUnit::GetEnclosingFunctionAtLocation(
  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 "Internal error: no translation unit";
  }

  CXCursor cursor = GetCursor( filename, line, column );

  if ( !CursorIsValid( cursor ) ) {
    return "Internal error: cursor not valid";
  }

  CXCursor parent = clang_getCursorSemanticParent( cursor );

  std::string parent_str =
    CXStringToString( clang_getCursorDisplayName( parent ) );

  if ( parent_str.empty() ) {
    return "Unknown semantic parent";
  }

  return parent_str;
}
Exemplo n.º 6
0
Location TranslationUnit::GetDefinitionLocationForCursor( CXCursor cursor ) {
  CXCursor definition_cursor = clang_getCursorDefinition( cursor );

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

  return Location( clang_getCursorLocation( definition_cursor ) );
}
Exemplo n.º 7
0
std::string TranslationUnit::GetTypeAtLocation(
  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 "Internal error: no translation unit";

  CXCursor cursor = GetCursor( line, column );

  if ( !CursorIsValid( cursor ) )
    return "Internal error: cursor not valid";

  CXType type = clang_getCursorType( cursor );

  std::string type_description =
    CXStringToString( clang_getTypeSpelling( type ) );

  if ( type_description.empty() )
    return "Unknown type";

  // We have a choice here; libClang provides clang_getCanonicalType which will
  // return the "underlying" type for the type returned by clang_getCursorType
  // e.g. for a typedef
  //     type = clang_getCanonicalType( type );
  //
  // Without the above, something like the following would return "MyType"
  // rather than int:
  //     typedef int MyType;
  //     MyType i = 100; <-- type = MyType, canonical type = int
  //
  // There is probably more semantic value in calling it MyType. Indeed, if we
  // opt for the more specific type, we can get very long or
  // confusing STL types even for simple usage. e.g. the following:
  //     std::string test = "test"; <-- type = std::string;
  //                                    canonical type = std::basic_string<char>
  //
  // So as a compromise, we return both if and only if the types differ, like
  //     std::string => std::basic_string<char>

  CXType canonical_type = clang_getCanonicalType( type );

  if ( !clang_equalTypes( type, canonical_type ) ) {
    type_description += " => ";
    type_description += CXStringToString(
                          clang_getTypeSpelling( canonical_type ) );
  }

  return type_description;
}
Exemplo n.º 8
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 );
}
Exemplo n.º 9
0
Location TranslationUnit::GetDefinitionLocation(
  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 GetDefinitionLocationForCursor( cursor );
}