Incorporate Issue 130313.5, Add support for Fortran assumed-rank arrays.
[dwarf-doc.git] / dwarf5 / latexdoc / examples.tex
index 031dbe7..744a095 100644 (file)
@@ -215,11 +215,11 @@ The following examples illustrate how to represent some of
 the more complicated forms of array and record aggregates
 using DWARF.
 
-\subsection{Fortran 90 Example}
-\label{app:fortran90example}
-Consider the \addtoindex{Fortran 90} source fragment in 
+\subsection{Fortran Array Example}
+\label{app:fortranarrayexample}
+Consider the \addtoindex{Fortran array}\addtoindexx{Fortran 90} source fragment in 
 \addtoindexx{array type entry!examples}
-Figure \referfol{fig:fortran90examplesourcefragment}.
+Figure \referfol{fig:fortranarrayexamplesourcefragment}.
 
 \begin{figure}[here]
 \begin{lstlisting}
@@ -233,11 +233,11 @@ do i = 1, 20
 allocate(arrayvar(i)%ap(i+10))
 end do
 \end{lstlisting}
-\caption{Fortran 90 example: source fragment} \label{fig:fortran90examplesourcefragment}
+\caption{Fortran array example: source fragment} \label{fig:fortranarrayexamplesourcefragment}
 \end{figure}
 
 For allocatable and pointer arrays, it is essentially required
-by the \addtoindex{Fortran 90} semantics that each array consist of 
+by the \addtoindex{Fortran array} semantics that each array consist of 
 \addtoindexx{descriptor!array}
 two
 \addtoindexx{array!descriptor for}
@@ -249,18 +249,16 @@ and because the lifetime of the descriptor is necessarily
 longer than and includes that of the raw data, there must be
 an address somewhere in the descriptor that points to the
 raw data when, in fact, there is some (that is, when 
-the ``variable'' is allocated or associated).
+the \doublequote{variable} is allocated or associated).
 
 For concreteness, suppose that a descriptor looks something
 like the C structure in 
-Figure \refersec{fig:fortran90exampledescriptorrepresentation}.
+Figure \refersec{fig:fortranarrayexampledescriptorrepresentation}.
 Note, however, that it is
 a property of the design that 1) a debugger needs no builtin
 knowledge of this structure and 2) there does not need to
 be an explicit representation of this structure in the DWARF
-input to the 
-\addtoindexx{Fortran 90}
-debugger.
+input to the debugger.
 
 \begin{figure}[here]
 \begin{lstlisting}
@@ -277,8 +275,8 @@ struct desc {
     } dims[63];
 };
 \end{lstlisting}
-\caption{Fortran 90 example: descriptor representation}
-\label{fig:fortran90exampledescriptorrepresentation}
+\caption{Fortran array example: descriptor representation}
+\label{fig:fortranarrayexampledescriptorrepresentation}
 \end{figure}
 
 
@@ -299,7 +297,7 @@ provide a descriptor anyway, thereby giving it two parts. (This
 may be convenient for general runtime support unrelated to
 debugging.) In this case the above vocabulary applies as
 stated. Alternatively, an implementation can do without a
-descriptor, in which case the \doublequote{address of the variable},
+descriptor, in which case the \doublequote{address of the variable,}
 or equivalently the \doublequote{base address of the object}, refers
 to the \doublequote{raw data} (the real data, the only thing around
 that can be the object).
@@ -317,7 +315,7 @@ a descriptor does have a
 \livelink{chap:DWATdatalocation}{DW\_AT\_data\_location} attribute. In
 that case the object doubles as its own descriptor.)
 
-The \addtoindex{Fortran 90} derived type \texttt{array\_ptr} can now be redescribed
+The \addtoindex{Fortran} derived type \texttt{array\_ptr} can now be redescribed
 in C\dash like terms that expose some of the representation as in
 
 \begin{lstlisting}[numbers=none]
@@ -345,7 +343,7 @@ within an entity of the given type
 
 The DWARF description is shown 
 \addtoindexx{Fortran 90}
