.. highlight:: ada
.. _Source_Navigation:

*****************
Source Navigation
*****************

.. index:: source navigation
.. index:: navigation
.. index:: cross-references
.. _Support_for_Cross-References:

Support for Cross-References
============================

GPS provides cross-reference navigation for program entities defined in
your application such as types, procedures, functions, and variables.  This
support relies on compiler-generated cross-reference information, so you
need to compile your project before being able to navigate within it.
Similarly, if you have modified your sources, you need to rebuild and
recompute the xref information it you want your changes to be taken into
account by GPS.

Here is language specific information about source navigation:

*Ada*

  .. index:: Ada; cross-references

  By default, GPS uses the GNAT compiler to generate the cross-reference
  information it needs.  However, if you are using the :command:`-gnatD` or
  :command:`-gnatx` switches, no cross reference information is available
  to GPS.

  .. index:: GNAT; -gnatQ
  .. index:: GNAT; -k

  If you need to navigate through sources that do not compile (such as after
  modifications or while porting or initially developing an application),
  GNAT generates partial cross-reference information if you specify the
  :command:`-gnatQ` switch. Using this along with the :command:`-k` switch
  of :program:`gnatmake` generates as much relevant information from your
  non-compilable sources as possible.

  .. index:: GNAT; ALI files

  Sometimes GPS cannot find the external files (called :file:`ALI files`)
  containing the cross-reference information. Most likely, this is either
  because you have not compiled your sources yet or because the sources
  changed since the :file:`ALI files` were generated.  Another possibility
  is that you have not included the object directories that contain the
  :file:`ALI files` in the project.

  .. index:: separate unit
  .. index:: gnatkr

  In addition, GPS cannot automatically handle one special case, when you
  have separate units whose file names have been crunched by the
  :program:`gnatkr` command.


*C/C++*

  .. index:: C; cross-references
  .. index:: C++; cross-references
  .. index:: gcc; -fdump-xref

  You need to use the GCC C and C++ compilers that come with GNAT to
  generate the cross-references information needed by GPS and to call them
  with the :command:`-fdump-xref` switch, so you need to first add that
  switch to your project's switches for C and C++ sources and compile your
  application before you browse through the cross-references.  If your
  sources have been modified, recompile the modified files.


Ada cross-reference heuristics
------------------------------

GPS provides basic navigation support for Ada, C, and C++ sources even in
the absence of information coming from the compiler by using a built-in
parser, parsing the files both at startup and when they are modified.  This
provides basic navigation in simple cases.

In this mode, GPS can navigate to an entity body from the declaration and
vice versa.  For other references, GPS can navigate to the declaration only
if the heuristics provides the necessary information without ambiguity,
which may not be the case with overloaded entities.

GPS also uses this parser to provide the Ada outline view, code completion
and entity view, but these heuristics are not used in global reference
searching operations or to generate call graphs.


The cross-reference database
----------------------------

GPS parses the cross-reference information generated by the compiler (the
:file:`.ali` and :file:`.gli`) files into an :program:`sqlite`
database. This database can become quite large and should preferrably be on
a fast local disk.

By default, GPS places this database in the object directory of the
currently-loaded root project.  Override this choice by adding an attribute
:guilabel:`Xref_Database` in the :guilabel:`IDE` package of your project
file, either as an absolute path or a path relative to the location of the
project file.  We recommend this path be specific to each use, and to each
project this user might be working on, as in the following examples::

   --  assume this is in /home/user1/work/default.gpr
   project Default is
      for Object_Dir use "obj";

      package IDE is
         for Xref_Database use "xref_database.db";
         --  This would be /home/user1/work/xref_database.db

         for Xref_Database use Project'Object_Dir & "/xref_database.db";
         --  This would be /home/user1/work/obj/xref_database.db
         --  This is the default when this attribute is not specified

         for Xref_Database use external("HOME") & "/prj1/database.db";
         --  This would be /home/user1/prj1/database.db
      end IDE;
   end Default;

One drawback in altering the default location is that :program:`gprclean`
will not remove this database when you clean your project.  But it might speed
up GPS if your project is not on a fast local disk and you can put the
database there.

**WARNING**: You should not store this file in a directory that is accessed via
a network filesystem, like NFS, or Clearcase's MVFS. If your obj directory is
on such a filesystem, be sure to specify a custom Xref_Database directory in
your project file.


Cross-references and partially compiled projects
------------------------------------------------

The cross-reference engine works best when the cross-reference
information generated by the compiler (the :file:`.ali` files) is
fully up to date.