-in Figure \refersec{fig:fortran90exampledwarfdescription}.
+in Figure \refersec{fig:fortranarrayexampledwarfdescription}.
 
 \begin{figure}[h]
 \figurepart{1}{2}
@@ -394,8 +392,8 @@ in Figure \refersec{fig:fortran90exampledwarfdescription}.
             !  dimension (other than to express the larger offsets involved).
 \end{alltt}
 \end{dwflisting}
-\caption{Fortran 90 example: DWARF description}
-\label{fig:fortran90exampledwarfdescription}
+\caption{Fortran array example: DWARF description}
+\label{fig:fortranarrayexampledwarfdescription}
 \end{figure}
 
 \begin{figure}
@@ -450,12 +448,12 @@ in Figure \refersec{fig:fortran90exampledwarfdescription}.
 \end{dwflisting}
 \begin{center}
 
-Figure~\ref{fig:fortran90exampledwarfdescription} Fortran 90 example: DWARF description \textit{(concluded)}
+Figure~\ref{fig:fortranarrayexampledwarfdescription} Fortran array example: DWARF description \textit{(concluded)}
 \end{center}
 \end{figure}
 
 Suppose 
-\addtoindexx{Fortran 90 example}
+\addtoindexx{Fortran array example}
 the program is stopped immediately following completion
 of the do loop. Suppose further that the user enters the
 following debug command:
@@ -555,16 +553,294 @@ could be completely different descriptor arrangements and the
 mechanics would still be the same---only the stack machines
 would be different.
 