If you start from such a state and then modify the spec or body of an Ada
package and recompile only that file, any reference to entities declared in
that spec in other packages might no longer be found (until you recompile
those other packages, as :program:`gprbuild` would).

This is because GPS has no way to know for sure whether an entity
:samp:`Foo` in the spec is the same enity as before or is a new one with
the same name. It uses an approximate algorithm where the references are
only preserved if an entity with the same name remains at precisely the
same location in the new version of the source. But if a blank line in the
file will change the declaration line for all entities declared further in
the file, so those will lose their references from other source files.

.. index:: cross-references; runtime files

Cross-reference and GNAT runtime
--------------------------------

By default, GPS does not parse the GNAT runtime files because there is a
large number of them and doing so would significantly slow down GPS, while
producing only a minimal gain for most users.  However, the location of
subprograms in those runtime files is available from the :file:`.ali` files
corresponding to the sources of your project.

From your own sources, you can navigate to one of the runtime files (for
example, if you have a reference to :func:`Put_Line`, you will jump to its
declaration in :file:`a-textio.ads`). But you cannot perform
cross-reference queries from a runtime file itself.

If you need this capability, modify one of the GPS plug-ins, named
:file:`support/core/cross-references.py`, and add the :command:`--runtime`
switch to the list of switches for :program:`gnatinspect`.

.. _The_Navigate_Menu:

The Navigate Menu
=================

.. index:: menu; navigate --> find or replace

* :menuselection:`Navigate --> Find or Replace...`

  Open the find and replace dialog. See :ref:`Searching_and_Replacing`.


.. index:: menu; navigate --> find next

* :menuselection:`Navigate --> Find Next`

  Find next occurrence of the current search.  See
  :ref:`Searching_and_Replacing`.


.. index:: menu; navigate --> find previous

* :menuselection:`Navigate --> Find Previous`

  Find previous occurrence of the current search. See
  :ref:`Searching_and_Replacing`.


.. index:: menu; navigate --> find all references
.. _Find_All_References:

* :menuselection:`Navigate --> Find All References`

  Find all the references to the current entity in the project.  This is
  not a simple text search, but is based on the semantic information
  extracted from the sources.  The result of the search is displayed in the
  :guilabel:`Location` view. See :ref:`The_Locations_View`.

.. index:: menu; navigate --> goto declaration
.. index:: goto declaration

* :menuselection:`Navigate --> Goto declaration`

  Go to the declaration (spec) of the current entity.  You can also access
  this entry through the editor's contextual menu.  This requires the
  availability of cross-reference information.  See
  :ref:`Support_for_Cross-References`.

.. index:: menu; navigate --> goto body
.. index:: goto body

* :menuselection:`Navigate --> Goto body`

  Go to the body (implementation) of the current entity. If the current
  entity is the declaration of an Ada subprogram imported from C, it goes
  to the location where the C function is defined.  You can also access
  this entry through the editor's contextual menu.  This requires the
  availability of cross-reference information.  See
  :ref:`Support_for_Cross-References`.


.. index:: menu; navigate --> goto matching delimiter

* :menuselection:`Navigate --> Goto matching delimiter`

  Go to the delimiter matching the one right before (for a closing
  delimiter) or right after (for an opening delimiter) the cursor, if any.


.. index:: menu; navigate --> goto line
.. index:: goto line

* :menuselection:`Navigate --> Goto line`

  Open a dialog where you can type a line number and jump to that line in
  the current source editor. This entry is also available by clicking on
  the location at the bottom of editors.

.. index:: menu; navigate --> goto entity

* :menuselection:`Navigate --> Goto entity`

  Moves the focus to the :ref:`omni_search` view. You can the enter the
  name (or part of the name) for any entity defined in your project.
  Clicking on one of the results takes you to its declaration.

.. index:: menu; navigate --> goto file spec<->body

* :menuselection:`Navigate --> Goto file spec<->body`

  Open the corresponding spec file if the current edited file is a body
  file, or the body file otherwise.  You can also access this entry through
  the editor's contextual menu.  This requires support for
  cross-references.


.. index:: menu; navigate --> start of statement

* :menuselection:`Navigate --> Start of statement`

  Move the cursor to the start of the current statement or the start of the
  enclosing statement if the cursor is already at the start of a statement.


.. index:: menu; navigate --> end of statement

* :menuselection:`Navigate --> End of statement`

  Move the cursor to the end of the current statement or the end of the
  enclosing statement if the cursor position is already at the end of a
  statement.