+%\needlines{8}
+\subsection{Fortran Coarray Examples}
+\label{app:Fortrancoarrayexamples}
+
+\subsubsection{Fortran Scalar Coarray Example}
+The \addtoindex{Fortran} scalar coarray example
+\addtoindexx{coarray!example}\addtoindexx{scalar coarray|see{coarray}}
+in Figure \refersec{fig:Fortranscalarcoarraysourcefragment} can be described as 
+illustrated in Figure \refersec{fig:FortranscalarcoarrayDWARFdescription}.
+
+\begin{figure}[!h]
+\begin{lstlisting}
+        INTEGER X[*]
+\end{lstlisting}
+\caption{Fortran scalar coarray: source fragment}
+\label{fig:Fortranscalarcoarraysourcefragment}
+\end{figure}
+
+\begin{figure}[!h]
+\begin{dwflisting}
+\begin{alltt}
+10\$:  \DWTAGcoarraytype
+        \DWATtype(reference to INTEGER)
+        \DWTAGsubrangetype                ! Note omitted upper bound                   
+            \DWATlowerbound(constant 1)
+
+11\$:  \DWTAGvariable
+        \DWATname("X")
+        \DWATtype(reference to coarray type at 10\$)
+\end{alltt}
+\end{dwflisting}
+\caption{Fortran scalar coarray: DWARF description}
+\label{fig:FortranscalarcoarrayDWARFdescription}
+\end{figure}
+
+\subsubsection{Fortran Array Coarray Example}
+The \addtoindex{Fortran} (simple) array coarray example
+\addtoindexx{coarray!example}\addtoindexx{array coarray|see{coarray}}
+in Figure \refersec{fig:Fortranarraycoarraysourcefragment} can be described as 
+illustrated in Figure \refersec{fig:FortranarraycoarrayDWARFdescription}.
+
+\begin{figure}[here]
+\begin{lstlisting}
+        INTEGER X(10)[*]
+\end{lstlisting}
+\caption{Fortran array coarray: source fragment}
+\label{fig:Fortranarraycoarraysourcefragment}
+\end{figure}
+
+\begin{figure}[here]
+\begin{dwflisting}
+\begin{alltt}
+10\$: \DWTAGarraytype
+        \DWATordering(\DWORDcolmajor)
+        \DWATtype(reference to INTEGER)
+11\$:    \DWTAGsubrangetype
+            \DWATlowerbound(constant 1)
+            \DWATupperbound(constant 10)
+
+12\$: \DWTAGcoarraytype
+        \DWATtype(reference to array type at 10\$)
+13\$:    \DWTAGsubrangetype                ! Note omitted upper bound
+            \DWATlowerbound(constant 1)
+
+14$: \DWTAGvariable
+        \DWATname("X")
+        \DWATtype(reference to coarray type at 12\$)
+\end{alltt}
+\end{dwflisting}
+\caption{Fortran array coarray: DWARF description}
+\label{fig:FortranarraycoarrayDWARFdescription}
+\end{figure}
+
+\subsubsection{Fortran Multidimensional Coarray Example}
+The \addtoindex{Fortran} multidimensional coarray of a multidimensional array example
+\addtoindexx{coarray!example}\addtoindexx{array coarray|see{coarray}}
+in Figure \refersec{fig:Fortranmultidimensionalcoarraysourcefragment} can be described as 
+illustrated in Figure \refersec{fig:FortranmultidimensionalcoarrayDWARFdescription}.
+
+\begin{figure}[here]
+\begin{lstlisting}
+        INTEGER X(10,11,12)[2,3,*]
+\end{lstlisting}
+\caption{Fortran multidimentional coarray: source fragment}
+\label{fig:Fortranmultidimensionalcoarraysourcefragment}
+\end{figure}
+
+\begin{figure}[here]
+\begin{dwflisting}
+\begin{alltt}
+10\$: \DWTAGarraytype
+        \DWATordering(\DWORDcolmajor)
+        \DWATtype(reference to INTEGER)
+11\$:    \DWTAGsubrangetype
+            \DWATlowerbound(constant 1)
+            \DWATupperbound(constant 10)
+12\$:    \DWTAGsubrangetype
+            \DWATlowerbound(constant  1)
+            \DWATupperbound(constant 11)
+13\$:    \DWTAGsubrangetype
+            \DWATlowerbound(constant  1)
+            \DWATupperbound(constant 12)
+
+14\$: \DWTAGcoarraytype
+        \DWATtype(reference to array_type at 10\$)
+15\$:    \DWTAGsubrangetype
+            \DWATlowerbound(constant 1)
+            \DWATupperbound(constant 2)
+16\$:    \DWTAGsubrangetype
+            \DWATlowerbound(constant 1)
+            \DWATupperbound(constant 3)
+17\$:    \DWTAGsubrangetype                ! Note omitted upper bound
+            \DWATlowerbound(constant 1)
+
+18\$: \DWTAGvariable
+        \DWATname("X")
+        \DWATtype(reference to coarray type at 14\$)
+\end{alltt}
+\end{dwflisting}
+\caption{Fortran multidimensional coarray: DWARF description}
+\label{fig:FortranmultidimensionalcoarrayDWARFdescription}
+\end{figure}
+
+
+\clearpage
+\subsection{Fortran 2008 Assumed-rank Array Example}
+\label{app:assumedrankexample}
+Consider the example in Figure~\ref{fig:assumedrankdecl}, which shows
+an assumed-rank array in Fortran~2008 with
+supplement~29113:\footnote{Technical Specification ISO/IEC TS
+  29113:2012 \emph{Further Interoperability of Fortran with C}}
+
+\begin{figure}[!h]
+\begin{lstlisting}[language={[95]Fortran}]
+  subroutine foo(x)
+    real :: x(..)
+
+    ! x has n dimensions
+  
+  end subroutine
+\end{lstlisting}
+\caption{Declaration of a Fortran 2008 assumed-rank array}
+\label{fig:assumedrankdecl}
+\end{figure}
+
+Let's assume the Fortran compiler used an array descriptor that looks
+like the one shown in Figure~\ref{fig:arraydesc}.
+
+\begin{figure}[!h]
+\begin{lstlisting}[language=C]
+  struct array_descriptor {
+    void *base_addr;
+    int rank;
+    struct dim dims[]; 
+  }
+
+  struct dim {
+     int lower_bound;
+     int upper_bound;
+     int stride;
+     int flags;
+  }
+\end{lstlisting}
+\caption{One of many possible layouts for an array descriptor}
+\label{fig:arraydesc}
+\end{figure}
+
+The DWARF type for the array \emph{x} can be described as shown in
+Figure~\ref{fig:assumedrankdwarf}.
+
+\begin{figure}[!h]
+\begin{minipage}[t]{\linewidth}
+\centering
+Abbreviation Table: \dotdebugabbrev{}
+\begin{framed}
+\scriptsize
+\begin{alltt}
+10\$:  \DWTAGarraytype
+         \livelink{chap:DWATtype}{DW\_AT\_type}(reference to real)
+         \livelink{chap:DWATrank}{DW\_AT\_rank}(expression=
+             \livelink{chap:DWOPpushobjectaddress}{DW\_OP\_push\_object\_address}
+             \livelink{chap:DWOPlit}{DW\_OP\_lit}<offset of rank in descriptor>
+             \livelink{chap:DWOPplus}{DW\_OP\_plus}
+             \livelink{chap:DWOPderef}{DW\_OP\_deref})
+         \livelink{chap:DWATdatalocation}{DW\_AT\_data\_location}(expression=
+             \livelink{chap:DWOPpushobjectaddress}{DW\_OP\_push\_object\_address}
+             \livelink{chap:DWOPlit}{DW\_OP\_lit}<offset of data in descriptor>
+             \livelink{chap:DWOPplus}{DW\_OP\_plus}
+             \livelink{chap:DWOPderef}{DW\_OP\_deref})
+11\$:    \DWTAGgenericsubrange
+             \livelink{chap:DWATtype}{DW\_AT\_type}(reference to integer)
+             \livelink{chap:DWATlowerbound}{DW\_AT\_lower\_bound}(expression=
+             !   Looks up the lower bound of dimension i.
+      
+             !   Operation                              ! Stack effect
+             !   (implicit)                             ! i                                                                     
+                 \livelink{chap:DWOPlit}{DW\_OP\_lit}<byte size of struct dim>     ! i sizeof(dim)
+                 \livelink{chap:DWOPmult}{DW\_OP\_mult}                             ! dim[i]
+                 \livelink{chap:DWOPlit}{DW\_OP\_lit}<offset of dim in descriptor> ! dim[i] offset
+                 \livelink{chap:DWOPplus}{DW\_OP\_plus}                             ! dim[i]+offset
+                 \livelink{chap:DWOPpushobjectaddress}{DW\_OP\_push\_object\_address}              ! dim[i]+offset objptr
+                 \livelink{chap:DWOPplus}{DW\_OP\_plus}                             ! objptr.dim[i]
+                 \livelink{chap:DWOPlit}{DW\_OP\_lit}<offset of lowerbound in dim> ! objptr.dim[i] offset
+                 \livelink{chap:DWOPplus}{DW\_OP\_plus}                             ! objptr.dim[i].lowerbound
+                 \livelink{chap:DWOPderef}{DW\_OP\_deref})                           ! *objptr.dim[i].lowerbound
+             \livelink{chap:DWATupperbound}{DW\_AT\_upper\_bound}(expression=
+             !   Looks up the upper bound of dimension i.
+                 \livelink{chap:DWOPlit}{DW\_OP\_lit}<byte size of dim>
+                 \livelink{chap:DWOPmult}{DW\_OP\_mult}
+                 \livelink{chap:DWOPlit}{DW\_OP\_lit}<offset of dim in descriptor>
+                 \livelink{chap:DWOPplus}{DW\_OP\_plus}
+                 \livelink{chap:DWOPpushobjectaddress}{DW\_OP\_push\_object\_address}
+                 \livelink{chap:DWOPplus}{DW\_OP\_plus}
+                 \livelink{chap:DWOPlit}{DW\_OP\_lit}<offset of upperbound in dim>
+                 \livelink{chap:DWOPplus}{DW\_OP\_plus}
+                 \livelink{chap:DWOPderef}{DW\_OP\_deref})
+             \livelink{chap:DWATbytestride}{DW\_AT\_byte\_stride}(expression=
+             !   Looks up the byte stride of dimension i.
+                 ...
+             !   (analogous to DW\_AT\_upper\_bound)
+                 )
+\end{alltt}
+\end{framed}
+\end{minipage}
+\caption{Sample DWARF for the array descriptor in Figure~\ref{fig:arraydesc}}
+\label{fig:assumedrankdwarf}
+\end{figure}
+
+The layout of the array descriptor is not specified by the Fortran
+standard unless the array is explicitly marked as C-interoperable. To
+get the bounds of an assumed-rank array, the expressions in the
+\DWTAGgenericsubrange{} type need to be evaluated for each of the
+\DWATrank{} dimensions as shown the pseudocode in
+Figure~\ref{fig:assumedrankdwarfparser}.
+
+\begin{figure}[!h]
+\begin{lstlisting}[language=C]
+    typedef struct {
+        int lower, upper, stride;
+    } dims_t;
+
+    typedef struct {
+        int rank;
+    struct dims_t *dims;
+    } array_t;
+
+    array_t get_dynamic_array_dims(DW_TAG_array a) {
+      array_t result;
+
+      // Evaluate the DW_AT_rank expression to get the number of dimensions.
+      dwarf_stack_t stack;
+      dwarf_eval(stack, a.rank_expr);
+      result.rank = dwarf_pop(stack); 
+      result.dims = new dims_t[rank];
+
+      // Iterate over all dimensions and find their bounds.
+      for (int i = 0; i < result.rank; i++) {
+        // Evaluate the generic subrange's DW_AT_lower expression for dimension i.
+        dwarf_push(stack, i);
+        assert( stack.size == 1 );
+        dwarf_eval(stack, a.generic_subrange.lower_expr);
+        result.dims[i].lower = dwarf_pop(stack);
+        assert( stack.size == 0 );
+
+        dwarf_push(stack, i);
+        dwarf_eval(stack, a.generic_subrange.upper_expr);
+        result.dims[i].upper = dwarf_pop(stack);
+    
+        dwarf_push(stack, i);
+        dwarf_eval(stack, a.generic_subrange.byte_stride_expr);
+        result.dims[i].stride = dwarf_pop(stack);
+      }
+      return result;
+    }
+\end{lstlisting}
+\caption{How to interpret the DWARF from Figure~\ref{fig:assumedrankdwarf}}
+\label{fig:assumedrankdwarfparser}
+\end{figure}
 
 
+
+\clearpage
 \subsection{Ada Example}
 \label{app:adaexample}
-
 Figure \refersec{fig:adaexamplesourcefragment}
 illustrates two kinds of \addtoindex{Ada} 
 parameterized array, one embedded in a record.
 
-
 \begin{figure}[here]
 \begin{lstlisting}
 M : INTEGER := <exp>;
@@ -577,7 +853,7 @@ end record;
 
 OBJ2B : REC2;
 \end{lstlisting}
-\caption{Ada 90 example: source fragment}
+\caption{Ada example: source fragment}
 \label{fig:adaexamplesourcefragment}
 \end{figure}
 
@@ -681,7 +957,7 @@ of this example and therefore is not shown.
         \livelink{chap:DWATlocation}{DW\_AT\_location}(...as appropriate...)
 \end{alltt}
 \end{dwflisting}
-\caption{Ada 90 example: DWARF description}
+\caption{Ada example: DWARF description}
 \label{fig:adaexampledwarfdescription}
 \end{figure}
 
@@ -727,8 +1003,6 @@ Section \refersec{chap:datamemberentries}.
 \begin{figure}[p]
 \figurepart{1}{2}
 \begin{dwflisting}
-% DWARF4 had some entries here as \livelink{chap:DWATmember}{DW\_AT\_member} .
-% Those are fixed here to \livelink{chap:DWTAGmember}{DW\_TAG\_member}
 \begin{alltt}
 10\$: \livelink{chap:DWTAGbasetype}{DW\_TAG\_base\_type}
         \livelink{chap:DWATname}{DW\_AT\_name}("BOOLEAN")
@@ -1461,8 +1735,8 @@ where
 is either \texttt{INNER} or \texttt{OUTER} to indicate to which
 subprogram the debugging information entry applies, 
 \item[\textless ac\textgreater]
-is either AI or CI to indicate ``abstract instance'' or
-``concrete instance'' respectively, 
+is either AI or CI to indicate \doublequote{abstract instance} or
+\doublequote{concrete instance} respectively, 
 \item[\textless n\textgreater]
 is the number of the
 alternative being considered, and