.. index:: menu; navigate --> previous subprogram

* :menuselection:`Navigate --> Previous subprogram`

  Move the cursor to the start of the previous procedure, function, task,
  protected record, or entry.


.. index:: menu; navigate --> next subprogram

* :menuselection:`Navigate --> Next subprogram`

  Move the cursor to the start of the next procedure, function, task,
  protected record, or entry.


.. index:: menu; navigate --> previous tag

* :menuselection:`Navigate --> Previous tag`

  Go to previous tag or location. :ref:`The_Locations_View`.

.. index:: menu; navigate --> next tag

* :menuselection:`Navigate --> Next tag`

  Go to next tag or location. :ref:`The_Locations_View`.

.. index:: menu; navigate --> back

* :menuselection:`Navigate --> Back`

  Each time you use one of the navigation features in GPS, it stores the
  current location in a history. This entry allows you to navigate backward
  in the history, going to the location you were previously viewing.

.. index:: menu; navigate --> forward

* :menuselection:`Navigate --> Forward`

  Moves forward in the history of locations.


.. _Contextual_Menus_for_Source_Navigation:

Contextual Menus for Source Navigation
======================================

This contextual menu is available from any source editor.  If you
right-click on an entity or selected text, the contextual menu applies to
the selection or entity.  Most of these menus requires support for
cross-references.

* :menuselection:`Goto declaration of *entity*`

  Go to the declaration (spec) of *entity*.

.. index:: plug-ins; methods.py

* :menuselection:`Goto declarations of *entity*`

  This entry appears when clicking on a dispatching subprogram call. In
  that case, GPS cannot know what subprogram will actually be called at run
  time, so it gives you a list of all entities in the tagged type hierarchy
  and lets you choose which of the declarations you want to jump to. See
  also the :file:`methods.py` plug-in (enabled by default) which, given an
  object, lists all its primitive operations in a contextual menu so you
  can easily jump to them. See also the :menuselection:`References --> Find
  References To...` contextual menu, which allows you to find all calls to
  a subprogram or one of its overriding subprograms.

* :menuselection:`Goto full declaration of *entity*`

  This entry appears for a private or limited private types. Go to the full
  declaration (spec) of *entity*.

* :menuselection:`Goto type declaration of *entity*`

  Go to the type declaration of *entity*.

* :menuselection:`Display type hierarchy for *entity*`

  This entry appears for derived or access types. Put the :index:`type
  hierarchy` for *entity* into the :guilabel:`Location` view.

* :menuselection:`Goto body of *entity*`

  Go to the body (implementation of *entity*.) If *entity* is the
  declaration of an Ada subprogram imported from C, go to the the location
  where the C function is defined.

* :menuselection:`Goto bodies of *entity*`

  Similar to :menuselection:`Goto declarations of`, but applies to the
  bodies of entities.

* :menuselection:`Goto file spec/body`

  Open the corresponding spec file if the current edited file is a body
  file, or the body file otherwise. This entry is only available for the
  Ada language.

* :menuselection:`*Entity* calls`

  Display a list of all subprograms called by *entity* in a tree view. This
  is generally more convenient than using the corresponding
  :menuselection:`Browsers/` submenu if you expect many references.
  See :ref:`The_Callgraph_View`.

* :menuselection:`*Entity* is called by`

  Display a list of all subprograms calling *entity* in a tree view. This
  is generally more convenient than using the correponding
  :menuselection:`Browsers/` submenu if you expect many references.  See
  :ref:`The_Callgraph_View`.

* :menuselection:`References --> Find all references`

  :ref:`Find all references <Find_All_References>` to *entity* in all the
  files in the project.

* :menuselection:`References --> Find all references...`

  Similar to the entry above except you can select more precisely what
  kind of reference should be displayed.  You can also specify the scope
  of the search and whether the context (or caller) at each reference
  should be displayed.

  .. index:: primitive operations
  .. index:: overriding operations
  .. index:: methods

  The option :guilabel:`Include overriding and overridden operations`
  includes references to overridden or overriding entities.  This is
  particularly useful if you need to know whether you can easily modify
  the profile of a primitive operation or method since you can see what
  other entities would also be changed. If you select only the
  :guilabel:`declaration` check box, you see the list of all related
  primitive operations.

  .. index:: imported entities

  This dialog allows you to determine which entities are imported from a
  given file or unit. Click on any entity from that file (for example on
  the :command:`with` line for Ada code) and select the :guilabel:`All
  entities imported from same file` toggle, which displays in the
  :guilabel:`Location` view the list of all entities imported from the
  same file.

  Selecting the :guilabel:`Show context` option produces a list of all
  the references to these entities within the file.  If it is not
  selected, you just get a pointer to the declaration of the imported
  entities.

* :menuselection:`References --> Find all local references to *entity*`

  :ref:`Find all references <Find_All_References>` to *entity* in the current
  file (or in the current top level unit for Ada sources).

* :menuselection:`References --> Variables used in *entity*`

  Find all variables (local or global) used in *entity* and list each first
  reference in the locations window.

* :menuselection:`References --> Non Local variables used in *entity*`

  Find all non-local variables used in the entity.

.. index:: plug-ins; methods.py

* :menuselection:`References --> Methods of *entity*`

  This entry is only visible if you activated the plug-in
  :file:`methods.py` (the default) and when you click on a tagged type or
  an instance of a tagged type.  It lists all the :index:`primitive
  operations` or :index:`methods` of that type, allowing you to jump to the
  declaration of any of these operations or methods.

* :menuselection:`Browsers --> *Entity* calls`

  Open or raise the :guilabel:`Callgraph` browser on the specified entity and
  display all the subprograms called by it. See :ref:`Call_Graph`.

* :menuselection:`Browsers --> *Entity* calls (recursively)`

  Open or raise the :guilabel:`Callgraph` browser on the specified entity
  and display all the subprograms called by *entity*, transitively for all
  subprograms.  Since this can take a long time to compute and generate a
  very large graph, an intermediate dialog is displayed to limit the number
  of subprograms to display (1000 by default). See :ref:`Call_Graph`.

* :menuselection:`*Entity* is called by`

  Open or raise the :guilabel:`Callgraph` browser on the specified entity
  and display all the subprograms calling *entity*. See :ref:`Call_Graph`.

* :menuselection:`Expanded code`

  Present for Ada files only. Generates a :file:`.dg` file by calling the
  GNAT compiler with the `:index:command:`-gnatGL`` switch and displaying the
  expanded code.  Use this when investigating low-level issues and tracing
  how your source code is transformed by the GNAT front-end.

* :menuselection:`Expanded code --> Show subprogram`

  Display expanded code for the current subprogram in the current editor.

* :menuselection:`Expanded code --> Show file`

  Display expanded code for the current file in the current editor.

* :menuselection:`Expanded code --> Show in separate editor`

  Display expanded code for the current file in a new editor.

* :menuselection:`Expanded code --> Clear`

  Remove expanded code from the current editor.

* :menuselection:`Open *filename*`

  When you click on a filename (for example, a C :command:`#include`, or an
  error message in a log file), this entry opens that file. If the file
  name is followed by :samp:`:` and a line number, the cursor points to
  that line.


.. index:: hyperlinks
.. _Navigating_with_hyperlinks:

Navigating with hyperlinks
==========================

When you press the :kbd:`Control` key and start moving the mouse, entities
in the editors under the pointer become hyperlinks and the form of the
pointer changes.

Left-clicking on a reference to an entity opens a source editor on the
declaration of the entity and left-clicking on an entity declaration opens
an editor on the implementation of the entity.  Left-clicking on the Ada
declaration of a subprogram imported from C opens a source editor on the
definition of the corresponding C entity. This capability requires support
for cross-references.

Middle-clicking on either a reference to an entity or the declaration of an
entity jumps to the implementation (or type completion) of the entity.

For efficiency, GPS may create hyperlinks for some entities which have no
associated cross reference. In this case, clicking has no effect even
though an hyperlink is displayed.

.. index:: preferences; general --> hyper links

This behavior is controlled by the :menuselection:`General --> Hyper links`
preference.


.. index:: dispatching
.. index:: plug-ins; dispatching.py
.. _Highlighting_dispatching_calls:

Highlighting dispatching calls
==============================

By default, GPS highlights dispatching calls in Ada and C++ source code via
the :file:`dispatching.py` plug-in.  Based on the cross-reference
information, this plug-in highlights (with a special color you can
configure in the preferences dialog) all Ada dispatching calls or calls to
virtual methods in C++.  A dispatching call in Ada is a subprogram call
where the actual subprogram called is not known until run time and is
chosen based on the tag of the object.

Disable this highlighting (which may be slow if you have large sources) by
using the :menuselection:`Tools --> Plug-ins` menu and disabling the
:file:`dispatching.py` plug-in.
