Changes in / [9243a501:7cc6bd6]


Ignore:
Files:
6 added
2 deleted
61 edited

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/common.tex

    r9243a501 r7cc6bd6  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sat Apr  9 10:06:39 2016
    14 %% Update Count     : 1
     13%% Last Modified On : Sat Apr 30 13:52:12 2016
     14%% Update Count     : 41
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    1919% Names used in the document.
    2020
    21 \newcommand{\CFA}{C$\mathbf\forall$\xspace}                             % set language symbolic name
    22 \newcommand{\CFL}{Cforall\xspace}                                               % set language text name
     21\newcommand{\CFA}{C$\mathbf\forall$\xspace}              % set language symbolic name
     22\newcommand{\CFL}{Cforall\xspace}                        % set language text name
    2323\newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace} % CC symbolic name
    2424\def\c11{ISO/IEC C} % C11 name (cannot have numbers in latex command name)
     
    4343   \belowdisplayskip \abovedisplayskip
    4444}
    45 \usepackage{relsize}                                                                    % must be after change to small or selects old size
     45\usepackage{relsize}                                    % must be after change to small or selects old size
    4646
    4747% reduce size of chapter/section titles
     
    6666    \vskip 50\p@
    6767  }}
    68 \renewcommand\section{\@startsection{section}{1}{\z@}{-3.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\large\bfseries}}
    69 \renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}}
     68\renewcommand\section{\@startsection{section}{1}{\z@}{-3.5ex \@plus -1ex \@minus -.2ex}{2.3ex \@plus .2ex}{\normalfont\large\bfseries}}
     69\renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-3.25ex \@plus -1ex \@minus -.2ex}{1.5ex \@plus .2ex}{\normalfont\normalsize\bfseries}}
    7070\renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}}
    7171\renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}}
     
    109109\newcommand{\@sIndex}[2][\@empty]{#2\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi}
    110110
     111\newcommand{\Indexc}[1]{\lstinline$#1$\index{#1@\lstinline$#1$}}
     112\newcommand{\indexc}[1]{\index{#1@\lstinline$#1$}}
     113
    111114\newcommand{\newtermFontInline}{\emph}
    112115\newcommand{\newterm}{\@ifstar\@snewterm\@newterm}
     
    179182                fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,__label__,lvalue,_Noreturn,otype,restrict,_Static_assert,
    180183                _Thread_local,throw,throwResume,trait,try,typeof,__typeof,__typeof__,},
    181         moredelim=**[is][\color{red}]{`}{`}, % red highlighting of program text
    182184}%
    183185
     
    186188columns=flexible,
    187189basicstyle=\sf\relsize{-1},
     190stringstyle=\tt,
    188191tabsize=4,
    189192xleftmargin=\parindent,
    190 escapechar=@,
     193extendedchars=true,
     194escapechar=§,
    191195mathescape=true,
    192196keepspaces=true,
    193197showstringspaces=false,
    194198showlines=true,
    195 aboveskip=6pt,
    196 belowskip=4pt,
    197 literate={\\`}{\raisebox{0.3ex}{\ttfamily\upshape \hspace*{-2pt}`}}1, % escape \`, otherwise used for red highlighting
     199aboveskip=4pt,
     200belowskip=2pt,
     201moredelim=**[is][\color{red}]{®}{®}, % red highlighting
     202moredelim=**[is][\color{blue}]{©}{©}, % blue highlighting
     203moredelim=[is][\lstset{keywords={}}]{¶}{¶}, % temporarily turn off keywords
     204% literate={\\`}{\raisebox{0.3ex}{\ttfamily\upshape \hspace*{-2pt}`}}1, % escape \`, otherwise used for red highlighting
    198205}%
    199206
     
    203210\lst@ProcessOther{"22}{\lst@ttfamily{"}{\raisebox{0.3ex}{\ttfamily\upshape "}}} % replace double quote
    204211\lst@ProcessOther{"27}{\lst@ttfamily{'}{\raisebox{0.3ex}{\ttfamily\upshape '\hspace*{-2pt}}}} % replace single quote
    205 \lst@ProcessOther{"2D}{\lst@ttfamily{-}{\ttfamily\upshape -}} % replace minus
    206 \lst@ProcessOther{"3C}{\lst@ttfamily{<}{\texttt{<}}} % replace less than
    207 \lst@ProcessOther{"3E}{\lst@ttfamily{<}{\texttt{>}}} % replace greater than
     212\lst@ProcessOther{"2D}{\lst@ttfamily{-}{\textbf{\texttt{-}}}} % replace minus
     213\lst@ProcessOther{"3C}{\lst@ttfamily{<}{\textbf{\texttt{<}}}} % replace less than
     214\lst@ProcessOther{"3E}{\lst@ttfamily{>}{\textbf{\texttt{>}}}} % replace greater than
    208215\lst@ProcessOther{"5E}{\raisebox{0.4ex}{$\scriptstyle\land\,$}} % replace circumflex
    209216\lst@ProcessOther{"5F}{\lst@ttfamily{\char95}{{\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}}} % replace underscore
  • doc/refrat/refrat.tex

    r9243a501 r7cc6bd6  
    1111%% Created On       : Wed Apr  6 14:52:25 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sat Apr  9 10:19:12 2016
    14 %% Update Count     : 8
     13%% Last Modified On : Sat Apr 30 13:45:40 2016
     14%% Update Count     : 29
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
    1717% requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended
     18
     19% red highlighting ®...® (registered trademark sumbol)
     20% blue highlighting ©...© (copyright symbol)
     21% latex escape §...§ (section symbol)
     22% keyword escape ¶...¶ (pilcrow symbol)
     23% math escape $...$ (dollar symbol)
    1824
    1925\documentclass[openright,twoside]{report}
     
    125131\CFA's scope rules differ from C's in one major respect: a declaration of an identifier may overload\index{overloading} outer declarations of lexically identical identifiers in the same
    126132\Index{name space}, instead of hiding them.
    127 The outer declaration is hidden if the two declarations have \Index{compatible type}, or if one declares an array type and the other declares a pointer type and the element type and pointed-at type are compatible, or if one has function type and the other is a pointer to a compatible function type, or if one declaration is a \lstinline$type$\use{type} or
    128 \lstinline$typedef$\use{typedef} declaration and the other is not.  The outer declaration becomes
     133The outer declaration is hidden if the two declarations have \Index{compatible type}, or if one declares an array type and the other declares a pointer type and the element type and pointed-at type are compatible, or if one has function type and the other is a pointer to a compatible function type, or if one declaration is a \lstinline@type@\use{type} or
     134\lstinline@typedef@\use{typedef} declaration and the other is not.  The outer declaration becomes
    129135\Index{visible} when the scope of the inner declaration terminates.
    130136\begin{rationale}
    131 Hence, a \CFA program can declare an \lstinline$int v$ and a \lstinline$float v$ in the same scope;
     137Hence, a \CFA program can declare an \lstinline@int v@ and a \lstinline@float v@ in the same scope;
    132138a {\CC} program can not.
    133139\end{rationale}
     
    143149Identifiers with \Index{no linkage} always denote unique entities.
    144150\begin{rationale}
    145 A \CFA program can declare an \lstinline$extern int v$ and an \lstinline$extern float v$;
     151A \CFA program can declare an \lstinline@extern int v@ and an \lstinline@extern float v@;
    146152a C program cannot.
    147153\end{rationale}
     
    166172\end{lstlisting}
    167173
    168 The type parameters in an instantiation of a generic type must satisfy any constraints in the forall specifier on the type generator declaration, e.g., \lstinline$sumable$.
     174The type parameters in an instantiation of a generic type must satisfy any constraints in the forall specifier on the type generator declaration, e.g., \lstinline@sumable@.
    169175The instantiation then has the semantics that would result if the type parameters were substituted into the type generator declaration by macro substitution.
    170176
     
    227233In \CFA, these conversions play a role in overload resolution, and collectively are called the \define{safe arithmetic conversion}s.
    228234
    229 Let \(int_r\) and \(unsigned_r\) be the signed and unsigned integer types with integer conversion rank\index{integer conversion rank}\index{rank|see{integer conversion rank}} $r$.
    230 Let \(unsigned_{mr}\) be the unsigned integer type with maximal rank.
     235Let \lstinline@int$_r$@ and \lstinline@unsigned$_r$@ be the signed and unsigned integer types with integer conversion rank\index{integer conversion rank}\index{rank|see{integer conversion rank}} $r$.
     236Let \lstinline@unsigned$_{mr}$@ be the unsigned integer type with maximal rank.
    231237
    232238The following conversions are \emph{direct} safe arithmetic conversions.
     
    235241The \Index{integer promotion}s.
    236242\item
    237 For every rank $r$ greater than or equal to the rank of \lstinline$int$, conversion from \(int_r\) to \(unsigned_r\).
    238 \item
    239 For every rank $r$ greater than or equal to the rank of \lstinline$int$, where \(int_{r+1}\) exists and can represent all values of \(unsigned_r\), conversion from \(unsigned_r\) to \(int_{r+1}\).
    240 \item
    241 Conversion from \(unsigned_{mr}\) to \lstinline$float$.
     243For every rank $r$ greater than or equal to the rank of \lstinline@int@, conversion from \lstinline@int$_r$@ to \lstinline@unsigned$_r$@.
     244\item
     245For every rank $r$ greater than or equal to the rank of \lstinline@int@, where \lstinline@int$_{r+1}$@ exists and can represent all values of \lstinline@unsigned$_r$@, conversion from \lstinline@unsigned$_r$@ to \lstinline@int$_{r+1}$@.
     246\item
     247Conversion from \lstinline@unsigned$_{mr}$@ to \lstinline@float@.
    242248\item
    243249Conversion from an enumerated type to its compatible integer type.
    244250\item
    245 Conversion from \lstinline$float$ to \lstinline$double$, and from \lstinline$double$ to \lstinline$long double$.
    246 \item
    247 Conversion from \lstinline$float _Complex$ to \lstinline$double _Complex$, and from \lstinline$double _Complex$ to \lstinline$long double _Complex$.
     251Conversion from \lstinline@float@ to \lstinline@double@, and from \lstinline@double@ to \lstinline@long double@.
     252\item
     253Conversion from \lstinline@float _Complex@ to \lstinline@double _Complex@, and from \lstinline@double _Complex@ to \lstinline@long double _Complex@.
    248254\begin{sloppypar}
    249255\item
    250 Conversion from \lstinline$float _Imaginary$ to \lstinline$double _Imaginary$, and from \lstinline$double _Imaginary$ to \lstinline$long double$ \lstinline$_Imaginary$, if the implementation supports imaginary types.
     256Conversion from \lstinline@float _Imaginary@ to \lstinline@double _Imaginary@, and from \lstinline@double _Imaginary@ to \lstinline@long double _Imaginary@, if the implementation supports imaginary types.
    251257\end{sloppypar}
    252258\end{itemize}
    253259
    254 If type \lstinline$T$ can be converted to type \lstinline$U$ by a safe direct arithmetic conversion and type \lstinline$U$ can be converted to type \lstinline$V$ by a safe arithmetic conversion, then the conversion from \lstinline$T$ to type \lstinline$V$ is an \emph{indirect} safe arithmetic conversion.
     260If type \lstinline@T@ can be converted to type \lstinline@U@ by a safe direct arithmetic conversion and type \lstinline@U@ can be converted to type \lstinline@V@ by a safe arithmetic conversion, then the conversion from \lstinline@T@ to type \lstinline@V@ is an \emph{indirect} safe arithmetic conversion.
    255261
    256262\begin{rationale}
     
    275281        int x, y;
    276282};
    277 void move_by( struct point * p1, struct point * p2 ) {@\impl{move_by}@
     283void move_by( struct point * p1, struct point * p2 ) {§\impl{move_by}§
    278284        p1->x += p2.x;
    279285        p1->y += p2.y;
     
    285291move_to( &cp1, &cp2 );
    286292\end{lstlisting}
    287 Thanks to implicit conversion, the two arguments that \lstinline$move_by()$ receives are pointers to
    288 \lstinline$cp1$'s second member and \lstinline$cp2$'s second member.
     293Thanks to implicit conversion, the two arguments that \lstinline@move_by()@ receives are pointers to
     294\lstinline@cp1@'s second member and \lstinline@cp2@'s second member.
    289295
    290296
     
    328334a direct safe arithmetic conversion;
    329335\item
    330 from any object type or incomplete type to \lstinline$void$;
    331 \item
    332 from a pointer to any non-\lstinline$void$ type to a pointer to \lstinline$void$;
     336from any object type or incomplete type to \lstinline@void@;
     337\item
     338from a pointer to any non-\lstinline@void@ type to a pointer to \lstinline@void@;
    333339\item
    334340from a pointer to any type to a pointer to a more qualified version of the type\index{qualified type};
     
    341347Conversions that are not safe conversions are \define{unsafe conversion}s.
    342348\begin{rationale}
    343 As in C, there is an implicit conversion from \lstinline$void *$ to any pointer type.
     349As in C, there is an implicit conversion from \lstinline@void *@ to any pointer type.
    344350This is clearly dangerous, and {\CC} does not have this implicit conversion.
    345351\CFA\index{deficiencies!void * conversion} keeps it, in the interest of remaining as pure a superset of C as possible, but discourages it by making it unsafe.
     
    367373\begin{itemize}
    368374\item
    369 The cost of an implicit conversion from \lstinline$int$ to \lstinline$long$ is 1.
    370 The cost of an implicit conversion from \lstinline$long$ to \lstinline$double$ is 3, because it is defined in terms of conversions from \lstinline$long$ to \lstinline$unsigned long$, then to \lstinline$float$, and then to \lstinline$double$.
    371 
    372 \item
    373 If \lstinline$int$ can represent all the values of \lstinline$unsigned short$, then the cost of an implicit conversion from \lstinline$unsigned short$ to \lstinline$unsigned$ is 2:
    374 \lstinline$unsigned short$ to \lstinline$int$ to \lstinline$unsigned$.
    375 Otherwise, \lstinline$unsigned short$ is converted directly to \lstinline$unsigned$, and the cost is 1.
    376 
    377 \item
    378 If \lstinline$long$ can represent all the values of \lstinline$unsigned$, then the conversion cost of \lstinline$unsigned$ to \lstinline$long$ is 1.
     375The cost of an implicit conversion from \lstinline@int@ to \lstinline@long@ is 1.
     376The cost of an implicit conversion from \lstinline@long@ to \lstinline@double@ is 3, because it is defined in terms of conversions from \lstinline@long@ to \lstinline@unsigned long@, then to \lstinline@float@, and then to \lstinline@double@.
     377
     378\item
     379If \lstinline@int@ can represent all the values of \lstinline@unsigned short@, then the cost of an implicit conversion from \lstinline@unsigned short@ to \lstinline@unsigned@ is 2:
     380\lstinline@unsigned short@ to \lstinline@int@ to \lstinline@unsigned@.
     381Otherwise, \lstinline@unsigned short@ is converted directly to \lstinline@unsigned@, and the cost is 1.
     382
     383\item
     384If \lstinline@long@ can represent all the values of \lstinline@unsigned@, then the conversion cost of \lstinline@unsigned@ to \lstinline@long@ is 1.
    379385Otherwise, the conversion is an unsafe conversion, and its conversion cost is undefined.
    380386\end{itemize}
     
    384390\begin{syntax}
    385391\oldlhs{keyword}
    386         \rhs \lstinline$forall$
    387         \rhs \lstinline$lvalue$
    388         \rhs \lstinline$trait$
    389         \rhs \lstinline$dtype$
    390         \rhs \lstinline$ftype$
    391         \rhs \lstinline$type$
     392        \rhs \lstinline@forall@
     393        \rhs \lstinline@lvalue@
     394        \rhs \lstinline@trait@
     395        \rhs \lstinline@dtype@
     396        \rhs \lstinline@ftype@
     397        \rhs \lstinline@otype@
    392398\end{syntax}
    393399
     
    396402
    397403\CFA allows operator \Index{overloading} by associating operators with special function identifiers.
    398 Furthermore, the constants ``\lstinline$0$'' and ``\lstinline$1$'' have special status for many of C's data types (and for many programmer-defined data types as well), so \CFA treats them as overloadable identifiers.
     404Furthermore, the constants ``\lstinline@0@'' and ``\lstinline@1@'' have special status for many of C's data types (and for many programmer-defined data types as well), so \CFA treats them as overloadable identifiers.
    399405Programmers can use these identifiers to declare functions and objects that implement operators and constants for their own types.
    400406
     
    405411\begin{syntax}
    406412\oldlhs{identifier}
    407 \rhs \lstinline$0$
    408 \rhs \lstinline$1$
     413\rhs \lstinline@0@
     414\rhs \lstinline@1@
    409415\end{syntax}
    410416
    411 \index{constant identifiers}\index{identifiers!for constants} The tokens ``\lstinline$0$''\impl{0} and ``\lstinline$1$''\impl{1} are identifiers.
     417\index{constant identifiers}\index{identifiers!for constants} The tokens ``\lstinline@0@''\impl{0} and ``\lstinline@1@''\impl{1} are identifiers.
    412418No other tokens defined by the rules for integer constants are considered to be identifiers.
    413419\begin{rationale}
    414 Why ``\lstinline$0$'' and ``\lstinline$1$''? Those integers have special status in C.
     420Why ``\lstinline@0@'' and ``\lstinline@1@''? Those integers have special status in C.
    415421All scalar types can be incremented and decremented, which is defined in terms of adding or subtracting 1.
    416 The operations ``\lstinline$&&$'', ``\lstinline$||$'', and ``\lstinline$!$'' can be applied to any scalar arguments, and are defined in terms of comparison against 0.
     422The operations ``\lstinline@&&@'', ``\lstinline@||@'', and ``\lstinline@!@'' can be applied to any scalar arguments, and are defined in terms of comparison against 0.
    417423A \nonterm{constant-expression} that evaluates to 0 is effectively compatible with every pointer type.
    418424
    419425In C, the integer constants 0 and 1 suffice because the integer promotion rules can convert them to any arithmetic type, and the rules for pointer expressions treat constant expressions evaluating to 0 as a special case.
    420426However, user-defined arithmetic types often need the equivalent of a 1 or 0 for their functions or operators, polymorphic functions often need 0 and 1 constants of a type matching their polymorphic parameters, and user-defined pointer-like types may need a null value.
    421 Defining special constants for a user-defined type is more efficient than defining a conversion to the type from \lstinline$_Bool$.
    422 
    423 Why \emph{just} ``\lstinline$0$'' and ``\lstinline$1$''? Why not other integers? No other integers have special status in C.
    424 A facility that let programmers declare specific constants---``\lstinline$const Rational 12$'', for instance---would not be much of an improvement.
     427Defining special constants for a user-defined type is more efficient than defining a conversion to the type from \lstinline@_Bool@.
     428
     429Why \emph{just} ``\lstinline@0@'' and ``\lstinline@1@''? Why not other integers? No other integers have special status in C.
     430A facility that let programmers declare specific constants---``\lstinline@const Rational 12@'', for instance---would not be much of an improvement.
    425431Some facility for defining the creation of values of programmer-defined types from arbitrary integer tokens would be needed.
    426432The complexity of such a feature doesn't seem worth the gain.
     
    438444\begin{tabular}[t]{ll}
    439445%identifier & operation \\ \hline
    440 \lstinline$?[?]$ & subscripting \impl{?[?]}\\
    441 \lstinline$?()$ & function call \impl{?()}\\
    442 \lstinline$?++$ & postfix increment \impl{?++}\\
    443 \lstinline$?--$ & postfix decrement \impl{?--}\\
    444 \lstinline$++?$ & prefix increment \impl{++?}\\
    445 \lstinline$--?$ & prefix decrement \impl{--?}\\
    446 \lstinline$*?$ & dereference \impl{*?}\\
    447 \lstinline$+?$ & unary plus \impl{+?}\\
    448 \lstinline$-?$ & arithmetic negation \impl{-?}\\
    449 \lstinline$~?$ & bitwise negation \impl{~?}\\
    450 \lstinline$!?$ & logical complement \impl{"!?}\\
    451 \lstinline$?*?$ & multiplication \impl{?*?}\\
    452 \lstinline$?/?$ & division \impl{?/?}\\
     446\lstinline@?[?]@ & subscripting \impl{?[?]}\\
     447\lstinline@?()@ & function call \impl{?()}\\
     448\lstinline@?++@ & postfix increment \impl{?++}\\
     449\lstinline@?--@ & postfix decrement \impl{?--}\\
     450\lstinline@++?@ & prefix increment \impl{++?}\\
     451\lstinline@--?@ & prefix decrement \impl{--?}\\
     452\lstinline@*?@ & dereference \impl{*?}\\
     453\lstinline@+?@ & unary plus \impl{+?}\\
     454\lstinline@-?@ & arithmetic negation \impl{-?}\\
     455\lstinline@~?@ & bitwise negation \impl{~?}\\
     456\lstinline@!?@ & logical complement \impl{"!?}\\
     457\lstinline@?*?@ & multiplication \impl{?*?}\\
     458\lstinline@?/?@ & division \impl{?/?}\\
    453459\end{tabular}\hfil
    454460\begin{tabular}[t]{ll}
    455461%identifier & operation \\ \hline
    456 \lstinline$?%?$ & remainder \impl{?%?}\\
    457 \lstinline$?+?$ & addition \impl{?+?}\\
    458 \lstinline$?-?$ & subtraction \impl{?-?}\\
    459 \lstinline$?<<?$ & left shift \impl{?<<?}\\
    460 \lstinline$?>>?$ & right shift \impl{?>>?}\\
    461 \lstinline$?<?$ & less than \impl{?<?}\\
    462 \lstinline$?<=?$ & less than or equal \impl{?<=?}\\
    463 \lstinline$?>=?$ & greater than or equal \impl{?>=?}\\
    464 \lstinline$?>?$ & greater than \impl{?>?}\\
    465 \lstinline$?==?$ & equality \impl{?==?}\\
    466 \lstinline$?!=?$ & inequality \impl{?"!=?}\\
    467 \lstinline$?&?$ & bitwise AND \impl{?&?}\\
     462\lstinline@?%?@ & remainder \impl{?%?}\\
     463\lstinline@?+?@ & addition \impl{?+?}\\
     464\lstinline@?-?@ & subtraction \impl{?-?}\\
     465\lstinline@?<<?@ & left shift \impl{?<<?}\\
     466\lstinline@?>>?@ & right shift \impl{?>>?}\\
     467\lstinline@?<?@ & less than \impl{?<?}\\
     468\lstinline@?<=?@ & less than or equal \impl{?<=?}\\
     469\lstinline@?>=?@ & greater than or equal \impl{?>=?}\\
     470\lstinline@?>?@ & greater than \impl{?>?}\\
     471\lstinline@?==?@ & equality \impl{?==?}\\
     472\lstinline@?!=?@ & inequality \impl{?"!=?}\\
     473\lstinline@?&?@ & bitwise AND \impl{?&?}\\
    468474\end{tabular}\hfil
    469475\begin{tabular}[t]{ll}
    470476%identifier & operation \\ \hline
    471 \lstinline$?^?$ & exclusive OR \impl{?^?}\\
    472 \lstinline$?|?$ & inclusive OR \impl{?"|?}\\
    473 \lstinline$?=?$ & simple assignment \impl{?=?}\\
    474 \lstinline$?*=?$ & multiplication assignment \impl{?*=?}\\
    475 \lstinline$?/=?$ & division assignment \impl{?/=?}\\
    476 \lstinline$?%=?$ & remainder assignment \impl{?%=?}\\
    477 \lstinline$?+=?$ & addition assignment \impl{?+=?}\\
    478 \lstinline$?-=?$ & subtraction assignment \impl{?-=?}\\
    479 \lstinline$?<<=?$ & left-shift assignment \impl{?<<=?}\\
    480 \lstinline$?>>=?$ & right-shift assignment \impl{?>>=?}\\
    481 \lstinline$?&=?$ & bitwise AND assignment \impl{?&=?}\\
    482 \lstinline$?^=?$ & exclusive OR assignment \impl{?^=?}\\
    483 \lstinline$?|=?$ & inclusive OR assignment \impl{?"|=?}\\
     477\lstinline@?^?@ & exclusive OR \impl{?^?}\\
     478\lstinline@?|?@ & inclusive OR \impl{?"|?}\\
     479\lstinline@?=?@ & simple assignment \impl{?=?}\\
     480\lstinline@?*=?@ & multiplication assignment \impl{?*=?}\\
     481\lstinline@?/=?@ & division assignment \impl{?/=?}\\
     482\lstinline@?%=?@ & remainder assignment \impl{?%=?}\\
     483\lstinline@?+=?@ & addition assignment \impl{?+=?}\\
     484\lstinline@?-=?@ & subtraction assignment \impl{?-=?}\\
     485\lstinline@?<<=?@ & left-shift assignment \impl{?<<=?}\\
     486\lstinline@?>>=?@ & right-shift assignment \impl{?>>=?}\\
     487\lstinline@?&=?@ & bitwise AND assignment \impl{?&=?}\\
     488\lstinline@?^=?@ & exclusive OR assignment \impl{?^=?}\\
     489\lstinline@?|=?@ & inclusive OR assignment \impl{?"|=?}\\
    484490\end{tabular}
    485491\hfil
     
    496502
    497503\begin{rationale}
    498 The use of ``\lstinline$?$'' in identifiers means that some C programs are not \CFA programs.  For instance, the sequence of characters ``\lstinline$(i < 0)?--i:i$'' is legal in a C program, but a
    499 \CFA compiler detects a syntax error because it treats ``\lstinline$?--$'' as an identifier, not as the two tokens ``\lstinline$?$'' and ``\lstinline$--$''.
     504The use of ``\lstinline@?@'' in identifiers means that some C programs are not \CFA programs.  For instance, the sequence of characters ``\lstinline@(i < 0)?--i:i@'' is legal in a C program, but a
     505\CFA compiler detects a syntax error because it treats ``\lstinline@?--@'' as an identifier, not as the two tokens ``\lstinline@?@'' and ``\lstinline@--@''.
    500506\end{rationale}
    501507
     
    504510\begin{itemize}
    505511\item
    506 The logical operators ``\lstinline$&&$'' and ``\lstinline$||$'', and the conditional operator
    507 ``\lstinline$?:$''.
     512The logical operators ``\lstinline@&&@'' and ``\lstinline@||@'', and the conditional operator
     513``\lstinline@?:@''.
    508514These operators do not always evaluate their operands, and hence can not be properly defined by functions unless some mechanism like call-by-name is added to the language.
    509 Note that the definitions of ``\lstinline$&&$'' and ``\lstinline$||$'' say that they work by checking that their arguments are unequal to 0, so defining ``\lstinline$!=$'' and ``\lstinline$0$'' for user-defined types is enough to allow them to be used in logical expressions.
     515Note that the definitions of ``\lstinline@&&@'' and ``\lstinline@||@'' say that they work by checking that their arguments are unequal to 0, so defining ``\lstinline@!=@'' and ``\lstinline@0@'' for user-defined types is enough to allow them to be used in logical expressions.
    510516
    511517\item
     
    516522\item
    517523The ``address of'' operator.
    518 It would seem useful to define a unary ``\lstinline$&$'' operator that returns values of some programmer-defined pointer-like type.
     524It would seem useful to define a unary ``\lstinline@&@'' operator that returns values of some programmer-defined pointer-like type.
    519525The problem lies with the type of the operator.
    520 Consider the expression ``\lstinline$p = &x$'', where \lstinline$x$ is of type
    521 \lstinline$T$ and \lstinline$p$ has the programmer-defined type \lstinline$T_ptr$.
    522 The expression might be treated as a call to the unary function ``\lstinline$&?$''.
    523 Now what is the type of the function's parameter? It can not be \lstinline$T$, because then \lstinline$x$ would be passed by value, and there is no way to create a useful pointer-like result from a value.
    524 Hence the parameter must have type \lstinline$T *$.
    525 But then the expression must be rewritten as ``\lstinline$p = &?( &x )$''
     526Consider the expression ``\lstinline@p = &x@'', where \lstinline@x@ is of type
     527\lstinline@T@ and \lstinline@p@ has the programmer-defined type \lstinline@T_ptr@.
     528The expression might be treated as a call to the unary function ``\lstinline@&?@''.
     529Now what is the type of the function's parameter? It can not be \lstinline@T@, because then \lstinline@x@ would be passed by value, and there is no way to create a useful pointer-like result from a value.
     530Hence the parameter must have type \lstinline@T *@.
     531But then the expression must be rewritten as ``\lstinline@p = &?( &x )@''
    526532---which doesn't seem like progress!
    527533
    528534The rule for address-of expressions would have to be something like ``keep applying address-of functions until you get one that takes a pointer argument, then use the built-in operator and stop''.
    529 It seems simpler to define a conversion function from \lstinline$T *$ to \lstinline$T_ptr$.
    530 
    531 \item
    532 The \lstinline$sizeof$ operator.
     535It seems simpler to define a conversion function from \lstinline@T *@ to \lstinline@T_ptr@.
     536
     537\item
     538The \lstinline@sizeof@ operator.
    533539It is already defined for every object type, and intimately tied into the language's storage allocation model.
    534540Redefining it seems pointless.
    535541
    536542\item
    537 The ``member of'' operators ``\lstinline$.$'' and ``\lstinline$->$''.
     543The ``member of'' operators ``\lstinline@.@'' and ``\lstinline@->@''.
    538544These are not really infix operators, since their right ``operand'' is not a value or object.
    539545
     
    572578The ``fewest unsafe conversions'' rule ensures that the usual conversions are done, if possible.
    573579The ``lowest total expression cost'' rule chooses the proper common type.
    574 The odd-looking ``highest argument conversion cost'' rule ensures that, when unary expressions must be converted, conversions of function results are preferred to conversion of function arguments: \lstinline$(double)-i$ will be preferred to \lstinline$-(double)i$.
     580The odd-looking ``highest argument conversion cost'' rule ensures that, when unary expressions must be converted, conversions of function results are preferred to conversion of function arguments: \lstinline@(double)-i@ will be preferred to \lstinline@-(double)i@.
    575581
    576582The ``least polymorphic'' rule reduces the number of polymorphic function calls, since such functions are presumably more expensive than monomorphic functions and since the more specific function is presumably more appropriate.
    577583It also gives preference to monomorphic values (such as the
    578 \lstinline$int$ \lstinline$0$) over polymorphic values (such as the \Index{null pointer}
    579 \lstinline$0$\use{0}).
     584\lstinline@int@ \lstinline@0@) over polymorphic values (such as the \Index{null pointer}
     585\lstinline@0@\use{0}).
    580586However, interpretations that call polymorphic functions are preferred to interpretations that perform unsafe conversions, because those conversions potentially lose accuracy or violate strong typing.
    581587
     
    597603\begin{rationale}
    598604Predefined functions and constants have internal linkage because that simplifies optimization in traditional compile-and-link environments.
    599 For instance, ``\lstinline$an_int + an_int$'' is equivalent to ``\lstinline$?+?(an_int, an_int)$''.
     605For instance, ``\lstinline@an_int + an_int@'' is equivalent to ``\lstinline@?+?(an_int, an_int)@''.
    600606If integer addition has not been redefined in the current scope, a compiler can generate code to perform the addition directly.
    601607If predefined functions had external linkage, this optimization would be difficult.
     
    623629\rhs \nonterm{constant}
    624630\rhs \nonterm{string-literal}
    625 \rhs \lstinline$($ \nonterm{expression} \lstinline$)$
     631\rhs \lstinline@(@ \nonterm{expression} \lstinline@)@
    626632\rhs \nonterm{generic-selection}
    627633\end{syntax}
     
    629635\predefined
    630636\begin{lstlisting}
    631 const int 1;@\use{1}@
    632 const int 0;@\use{0}@
     637const int 1;§\use{1}§
     638const int 0;§\use{0}§
    633639forall( dtype DT ) DT * const 0;
    634640forall( ftype FT ) FT * const 0;
     
    639645
    640646A \nonterm{constant} or \nonterm{string-literal} has one valid interpretation, which has the type and value defined by {\c11}.
    641 The predefined integer identifiers ``\lstinline$1$'' and ``\lstinline$0$'' have the integer values 1 and 0, respectively.
    642 The other two predefined ``\lstinline$0$'' identifiers are bound to polymorphic pointer values that, when specialized\index{specialization} with a data type or function type respectively, produce a null pointer of that type.
     647The predefined integer identifiers ``\lstinline@1@'' and ``\lstinline@0@'' have the integer values 1 and 0, respectively.
     648The other two predefined ``\lstinline@0@'' identifiers are bound to polymorphic pointer values that, when specialized\index{specialization} with a data type or function type respectively, produce a null pointer of that type.
    643649
    644650A parenthesised expression has the same interpretations as the contained \nonterm{expression}.
    645651
    646652\examples
    647 The expression \lstinline$(void *)0$\use{0} specializes the (polymorphic) null pointer to a null pointer to \lstinline$void$. \lstinline$(const void *)0$ does the same, and also uses a safe conversion from \lstinline$void *$ to \lstinline$const void *$.
     653The expression \lstinline@(void *)0@\use{0} specializes the (polymorphic) null pointer to a null pointer to \lstinline@void@. \lstinline@(const void *)0@ does the same, and also uses a safe conversion from \lstinline@void *@ to \lstinline@const void *@.
    648654In each case, the null pointer conversion is better\index{best valid interpretations} than the unsafe conversion of the integer
    649 \lstinline$0$ to a pointer.
     655\lstinline@0@ to a pointer.
    650656
    651657\begin{rationale}
     
    653659
    654660\CFA does not have C's concept of ``null pointer constants'', which are not typed values but special strings of tokens.
    655 The C token ``\lstinline$0$'' is an expression of type \lstinline$int$ with the value ``zero'', and it \emph{also} is a null pointer constant.
     661The C token ``\lstinline@0@'' is an expression of type \lstinline@int@ with the value ``zero'', and it \emph{also} is a null pointer constant.
    656662Similarly,
    657 ``\lstinline$(void *)0$ is an expression of type \lstinline$(void *)$ whose value is a null pointer, and it also is a null pointer constant.
    658 However, in C, ``\lstinline$(void *)(void *)0$'' is
     663``\lstinline@(void *)0@ is an expression of type \lstinline@(void *)@ whose value is a null pointer, and it also is a null pointer constant.
     664However, in C, ``\lstinline@(void *)(void *)0@'' is
    659665\emph{not} a null pointer constant, even though it is null-valued, a pointer, and constant! The semantics of C expressions contain many special cases to deal with subexpressions that are null pointer constants.
    660666
     
    663669\begin{lstlisting}
    664670forall( dtype DT ) DT * const 0;
    665 \end{lstlisting} means that \lstinline$0$ is a polymorphic object, and contains a value that can have \emph{any} pointer-to-object type or pointer-to-incomplete type.
     671\end{lstlisting} means that \lstinline@0@ is a polymorphic object, and contains a value that can have \emph{any} pointer-to-object type or pointer-to-incomplete type.
    666672The only such value is the null pointer.
    667673Therefore the type \emph{alone} is enough to identify a null pointer.
     
    673679
    674680\constraints The best interpretation of the controlling expression shall be unambiguous\index{ambiguous interpretation}, and shall have type compatible with at most one of the types named in its generic association list.
    675 If a generic selection has no \lstinline$default$ generic association, the best interpretation of its controlling expression shall have type compatible with exactly one of the types named in its generic association list.
     681If a generic selection has no \lstinline@default@ generic association, the best interpretation of its controlling expression shall have type compatible with exactly one of the types named in its generic association list.
    676682
    677683\semantics
     
    684690\lhs{postfix-expression}
    685691\rhs \nonterm{primary-expression}
    686 \rhs \nonterm{postfix-expression} \lstinline$[$ \nonterm{expression} \lstinline$]$
    687 \rhs \nonterm{postfix-expression} \lstinline$($
    688          \nonterm{argument-expression-list}\opt \lstinline$)$
    689 \rhs \nonterm{postfix-expression} \lstinline$.$ \nonterm{identifier}
    690 \rhs \nonterm{postfix-expression} \lstinline$->$ \nonterm{identifier}
    691 \rhs \nonterm{postfix-expression} \lstinline$++$
    692 \rhs \nonterm{postfix-expression} \lstinline$--$
    693 \rhs \lstinline$($ \nonterm{type-name} \lstinline$)$ \lstinline${$ \nonterm{initializer-list} \lstinline$}$
    694 \rhs \lstinline$($ \nonterm{type-name} \lstinline$)$ \lstinline${$ \nonterm{initializer-list} \lstinline$,$ \lstinline$}$
     692\rhs \nonterm{postfix-expression} \lstinline@[@ \nonterm{expression} \lstinline@]@
     693\rhs \nonterm{postfix-expression} \lstinline@(@
     694         \nonterm{argument-expression-list}\opt \lstinline@)@
     695\rhs \nonterm{postfix-expression} \lstinline@.@ \nonterm{identifier}
     696\rhs \nonterm{postfix-expression} \lstinline@->@ \nonterm{identifier}
     697\rhs \nonterm{postfix-expression} \lstinline@++@
     698\rhs \nonterm{postfix-expression} \lstinline@--@
     699\rhs \lstinline@(@ \nonterm{type-name} \lstinline@)@ \lstinline@{@ \nonterm{initializer-list} \lstinline@}@
     700\rhs \lstinline@(@ \nonterm{type-name} \lstinline@)@ \lstinline@{@ \nonterm{initializer-list} \lstinline@,@ \lstinline@}@
    695701\lhs{argument-expression-list}
    696702\rhs \nonterm{assignment-expression}
    697 \rhs \nonterm{argument-expression-list} \lstinline$,$
     703\rhs \nonterm{argument-expression-list} \lstinline@,@
    698704         \nonterm{assignment-expression}
    699705\end{syntax}
     
    701707\rewriterules
    702708\begin{lstlisting}
    703 a[b] @\rewrite@ ?[?]( b, a ) // if a has integer type@\use{?[?]}@
    704 a[b] @\rewrite@ ?[?]( a, b ) // otherwise
    705 a( @\emph{arguments}@ ) @\rewrite@ ?()( a, @\emph{arguments}@ )@\use{?()}@
    706 a++ @\rewrite@ ?++(&( a ))@\use{?++}@
    707 a-- @\rewrite@ ?--(&( a ))@\use{?--}@
     709a[b] §\rewrite§ ?[?]( b, a ) // if a has integer type§\use{?[?]}§
     710a[b] §\rewrite§ ?[?]( a, b ) // otherwise
     711a( §\emph{arguments}§ ) §\rewrite§ ?()( a, §\emph{arguments}§ )§\use{?()}§
     712a++ §\rewrite§ ?++(&( a ))§\use{?++}§
     713a-- §\rewrite§ ?--(&( a ))§\use{?--}§
    708714\end{lstlisting}
    709715
     
    713719\predefined
    714720\begin{lstlisting}
    715 forall( otype T ) lvalue T ?[?]( T *, ptrdiff_t );@\use{ptrdiff_t}@
     721forall( otype T ) lvalue T ?[?]( T *, ptrdiff_t );§\use{ptrdiff_t}§
    716722forall( otype T ) lvalue _Atomic T ?[?]( _Atomic T *, ptrdiff_t );
    717723forall( otype T ) lvalue const T ?[?]( const T *, ptrdiff_t );
     
    733739The interpretations of subscript expressions are the interpretations of the corresponding function call expressions.
    734740\begin{rationale}
    735 C defines subscripting as pointer arithmetic in a way that makes \lstinline$a[i]$ and
    736 \lstinline$i[a]$ equivalent. \CFA provides the equivalence through a rewrite rule to reduce the number of overloadings of \lstinline$?[?]$.
     741C defines subscripting as pointer arithmetic in a way that makes \lstinline@a[i]@ and
     742\lstinline@i[a]@ equivalent. \CFA provides the equivalence through a rewrite rule to reduce the number of overloadings of \lstinline@?[?]@.
    737743
    738744Subscript expressions are rewritten as function calls that pass the first parameter by value.
    739745This is somewhat unfortunate, since array-like types tend to be large.
    740 The alternative is to use the rewrite rule ``\lstinline$a[b]$ \rewrite \lstinline$?[?](&(a), b)$''.
    741 However, C semantics forbid this approach: the \lstinline$a$ in ``\lstinline$a[b]$'' can be an arbitrary pointer value, which does not have an address.
     746The alternative is to use the rewrite rule ``\lstinline@a[b]@ \rewrite \lstinline@?[?](&(a), b)@''.
     747However, C semantics forbid this approach: the \lstinline@a@ in ``\lstinline@a[b]@'' can be an arbitrary pointer value, which does not have an address.
    742748
    743749The repetitive form of the predefined identifiers shows up a deficiency\index{deficiencies!pointers
     
    754760\nonterm{postfix-expression} in a function call may have some interpretations that are function designators and some that are not.
    755761
    756 For those interpretations of the \nonterm{postfix-expression} that are not function designators, the expression is rewritten and becomes a call of a function named ``\lstinline$?()$''.
     762For those interpretations of the \nonterm{postfix-expression} that are not function designators, the expression is rewritten and becomes a call of a function named ``\lstinline@?()@''.
    757763The valid interpretations of the rewritten expression are determined in the manner described below.
    758764
     
    762768\item if the argument corresponds to a parameter in the function designator's prototype, the argument interpretation must have the same type as the corresponding parameter, or be implicitly convertible to the parameter's type
    763769\item if the function designator's type does not include a prototype or if the argument corresponds to
    764 ``\lstinline$...$'' in a prototype, a \Index{default argument promotion} is applied to it.
     770``\lstinline@...@'' in a prototype, a \Index{default argument promotion} is applied to it.
    765771\end{itemize}
    766772The type of the valid interpretation is the return type of the function designator.
     
    770776\begin{itemize}
    771777\item
    772 If the declaration of the implicit parameter uses \Index{type-class} \lstinline$type$\use{type}, the implicit argument must be an object type;
    773 if it uses \lstinline$dtype$, the implicit argument must be an object type or an incomplete type;
    774 and if it uses \lstinline$ftype$, the implicit argument must be a function type.
     778If the declaration of the implicit parameter uses \Index{type-class} \lstinline@type@\use{type}, the implicit argument must be an object type;
     779if it uses \lstinline@dtype@, the implicit argument must be an object type or an incomplete type;
     780and if it uses \lstinline@ftype@, the implicit argument must be a function type.
    775781
    776782\item if an explicit parameter's type uses any implicit parameters, then the corresponding explicit argument must have a type that is (or can be safely converted\index{safe conversion} to) the type produced by substituting the implicit arguments for the implicit parameters in the explicit parameter type.
     
    791797\begin{rationale}
    792798One desirable property of a polymorphic programming language is \define{generalizability}: the ability to replace an abstraction with a more general but equivalent abstraction without requiring changes in any of the uses of the original\cite{Cormack90}.
    793 For instance, it should be possible to replace a function ``\lstinline$int f( int );$'' with ``\lstinline$forall( otype T ) T f( T );$'' without affecting any calls of \lstinline$f$.
     799For instance, it should be possible to replace a function ``\lstinline@int f( int );@'' with ``\lstinline@forall( otype T ) T f( T );@'' without affecting any calls of \lstinline@f@.
    794800
    795801\CFA\index{deficiencies!generalizability} does not fully possess this property, because
     
    805811f = g( d, f );          // (3) (unsafe conversion to float)
    806812\end{lstlisting}
    807 If \lstinline$g$ was replaced by ``\lstinline$forall( otype T ) T g( T, T );$'', the first and second calls would be unaffected, but the third would change: \lstinline$f$ would be converted to
    808 \lstinline$double$, and the result would be a \lstinline$double$.
    809 
    810 Another example is the function ``\lstinline$void h( int *);$''.
     813If \lstinline@g@ was replaced by ``\lstinline@forall( otype T ) T g( T, T );@'', the first and second calls would be unaffected, but the third would change: \lstinline@f@ would be converted to
     814\lstinline@double@, and the result would be a \lstinline@double@.
     815
     816Another example is the function ``\lstinline@void h( int *);@''.
    811817This function can be passed a
    812 \lstinline$void *$ argument, but the generalization ``\lstinline$forall( otype T ) void h( T *);$'' can not.
    813 In this case, \lstinline$void$ is not a valid value for \lstinline$T$ because it is not an object type.
    814 If unsafe conversions were allowed, \lstinline$T$ could be inferred to be \emph{any} object type, which is undesirable.
     818\lstinline@void *@ argument, but the generalization ``\lstinline@forall( otype T ) void h( T *);@'' can not.
     819In this case, \lstinline@void@ is not a valid value for \lstinline@T@ because it is not an object type.
     820If unsafe conversions were allowed, \lstinline@T@ could be inferred to be \emph{any} object type, which is undesirable.
    815821\end{rationale}
    816822
    817823\examples
    818 A function called ``\lstinline$?()$'' might be part of a numerical differentiation package.
     824A function called ``\lstinline@?()@'' might be part of a numerical differentiation package.
    819825\begin{lstlisting}
    820826extern otype Derivative;
     
    827833d = sin_dx( 12.9 );
    828834\end{lstlisting}
    829 Here, the only interpretation of \lstinline$sin_dx$ is as an object of type \lstinline$Derivative$.
    830 For that interpretation, the function call is treated as ``\lstinline$?()( sin_dx, 12.9 )$''.
     835Here, the only interpretation of \lstinline@sin_dx@ is as an object of type \lstinline@Derivative@.
     836For that interpretation, the function call is treated as ``\lstinline@?()( sin_dx, 12.9 )@''.
    831837\begin{lstlisting}
    832838int f( long );          // (1)
     
    835841int i = f( 5 );         // calls (1)
    836842\end{lstlisting}
    837 Function (1) provides a valid interpretation of ``\lstinline$f( 5 )$'', using an implicit \lstinline$int$ to \lstinline$long$ conversion.
    838 The other functions do not, since the second requires two arguments, and since there is no implicit conversion from \lstinline$int$ to \lstinline$int *$ that could be used with the third function.
     843Function (1) provides a valid interpretation of ``\lstinline@f( 5 )@'', using an implicit \lstinline@int@ to \lstinline@long@ conversion.
     844The other functions do not, since the second requires two arguments, and since there is no implicit conversion from \lstinline@int@ to \lstinline@int *@ that could be used with the third function.
    839845
    840846\begin{lstlisting}
     
    842848double d = h( 1.5 );
    843849\end{lstlisting}
    844 ``\lstinline$1.5$'' is a \lstinline$double$ constant, so \lstinline$T$ is inferred to be
    845 \lstinline$double$, and the result of the function call is a \lstinline$double$.
     850``\lstinline@1.5@'' is a \lstinline@double@ constant, so \lstinline@T@ is inferred to be
     851\lstinline@double@, and the result of the function call is a \lstinline@double@.
    846852
    847853\begin{lstlisting}
     
    858864g( i, p );                      // calls (4)
    859865\end{lstlisting}
    860 The first call has valid interpretations for all four versions of \lstinline$g$. (6) and (7) are discarded because they involve unsafe \lstinline$double$-to-\lstinline$long$ conversions. (5) is chosen because it is less polymorphic than (4).
     866The first call has valid interpretations for all four versions of \lstinline@g@. (6) and (7) are discarded because they involve unsafe \lstinline@double@-to-\lstinline@long@ conversions. (5) is chosen because it is less polymorphic than (4).
    861867
    862868For the second call, (7) is again discarded.
    863 Of the remaining interpretations for (4), (5), and (6) (with \lstinline$i$ converted to \lstinline$long$), (6) is chosen because it is the least polymorphic.
     869Of the remaining interpretations for (4), (5), and (6) (with \lstinline@i@ converted to \lstinline@long@), (6) is chosen because it is the least polymorphic.
    864870
    865871The third call has valid interpretations for all of the functions;
     
    870876forall( otype T ) T min( T, T );
    871877double max( double, double );
    872 trait min_max( T ) {@\impl{min_max}@
     878trait min_max( T ) {§\impl{min_max}§
    873879        T min( T, T );
    874880        T max( T, T );
     
    877883shuffle( 9, 10 );
    878884\end{lstlisting}
    879 The only possibility for \lstinline$U$ is \lstinline$double$, because that is the type used in the only visible \lstinline$max$ function. 9 and 10 must be converted to \lstinline$double$, and
    880 \lstinline$min$ must be specialized with \lstinline$T$ bound to \lstinline$double$.
     885The only possibility for \lstinline@U@ is \lstinline@double@, because that is the type used in the only visible \lstinline@max@ function. 9 and 10 must be converted to \lstinline@double@, and
     886\lstinline@min@ must be specialized with \lstinline@T@ bound to \lstinline@double@.
    881887\begin{lstlisting}
    882888extern void q( int );           // (8)
     
    886892r( 0 );
    887893\end{lstlisting}
    888 The \lstinline$int 0$ could be passed to (8), or the \lstinline$(void *)$ \Index{specialization} of the null pointer\index{null pointer} \lstinline$0$\use{0} could be passed to (9).
    889 The former is chosen because the \lstinline$int$ \lstinline$0$ is \Index{less polymorphic}.
    890 For the same reason, \lstinline$int$ \lstinline$0$ is passed to \lstinline$r()$, even though it has \emph{no} declared parameter types.
     894The \lstinline@int 0@ could be passed to (8), or the \lstinline@(void *)@ \Index{specialization} of the null pointer\index{null pointer} \lstinline@0@\use{0} could be passed to (9).
     895The former is chosen because the \lstinline@int@ \lstinline@0@ is \Index{less polymorphic}.
     896For the same reason, \lstinline@int@ \lstinline@0@ is passed to \lstinline@r()@, even though it has \emph{no} declared parameter types.
    891897
    892898
    893899\subsubsection{Structure and union members}
    894900
    895 \semantics In the member selection expression ``\lstinline$s$.\lstinline$m$'', there shall be at least one interpretation of \lstinline$s$ whose type is a structure type or union type containing a member named \lstinline$m$.
    896 If two or more interpretations of \lstinline$s$ have members named
    897 \lstinline$m$ with mutually compatible types, then the expression has an \Index{ambiguous interpretation} whose type is the composite type of the types of the members.
    898 If an interpretation of \lstinline$s$ has a member \lstinline$m$ whose type is not compatible with any other
    899 \lstinline$s$'s \lstinline$m$, then the expression has an interpretation with the member's type.
     901\semantics In the member selection expression ``\lstinline@s@.\lstinline@m@'', there shall be at least one interpretation of \lstinline@s@ whose type is a structure type or union type containing a member named \lstinline@m@.
     902If two or more interpretations of \lstinline@s@ have members named
     903\lstinline@m@ with mutually compatible types, then the expression has an \Index{ambiguous interpretation} whose type is the composite type of the types of the members.
     904If an interpretation of \lstinline@s@ has a member \lstinline@m@ whose type is not compatible with any other
     905\lstinline@s@'s \lstinline@m@, then the expression has an interpretation with the member's type.
    900906The expression has no other interpretations.
    901907
    902 The expression ``\lstinline$p->m$'' has the same interpretations as the expression
    903 ``\lstinline$(*p).m$''.
     908The expression ``\lstinline@p->m@'' has the same interpretations as the expression ``\lstinline@(*p).m@''.
    904909
    905910
     
    9961001        * ?--( _Atomic const restrict volatile T * _Atomic restrict volatile * );
    9971002\end{lstlisting}
    998 For every extended integer type \lstinline$X$ there exist
     1003For every extended integer type \lstinline@X@ there exist
    9991004% Don't use predefined: keep this out of prelude.cf.
    10001005\begin{lstlisting}
     
    10021007  ?--( volatile X * ), ?--( _Atomic volatile X * );
    10031008\end{lstlisting}
    1004 For every complete enumerated type \lstinline$E$ there exist
     1009For every complete enumerated type \lstinline@E@ there exist
    10051010% Don't use predefined: keep this out of prelude.cf.
    10061011\begin{lstlisting}
     
    10101015
    10111016\begin{rationale}
    1012 Note that ``\lstinline$++$'' and ``\lstinline$--$'' are rewritten as function calls that are given a pointer to that operand. (This is true of all operators that modify an operand.) As Hamish Macdonald has pointed out, this forces the modified operand of such expressions to be an lvalue.
     1017Note that ``\lstinline@++@'' and ``\lstinline@--@'' are rewritten as function calls that are given a pointer to that operand. (This is true of all operators that modify an operand.) As Hamish Macdonald has pointed out, this forces the modified operand of such expressions to be an lvalue.
    10131018This partially enforces the C semantic rule that such operands must be \emph{modifiable} lvalues.
    10141019\end{rationale}
     
    10161021\begin{rationale}
    10171022In C, a semantic rule requires that pointer operands of increment and decrement be pointers to object types.
    1018 Hence, \lstinline$void *$ objects cannot be incremented.
    1019 In \CFA, the restriction follows from the use of a \lstinline$type$ parameter in the predefined function definitions, as opposed to \lstinline$dtype$, since only object types can be inferred arguments corresponding to the type parameter \lstinline$T$.
     1023Hence, \lstinline@void *@ objects cannot be incremented.
     1024In \CFA, the restriction follows from the use of a \lstinline@type@ parameter in the predefined function definitions, as opposed to \lstinline@dtype@, since only object types can be inferred arguments corresponding to the type parameter \lstinline@T@.
    10201025\end{rationale}
    10211026
    10221027\semantics
    10231028First, each interpretation of the operand of an increment or decrement expression is considered separately.
    1024 For each interpretation that is a bit-field or is declared with the
    1025 \lstinline$register$\index{register@{\lstinline$register$}} \index{Itorage-class specifier}, the expression has one valid interpretation, with the type of the operand, and the expression is ambiguous if the operand is.
     1029For each interpretation that is a bit-field or is declared with the \Indexc{register}\index{storage-class specifier}, the expression has one valid interpretation, with the type of the operand, and the expression is ambiguous if the operand is.
    10261030
    10271031For the remaining interpretations, the expression is rewritten, and the interpretations of the expression are the interpretations of the corresponding function call.
     
    10361040\end{lstlisting}
    10371041\begin{sloppypar}
    1038 Since \lstinline$&(vs)$ has type \lstinline$volatile short int *$, the best valid interpretation of
    1039 \lstinline$vs++$ calls the \lstinline$?++$ function with the \lstinline$volatile short *$ parameter.
    1040 \lstinline$s++$ does the same, applying the safe conversion from \lstinline$short int *$ to
    1041 \lstinline$volatile short int *$.
    1042 Note that there is no conversion that adds an \lstinline$_Atomic$ qualifier, so the \lstinline$_Atomic volatile short int$ overloading does not provide a valid interpretation.
     1042Since \lstinline@&(vs)@ has type \lstinline@volatile short int *@, the best valid interpretation of
     1043\lstinline@vs++@ calls the \lstinline@?++@ function with the \lstinline@volatile short *@ parameter.
     1044\lstinline@s++@ does the same, applying the safe conversion from \lstinline@short int *@ to \lstinline@volatile short int *@.
     1045Note that there is no conversion that adds an \lstinline@_Atomic@ qualifier, so the \lstinline@_Atomic volatile short int@ overloading does not provide a valid interpretation.
    10431046\end{sloppypar}
    10441047
    1045 There is no safe conversion from \lstinline$const short int *$ to \lstinline$volatile short int *$, and no \lstinline$?++$ function that accepts a \lstinline$const *$ parameter, so \lstinline$cs++$ has no valid interpretations.
    1046 
    1047 The best valid interpretation of \lstinline$as++$ calls the \lstinline$short ?++$ function with the \lstinline$_Atomic volatile short int *$ parameter, applying a safe conversion to add the \lstinline$volatile$ qualifier.
     1048There is no safe conversion from \lstinline@const short int *@ to \lstinline@volatile short int *@, and no \lstinline@?++@ function that accepts a \lstinline@const *@ parameter, so \lstinline@cs++@ has no valid interpretations.
     1049
     1050The best valid interpretation of \lstinline@as++@ calls the \lstinline@short ?++@ function with the \lstinline@_Atomic volatile short int *@ parameter, applying a safe conversion to add the \lstinline@volatile@ qualifier.
    10481051\begin{lstlisting}
    10491052char * const restrict volatile * restrict volatile pqpc;
     
    10521055ppc++;
    10531056\end{lstlisting}
    1054 Since \lstinline$&(pqpc)$ has type \lstinline$char * const restrict volatile * restrict volatile *$, the best valid interpretation of \lstinline$pqpc++$ calls the polymorphic \lstinline$?++$ function with the \lstinline$const restrict volatile T * restrict volatile *$ parameter, inferring \lstinline$T$ to be \lstinline$char *$.
    1055 
    1056 \lstinline$ppc++$ calls the same function, again inferring \lstinline$T$ to be \lstinline$char *$, and using the safe conversions from \lstinline$T$ to \lstinline$T const$ \lstinline$restrict volatile$.
     1057Since \lstinline@&(pqpc)@ has type \lstinline@char * const restrict volatile * restrict volatile *@, the best valid interpretation of \lstinline@pqpc++@ calls the polymorphic \lstinline@?++@ function with the \lstinline@const restrict volatile T * restrict volatile *@ parameter, inferring \lstinline@T@ to be \lstinline@char *@.
     1058
     1059\lstinline@ppc++@ calls the same function, again inferring \lstinline@T@ to be \lstinline@char *@, and using the safe conversions from \lstinline@T@ to \lstinline@T const@ \lstinline@restrict volatile@.
    10571060
    10581061\begin{rationale}
     
    10681071\begin{enumerate}
    10691072\item
    1070 ``\lstinline$char * p; p++;$''.
    1071 The argument to \lstinline$?++$ has type \lstinline$char * *$, and the result has type \lstinline$char *$.
    1072 The expression would be valid if \lstinline$?++$ were declared by
     1073``\lstinline@char * p; p++;@''.
     1074The argument to \lstinline@?++@ has type \lstinline@char * *@, and the result has type \lstinline@char *@.
     1075The expression would be valid if \lstinline@?++@ were declared by
    10731076\begin{lstlisting}
    10741077forall( otype T ) T * ?++( T * * );
    1075 \end{lstlisting} with \lstinline$T$ inferred to be \lstinline$char$.
    1076 
    1077 \item
    1078 ``\lstinline$char *restrict volatile qp; qp++$''.
    1079 The result again has type \lstinline$char *$, but the argument now has type \lstinline$char *restrict volatile *$, so it cannot be passed to the hypothetical function declared in point 1.
     1078\end{lstlisting} with \lstinline@T@ inferred to be \lstinline@char@.
     1079
     1080\item
     1081``\lstinline@char *restrict volatile qp; qp++@''.
     1082The result again has type \lstinline@char *@, but the argument now has type \lstinline@char *restrict volatile *@, so it cannot be passed to the hypothetical function declared in point 1.
    10801083Hence the actual predefined function is
    10811084\begin{lstlisting}
    10821085forall( otype T ) T * ?++( T * restrict volatile * );
    1083 \end{lstlisting} which also accepts a \lstinline$char * *$ argument, because of the safe conversions that add
    1084 \lstinline$volatile$ and \lstinline$restrict$ qualifiers. (The parameter is not const-qualified, so constant pointers cannot be incremented.)
    1085 
    1086 \item
    1087 ``\lstinline$char *_Atomic ap; ap++$''.
    1088 The result again has type \lstinline$char *$, but no safe conversion adds an \lstinline$_Atomic$ qualifier, so the function in point 2 is not applicable.
    1089 A separate overloading of \lstinline$?++$ is required.
    1090 
    1091 \item
    1092 ``\lstinline$char const volatile * pq; pq++$''.
     1086\end{lstlisting} which also accepts a \lstinline@char * *@ argument, because of the safe conversions that add
     1087\lstinline@volatile@ and \lstinline@restrict@ qualifiers. (The parameter is not const-qualified, so constant pointers cannot be incremented.)
     1088
     1089\item
     1090``\lstinline@char *_Atomic ap; ap++@''.
     1091The result again has type \lstinline@char *@, but no safe conversion adds an \lstinline@_Atomic@ qualifier, so the function in point 2 is not applicable.
     1092A separate overloading of \lstinline@?++@ is required.
     1093
     1094\item
     1095``\lstinline@char const volatile * pq; pq++@''.
    10931096Here the result has type
    1094 \lstinline$char const volatile *$, so a new overloading is needed:
     1097\lstinline@char const volatile *@, so a new overloading is needed:
    10951098\begin{lstlisting}
    10961099forall( otype T ) T const volatile * ?++( T const volatile *restrict volatile * );
     
    10991102 
    11001103\item
    1101 ``\lstinline$float *restrict * prp; prp++$''.
    1102 The \lstinline$restrict$ qualifier is handled just like \lstinline$const$ and \lstinline$volatile$ in the previous case:
     1104``\lstinline@float *restrict * prp; prp++@''.
     1105The \lstinline@restrict@ qualifier is handled just like \lstinline@const@ and \lstinline@volatile@ in the previous case:
    11031106\begin{lstlisting}
    11041107forall( otype T ) T restrict * ?++( T restrict *restrict volatile * );
    1105 \end{lstlisting} with \lstinline$T$ inferred to be \lstinline$float *$.
    1106 This looks odd, because {\c11} contains a constraint that requires restrict-qualified types to be pointer-to-object types, and \lstinline$T$ is not syntactically a pointer type. \CFA loosens the constraint.
     1108\end{lstlisting} with \lstinline@T@ inferred to be \lstinline@float *@.
     1109This looks odd, because {\c11} contains a constraint that requires restrict-qualified types to be pointer-to-object types, and \lstinline@T@ is not syntactically a pointer type. \CFA loosens the constraint.
    11071110\end{enumerate}
    11081111\end{rationale}
     
    11201123\lhs{unary-expression}
    11211124\rhs \nonterm{postfix-expression}
    1122 \rhs \lstinline$++$ \nonterm{unary-expression}
    1123 \rhs \lstinline$--$ \nonterm{unary-expression}
     1125\rhs \lstinline@++@ \nonterm{unary-expression}
     1126\rhs \lstinline@--@ \nonterm{unary-expression}
    11241127\rhs \nonterm{unary-operator} \nonterm{cast-expression}
    1125 \rhs \lstinline$sizeof$ \nonterm{unary-expression}
    1126 \rhs \lstinline$sizeof$ \lstinline$($ \nonterm{type-name} \lstinline$)$
    1127 \lhs{unary-operator} one of \rhs \lstinline$&$ \lstinline$*$ \lstinline$+$ \lstinline$-$ \lstinline$~$ \lstinline$!$
     1128\rhs \lstinline@sizeof@ \nonterm{unary-expression}
     1129\rhs \lstinline@sizeof@ \lstinline@(@ \nonterm{type-name} \lstinline@)@
     1130\lhs{unary-operator} one of \rhs \lstinline@&@ \lstinline@*@ \lstinline@+@ \lstinline@-@ \lstinline@~@ \lstinline@!@
    11281131\end{syntax}
    11291132
    11301133\rewriterules
    11311134\begin{lstlisting}
    1132 *a      @\rewrite@ *?( a ) @\use{*?}@
    1133 +a      @\rewrite@ +?( a ) @\use{+?}@
    1134 -a      @\rewrite@ -?( a ) @\use{-?}@
    1135 ~a      @\rewrite@ ~?( a ) @\use{~?}@
    1136 !a      @\rewrite@ !?( a ) @\use{"!?}@
    1137 ++a     @\rewrite@ ++?(&( a )) @\use{++?}@
    1138 --a     @\rewrite@ --?(&( a )) @\use{--?}@
     1135*a      §\rewrite§ *?( a ) §\use{*?}§
     1136+a      §\rewrite§ +?( a ) §\use{+?}§
     1137-a      §\rewrite§ -?( a ) §\use{-?}§
     1138~a      §\rewrite§ ~?( a ) §\use{~?}§
     1139!a      §\rewrite§ !?( a ) §\use{"!?}§
     1140++a     §\rewrite§ ++?(&( a )) §\use{++?}§
     1141--a     §\rewrite§ --?(&( a )) §\use{--?}§
    11391142\end{lstlisting}
    11401143
     
    12321235        * --?( _Atomic const restrict volatile T * _Atomic restrict volatile * );
    12331236\end{lstlisting}
    1234 For every extended integer type \lstinline$X$ there exist
     1237For every extended integer type \lstinline@X@ there exist
    12351238% Don't use predefined: keep this out of prelude.cf.
    12361239\begin{lstlisting}
     
    12401243        --?( _Atomic volatile X * );
    12411244\end{lstlisting}
    1242 For every complete enumerated type \lstinline$E$ there exist
     1245For every complete enumerated type \lstinline@E@ there exist
    12431246% Don't use predefined: keep this out of prelude.cf.
    12441247\begin{lstlisting}
     
    12771280
    12781281\constraints
    1279 The operand of the unary ``\lstinline$&$'' operator shall have exactly one
     1282The operand of the unary ``\lstinline@&@'' operator shall have exactly one
    12801283\Index{interpretation}\index{ambiguous interpretation}, which shall be unambiguous.
    12811284
    12821285\semantics
    1283 The ``\lstinline$&$'' expression has one interpretation which is of type \lstinline$T *$, where
    1284 \lstinline$T$ is the type of the operand.
     1286The ``\lstinline@&@'' expression has one interpretation which is of type \lstinline@T *@, where
     1287\lstinline@T@ is the type of the operand.
    12851288
    12861289The interpretations of an indirection expression are the interpretations of the corresponding function call.
     
    13111314forall( ftype FT ) int !?( FT * );
    13121315\end{lstlisting}
    1313 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1316For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist
    13141317% Don't use predefined: keep this out of prelude.cf.
    13151318\begin{lstlisting}
     
    13241327\begin{lstlisting}
    13251328long int li;
    1326 void eat_double( double );@\use{eat_double}@
    1327 eat_double(-li ); // @\rewrite@ eat_double( -?( li ) );
    1328 \end{lstlisting}
    1329 The valid interpretations of ``\lstinline$-li$'' (assuming no extended integer types exist) are
     1329void eat_double( double );§\use{eat_double}§
     1330eat_double(-li ); // §\rewrite§ eat_double( -?( li ) );
     1331\end{lstlisting}
     1332The valid interpretations of ``\lstinline@-li@'' (assuming no extended integer types exist) are
    13301333\begin{center}
    13311334\begin{tabular}{llc} interpretation & result type & expression conversion cost \\
    13321335\hline
    1333 \lstinline$-?( (int)li )$                                       & \lstinline$int$                                       & (unsafe) \\
    1334 \lstinline$-?( (unsigned)li)$                           & \lstinline$unsigned int$                      & (unsafe) \\
    1335 \lstinline$-?( (long)li)$                                       & \lstinline$long$                                      & 0 \\
    1336 \lstinline$-?( (long unsigned int)li)$          & \lstinline$long unsigned int$         & 1 \\
    1337 \lstinline$-?( (long long int)li)$                      & \lstinline$long long int$                     & 2 \\
    1338 \lstinline$-?( (long long unsigned int)li)$     & \lstinline$long long unsigned int$& 3 \\
    1339 \lstinline$-?( (float)li)$                                      & \lstinline$float$                                     & 4 \\
    1340 \lstinline$-?( (double)li)$                                     & \lstinline$double$                            & 5 \\
    1341 \lstinline$-?( (long double)li)$                        & \lstinline$long double$                       & 6 \\
    1342 \lstinline$-?( (_Complex float)li)$                     & \lstinline$float$                                     & (unsafe) \\
    1343 \lstinline$-?( (_Complex double)li)$            & \lstinline$double$                            & (unsafe) \\
    1344 \lstinline$-?( (_Complex long double)li)$       & \lstinline$long double$                       & (unsafe) \\
     1336\lstinline@-?( (int)li )@                                       & \lstinline@int@                                       & (unsafe) \\
     1337\lstinline@-?( (unsigned)li)@                           & \lstinline@unsigned int@                      & (unsafe) \\
     1338\lstinline@-?( (long)li)@                                       & \lstinline@long@                                      & 0 \\
     1339\lstinline@-?( (long unsigned int)li)@          & \lstinline@long unsigned int@         & 1 \\
     1340\lstinline@-?( (long long int)li)@                      & \lstinline@long long int@                     & 2 \\
     1341\lstinline@-?( (long long unsigned int)li)@     & \lstinline@long long unsigned int@& 3 \\
     1342\lstinline@-?( (float)li)@                                      & \lstinline@float@                                     & 4 \\
     1343\lstinline@-?( (double)li)@                                     & \lstinline@double@                            & 5 \\
     1344\lstinline@-?( (long double)li)@                        & \lstinline@long double@                       & 6 \\
     1345\lstinline@-?( (_Complex float)li)@                     & \lstinline@float@                                     & (unsafe) \\
     1346\lstinline@-?( (_Complex double)li)@            & \lstinline@double@                            & (unsafe) \\
     1347\lstinline@-?( (_Complex long double)li)@       & \lstinline@long double@                       & (unsafe) \\
    13451348\end{tabular}
    13461349\end{center}
    1347 The valid interpretations of the \lstinline$eat_double$ call, with the cost of the argument conversion and the cost of the entire expression, are
     1350The valid interpretations of the \lstinline@eat_double@ call, with the cost of the argument conversion and the cost of the entire expression, are
    13481351\begin{center}
    13491352\begin{tabular}{lcc} interpretation & argument cost & expression cost \\
    13501353\hline
    1351 \lstinline$eat_double( (double)-?( (int)li) )$                                  & 7                     & (unsafe) \\
    1352 \lstinline$eat_double( (double)-?( (unsigned)li) )$                             & 6                     & (unsafe) \\
    1353 \lstinline$eat_double( (double)-?(li) )$                                                & 5                     & \(0+5=5\) \\
    1354 \lstinline$eat_double( (double)-?( (long unsigned int)li) )$    & 4                     & \(1+4=5\) \\
    1355 \lstinline$eat_double( (double)-?( (long long int)li) )$                & 3                     & \(2+3=5\) \\
    1356 \lstinline$eat_double( (double)-?( (long long unsigned int)li) )$& 2            & \(3+2=5\) \\
    1357 \lstinline$eat_double( (double)-?( (float)li) )$                                & 1                     & \(4+1=5\) \\
    1358 \lstinline$eat_double( (double)-?( (double)li) )$                               & 0                     & \(5+0=5\) \\
    1359 \lstinline$eat_double( (double)-?( (long double)li) )$                  & (unsafe)      & (unsafe) \\
    1360 \lstinline$eat_double( (double)-?( (_Complex float)li) )$               & (unsafe)      & (unsafe) \\
    1361 \lstinline$eat_double( (double)-?( (_Complex double)li) )$              & (unsafe)      & (unsafe) \\
    1362 \lstinline$eat_double( (double)-?( (_Complex long double)li) )$ & (unsafe)      & (unsafe) \\
     1354\lstinline@eat_double( (double)-?( (int)li) )@                                  & 7                     & (unsafe) \\
     1355\lstinline@eat_double( (double)-?( (unsigned)li) )@                             & 6                     & (unsafe) \\
     1356\lstinline@eat_double( (double)-?(li) )@                                                & 5                     & \(0+5=5\) \\
     1357\lstinline@eat_double( (double)-?( (long unsigned int)li) )@    & 4                     & \(1+4=5\) \\
     1358\lstinline@eat_double( (double)-?( (long long int)li) )@                & 3                     & \(2+3=5\) \\
     1359\lstinline@eat_double( (double)-?( (long long unsigned int)li) )@& 2            & \(3+2=5\) \\
     1360\lstinline@eat_double( (double)-?( (float)li) )@                                & 1                     & \(4+1=5\) \\
     1361\lstinline@eat_double( (double)-?( (double)li) )@                               & 0                     & \(5+0=5\) \\
     1362\lstinline@eat_double( (double)-?( (long double)li) )@                  & (unsafe)      & (unsafe) \\
     1363\lstinline@eat_double( (double)-?( (_Complex float)li) )@               & (unsafe)      & (unsafe) \\
     1364\lstinline@eat_double( (double)-?( (_Complex double)li) )@              & (unsafe)      & (unsafe) \\
     1365\lstinline@eat_double( (double)-?( (_Complex long double)li) )@ & (unsafe)      & (unsafe) \\
    13631366\end{tabular}
    13641367\end{center}
    1365 Each has result type \lstinline$void$, so the best must be selected.
     1368Each has result type \lstinline@void@, so the best must be selected.
    13661369The interpretations involving unsafe conversions are discarded.
    13671370The remainder have equal expression conversion costs, so the
    13681371``highest argument conversion cost'' rule is invoked, and the chosen interpretation is
    1369 \lstinline$eat_double( (double)-?(li) )$.
    1370 
    1371 
    1372 \subsubsection{The \lstinline$sizeof$ and \lstinline$_Alignof$ operators}
     1372\lstinline@eat_double( (double)-?(li) )@.
     1373
     1374
     1375\subsubsection[The sizeof and \_Alignof operators]{The \lstinline@sizeof@ and \lstinline@_Alignof@ operators}
    13731376
    13741377\constraints
    1375 The operand of \lstinline$sizeof$ or \lstinline$_Alignof$ shall not be \lstinline$type$,
    1376 \lstinline$dtype$, or \lstinline$ftype$.
    1377 
    1378 When the \lstinline$sizeof$\use{sizeof} operator is applied to an expression, the expression shall have exactly one \Index{interpretation}\index{ambiguous interpretation}, which shall be unambiguous. \semantics A \lstinline$sizeof$ or \lstinline$_Alignof$ expression has one interpretation, of type \lstinline$size_t$.
    1379 
    1380 When \lstinline$sizeof$ is applied to an identifier declared by a \nonterm{type-declaration} or a
     1378The operand of \lstinline@sizeof@ or \lstinline@_Alignof@ shall not be \lstinline@type@, \lstinline@dtype@, or \lstinline@ftype@.
     1379
     1380When the \lstinline@sizeof@\use{sizeof} operator is applied to an expression, the expression shall have exactly one \Index{interpretation}\index{ambiguous interpretation}, which shall be unambiguous. \semantics A \lstinline@sizeof@ or \lstinline@_Alignof@ expression has one interpretation, of type \lstinline@size_t@.
     1381
     1382When \lstinline@sizeof@ is applied to an identifier declared by a \nonterm{type-declaration} or a
    13811383\nonterm{type-parameter}, it yields the size in bytes of the type that implements the operand.
    13821384When the operand is an opaque type or an inferred type parameter\index{inferred parameter}, the expression is not a constant expression.
    13831385
    1384 When \lstinline$_Alignof$ is applied to an identifier declared by a \nonterm{type-declaration} or a
     1386When \lstinline@_Alignof@ is applied to an identifier declared by a \nonterm{type-declaration} or a
    13851387\nonterm{type-parameter}, it yields the alignment requirement of the type that implements the operand.
    13861388When the operand is an opaque type or an inferred type parameter\index{inferred parameter}, the expression is not a constant expression.
     
    13891391otype Pair = struct { int first, second; };
    13901392size_t p_size = sizeof(Pair);           // constant expression
    1391 extern otype Rational;@\use{Rational}@
     1393extern otype Rational;§\use{Rational}§
    13921394size_t c_size = sizeof(Rational);       // non-constant expression
    13931395forall(type T) T f(T p1, T p2) {
     
    13961398}
    13971399\end{lstlisting}
    1398 ``\lstinline$sizeof Rational$'', although not statically known, is fixed.
    1399 Within \lstinline$f()$,
    1400 ``\lstinline$sizeof(T)$'' is fixed for each call of \lstinline$f()$, but may vary from call to call.
     1400``\lstinline@sizeof Rational@'', although not statically known, is fixed.
     1401Within \lstinline@f()@,
     1402``\lstinline@sizeof(T)@'' is fixed for each call of \lstinline@f()@, but may vary from call to call.
    14011403\end{rationale}
    14021404
     
    14071409\lhs{cast-expression}
    14081410\rhs \nonterm{unary-expression}
    1409 \rhs \lstinline$($ \nonterm{type-name} \lstinline$)$ \nonterm{cast-expression}
     1411\rhs \lstinline@(@ \nonterm{type-name} \lstinline@)@ \nonterm{cast-expression}
    14101412\end{syntax}
    14111413
    14121414\constraints
    1413 The \nonterm{type-name} in a \nonterm{cast-expression} shall not be \lstinline$type$,
    1414 \lstinline$dtype$, or \lstinline$ftype$.
     1415The \nonterm{type-name} in a \nonterm{cast-expression} shall not be \lstinline@type@,
     1416\lstinline@dtype@, or \lstinline@ftype@.
    14151417
    14161418\semantics
    14171419
    1418 In a \Index{cast expression} ``\lstinline$($\nonterm{type-name}\lstinline$)e$'', if
    1419 \nonterm{type-name} is the type of an interpretation of \lstinline$e$, then that interpretation is the only interpretation of the cast expression;
    1420 otherwise, \lstinline$e$ shall have some interpretation that can be converted to \nonterm{type-name}, and the interpretation of the cast expression is the cast of the interpretation that can be converted at the lowest cost.
     1420In a \Index{cast expression} ``\lstinline@(@\nonterm{type-name}\lstinline@)e@'', if
     1421\nonterm{type-name} is the type of an interpretation of \lstinline@e@, then that interpretation is the only interpretation of the cast expression;
     1422otherwise, \lstinline@e@ shall have some interpretation that can be converted to \nonterm{type-name}, and the interpretation of the cast expression is the cast of the interpretation that can be converted at the lowest cost.
    14211423The cast expression's interpretation is ambiguous\index{ambiguous interpretation} if more than one interpretation can be converted at the lowest cost or if the selected interpretation is ambiguous.
    14221424
     
    14311433\lhs{multiplicative-expression}
    14321434\rhs \nonterm{cast-expression}
    1433 \rhs \nonterm{multiplicative-expression} \lstinline$*$ \nonterm{cast-expression}
    1434 \rhs \nonterm{multiplicative-expression} \lstinline$/$ \nonterm{cast-expression}
    1435 \rhs \nonterm{multiplicative-expression} \lstinline$%$ \nonterm{cast-expression}
     1435\rhs \nonterm{multiplicative-expression} \lstinline@*@ \nonterm{cast-expression}
     1436\rhs \nonterm{multiplicative-expression} \lstinline@/@ \nonterm{cast-expression}
     1437\rhs \nonterm{multiplicative-expression} \lstinline@%@ \nonterm{cast-expression}
    14361438\end{syntax}
    14371439
    14381440\rewriterules
    14391441\begin{lstlisting}
    1440 a * b @\rewrite@ ?*?( a, b )@\use{?*?}@
    1441 a / b @\rewrite@ ?/?( a, b )@\use{?/?}@
    1442 a % b @\rewrite@ ?%?( a, b )@\use{?%?}@
     1442a * b §\rewrite§ ?*?( a, b )§\use{?*?}§
     1443a / b §\rewrite§ ?/?( a, b )§\use{?/?}§
     1444a % b §\rewrite§ ?%?( a, b )§\use{?%?}§
    14431445\end{lstlisting}
    14441446
     
    14671469        ?*?( _Complex long double, _Complex long double ), ?/?( _Complex long double, _Complex long double );
    14681470\end{lstlisting}
    1469 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1471For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist
    14701472% Don't use predefined: keep this out of prelude.cf.
    14711473\begin{lstlisting}
     
    14851487int i;
    14861488long li;
    1487 void eat_double( double );@\use{eat_double}@
     1489void eat_double( double );§\use{eat_double}§
    14881490eat_double( li % i );
    14891491\end{lstlisting}
    1490 ``\lstinline$li % i$'' is rewritten as ``\lstinline$?%?(li, i )$''.
    1491 The valid interpretations of \lstinline$?%?(li, i )$, the cost\index{conversion cost} of converting their arguments, and the cost of converting the result to \lstinline$double$ (assuming no extended integer types are present ) are
     1492``\lstinline@li % i@'' is rewritten as ``\lstinline@?%?(li, i )@''.
     1493The valid interpretations of \lstinline@?%?(li, i )@, the cost\index{conversion cost} of converting their arguments, and the cost of converting the result to \lstinline@double@ (assuming no extended integer types are present ) are
    14921494\begin{center}
    14931495\begin{tabular}{lcc} interpretation & argument cost & result cost \\
    14941496\hline
    1495 \lstinline$ ?%?( (int)li, i )$                                                                          & (unsafe)      & 6     \\
    1496 \lstinline$ ?%?( (unsigned)li,(unsigned)i )$                                            & (unsafe)      & 5     \\
    1497 \lstinline$ ?%?( li, (long)i )$                                                                         & 1                     & 4     \\
    1498 \lstinline$ ?%?( (long unsigned)li,(long unsigned)i )$                          & 3                     & 3     \\
    1499 \lstinline$ ?%?( (long long)li,(long long)i )$                                          & 5                     & 2     \\
    1500 \lstinline$ ?%?( (long long unsigned)li, (long long unsigned)i )$       & 7                     & 1     \\
     1497\lstinline@ ?%?( (int)li, i )@                                                                          & (unsafe)      & 6     \\
     1498\lstinline@ ?%?( (unsigned)li,(unsigned)i )@                                            & (unsafe)      & 5     \\
     1499\lstinline@ ?%?( li, (long)i )@                                                                         & 1                     & 4     \\
     1500\lstinline@ ?%?( (long unsigned)li,(long unsigned)i )@                          & 3                     & 3     \\
     1501\lstinline@ ?%?( (long long)li,(long long)i )@                                          & 5                     & 2     \\
     1502\lstinline@ ?%?( (long long unsigned)li, (long long unsigned)i )@       & 7                     & 1     \\
    15011503\end{tabular}
    15021504\end{center}
    1503 The best interpretation of \lstinline$eat_double( li, i )$ is
    1504 \lstinline$eat_double( (double)?%?(li, (long)i ))$, which has no unsafe conversions and the lowest total cost.
    1505 
    1506 \begin{rationale}
    1507 {\c11} defines most arithmetic operations to apply an \Index{integer promotion} to any argument that belongs to a type that has an \Index{integer conversion rank} less than that of \lstinline$int$.If
    1508 \lstinline$s$ is a \lstinline$short int$, ``\lstinline$s *s$'' does not have type \lstinline$short int$;
    1509 it is treated as ``\lstinline$( (int)s ) * ( (int)s )$'', and has type \lstinline$int$. \CFA matches that pattern;
    1510 it does not predefine ``\lstinline$short ?*?( short, short )$''.
     1505The best interpretation of \lstinline@eat_double( li, i )@ is
     1506\lstinline@eat_double( (double)?%?(li, (long)i ))@, which has no unsafe conversions and the lowest total cost.
     1507
     1508\begin{rationale}
     1509{\c11} defines most arithmetic operations to apply an \Index{integer promotion} to any argument that belongs to a type that has an \Index{integer conversion rank} less than that of \lstinline@int@.If
     1510\lstinline@s@ is a \lstinline@short int@, ``\lstinline@s *s@'' does not have type \lstinline@short int@;
     1511it is treated as ``\lstinline@( (int)s ) * ( (int)s )@'', and has type \lstinline@int@. \CFA matches that pattern;
     1512it does not predefine ``\lstinline@short ?*?( short, short )@''.
    15111513
    15121514These ``missing'' operators limit polymorphism.
     
    15171519square( s );
    15181520\end{lstlisting}
    1519 Since \CFA does not define a multiplication operator for \lstinline$short int$,
    1520 \lstinline$square( s )$ is treated as \lstinline$square( (int)s )$, and the result has type
    1521 \lstinline$int$.
     1521Since \CFA does not define a multiplication operator for \lstinline@short int@,
     1522\lstinline@square( s )@ is treated as \lstinline@square( (int)s )@, and the result has type
     1523\lstinline@int@.
    15221524This is mildly surprising, but it follows the {\c11} operator pattern.
    15231525
     
    15291531\end{lstlisting}
    15301532This has no valid interpretations, because \CFA has no conversion from ``array of
    1531 \lstinline$short int$'' to ``array of \lstinline$int$''.
     1533\lstinline@short int@'' to ``array of \lstinline@int@''.
    15321534The alternatives in such situations include
    15331535\begin{itemize}
    15341536\item
    1535 Defining monomorphic overloadings of \lstinline$product$ for \lstinline$short$ and the other
     1537Defining monomorphic overloadings of \lstinline@product@ for \lstinline@short@ and the other
    15361538``small'' types.
    15371539\item
    1538 Defining ``\lstinline$short ?*?( short, short )$'' within the scope containing the call to
    1539 \lstinline$product$.
    1540 \item
    1541 Defining \lstinline$product$ to take as an argument a conversion function from the ``small'' type to the operator's argument type.
     1540Defining ``\lstinline@short ?*?( short, short )@'' within the scope containing the call to
     1541\lstinline@product@.
     1542\item
     1543Defining \lstinline@product@ to take as an argument a conversion function from the ``small'' type to the operator's argument type.
    15421544\end{itemize}
    15431545\end{rationale}
     
    15491551\lhs{additive-expression}
    15501552\rhs \nonterm{multiplicative-expression}
    1551 \rhs \nonterm{additive-expression} \lstinline$+$ \nonterm{multiplicative-expression}
    1552 \rhs \nonterm{additive-expression} \lstinline$-$ \nonterm{multiplicative-expression}
     1553\rhs \nonterm{additive-expression} \lstinline@+@ \nonterm{multiplicative-expression}
     1554\rhs \nonterm{additive-expression} \lstinline@-@ \nonterm{multiplicative-expression}
    15531555\end{syntax}
    15541556
    15551557\rewriterules
    15561558\begin{lstlisting}
    1557 a + b @\rewrite@ ?+?( a, b )@\use{?+?}@
    1558 a - b @\rewrite@ ?-?( a, b )@\use{?-?}@
     1559a + b §\rewrite§ ?+?( a, b )§\use{?+?}§
     1560a - b §\rewrite§ ?-?( a, b )§\use{?-?}§
    15591561\end{lstlisting}
    15601562
     
    16091611        * ?-?( _Atomic const restrict volatile T *, _Atomic const restrict volatile T * );
    16101612\end{lstlisting}
    1611 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1613For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist
    16121614% Don't use predefined: keep this out of prelude.cf.
    16131615\begin{lstlisting}
     
    16191621
    16201622\begin{rationale}
    1621 \lstinline$ptrdiff_t$ is an implementation-defined identifier defined in \lstinline$<stddef.h>$ that is synonymous with a signed integral type that is large enough to hold the difference between two pointers.
     1623\lstinline@ptrdiff_t@ is an implementation-defined identifier defined in \lstinline@<stddef.h>@ that is synonymous with a signed integral type that is large enough to hold the difference between two pointers.
    16221624It seems reasonable to use it for pointer addition as well. (This is technically a difference between \CFA and C, which only specifies that pointer addition uses an \emph{integral} argument.) Hence it is also used for subscripting, which is defined in terms of pointer addition.
    1623 The {\c11} standard uses \lstinline$size_t$ in several cases where a library function takes an argument that is used as a subscript, but \lstinline$size_t$ is unsuitable here because it is an unsigned type.
     1625The {\c11} standard uses \lstinline@size_t@ in several cases where a library function takes an argument that is used as a subscript, but \lstinline@size_t@ is unsuitable here because it is an unsigned type.
    16241626\end{rationale}
    16251627
     
    16301632\lhs{shift-expression}
    16311633\rhs \nonterm{additive-expression}
    1632 \rhs \nonterm{shift-expression} \lstinline$<<$ \nonterm{additive-expression}
    1633 \rhs \nonterm{shift-expression} \lstinline$>>$ \nonterm{additive-expression}
     1634\rhs \nonterm{shift-expression} \lstinline@<<@ \nonterm{additive-expression}
     1635\rhs \nonterm{shift-expression} \lstinline@>>@ \nonterm{additive-expression}
    16341636\end{syntax}
    16351637
    16361638\rewriterules \use{?>>?}%use{?<<?}
    16371639\begin{lstlisting}
    1638 a << b @\rewrite@ ?<<?( a, b )
    1639 a >> b @\rewrite@ ?>>?( a, b )
     1640a << b §\rewrite§ ?<<?( a, b )
     1641a >> b §\rewrite§ ?>>?( a, b )
    16401642\end{lstlisting}
    16411643
     
    16491651long long unsigned int ?<<?( long long unsigned int, int ), ?>>?( long long unsigned int, int);
    16501652\end{lstlisting}
    1651 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1653For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist
    16521654% Don't use predefined: keep this out of prelude.cf.
    16531655\begin{lstlisting}
     
    16691671\lhs{relational-expression}
    16701672\rhs \nonterm{shift-expression}
    1671 \rhs \nonterm{relational-expression} \lstinline$< $ \nonterm{shift-expression}
    1672 \rhs \nonterm{relational-expression} \lstinline$> $ \nonterm{shift-expression}
    1673 \rhs \nonterm{relational-expression} \lstinline$<=$ \nonterm{shift-expression}
    1674 \rhs \nonterm{relational-expression} \lstinline$>=$ \nonterm{shift-expression}
     1673\rhs \nonterm{relational-expression} \lstinline@< @ \nonterm{shift-expression}
     1674\rhs \nonterm{relational-expression} \lstinline@> @ \nonterm{shift-expression}
     1675\rhs \nonterm{relational-expression} \lstinline@<=@ \nonterm{shift-expression}
     1676\rhs \nonterm{relational-expression} \lstinline@>=@ \nonterm{shift-expression}
    16751677\end{syntax}
    16761678
    16771679\rewriterules\use{?>?}\use{?>=?}%use{?<?}%use{?<=?}
    16781680\begin{lstlisting}
    1679 a < b @\rewrite@ ?<?( a, b )
    1680 a > b @\rewrite@ ?>?( a, b )
    1681 a <= b @\rewrite@ ?<=?( a, b )
    1682 a >= b @\rewrite@ ?>=?( a, b )
     1681a < b §\rewrite§ ?<?( a, b )
     1682a > b §\rewrite§ ?>?( a, b )
     1683a <= b §\rewrite§ ?<=?( a, b )
     1684a >= b §\rewrite§ ?>=?( a, b )
    16831685\end{lstlisting}
    16841686
     
    17121714        ?>=?( _Atomic const restrict volatile DT *, _Atomic const restrict volatile DT * );
    17131715\end{lstlisting}
    1714 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1716For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist
    17151717% Don't use predefined: keep this out of prelude.cf.
    17161718\begin{lstlisting}
     
    17301732\lhs{equality-expression}
    17311733\rhs \nonterm{relational-expression}
    1732 \rhs \nonterm{equality-expression} \lstinline$==$ \nonterm{relational-expression}
    1733 \rhs \nonterm{equality-expression} \lstinline$!=$ \nonterm{relational-expression}
     1734\rhs \nonterm{equality-expression} \lstinline@==@ \nonterm{relational-expression}
     1735\rhs \nonterm{equality-expression} \lstinline@!=@ \nonterm{relational-expression}
    17341736\end{syntax}
    17351737
    17361738\rewriterules
    17371739\begin{lstlisting}
    1738 a == b @\rewrite@ ?==?( a, b )@\use{?==?}@
    1739 a != b @\rewrite@ ?!=?( a, b )@\use{?"!=?}@
     1740a == b §\rewrite§ ?==?( a, b )§\use{?==?}§
     1741a != b §\rewrite§ ?!=?( a, b )§\use{?"!=?}§
    17401742\end{lstlisting}
    17411743
     
    17901792        ?==?( forall( ftype FT2) FT2*, forall( ftype FT3) FT3 * ), ?!=?( forall( ftype FT2) FT2*, forall( ftype FT3) FT3 * );
    17911793\end{lstlisting}
    1792 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1794For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist
    17931795% Don't use predefined: keep this out of prelude.cf.
    17941796\begin{lstlisting}
     
    17981800
    17991801\begin{rationale}
    1800 The polymorphic equality operations come in three styles: comparisons between pointers of compatible types, between pointers to \lstinline$void$ and pointers to object types or incomplete types, and between the \Index{null pointer} constant and pointers to any type.
     1802The polymorphic equality operations come in three styles: comparisons between pointers of compatible types, between pointers to \lstinline@void@ and pointers to object types or incomplete types, and between the \Index{null pointer} constant and pointers to any type.
    18011803In the last case, a special constraint rule for null pointer constant operands has been replaced by a consequence of the \CFA type system.
    18021804\end{rationale}
     
    18191821\lhs{AND-expression}
    18201822\rhs \nonterm{equality-expression}
    1821 \rhs \nonterm{AND-expression} \lstinline$&$ \nonterm{equality-expression}
     1823\rhs \nonterm{AND-expression} \lstinline@&@ \nonterm{equality-expression}
    18221824\end{syntax}
    18231825
    18241826\rewriterules
    18251827\begin{lstlisting}
    1826 a & b @\rewrite@ ?&?( a, b )@\use{?&?}@
     1828a & b §\rewrite§ ?&?( a, b )§\use{?&?}§
    18271829\end{lstlisting}
    18281830
     
    18361838long long unsigned int ?&?( long long unsigned int, long long unsigned int );
    18371839\end{lstlisting}
    1838 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1840For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist
    18391841% Don't use predefined: keep this out of prelude.cf.
    18401842\begin{lstlisting}
     
    18511853\lhs{exclusive-OR-expression}
    18521854\rhs \nonterm{AND-expression}
    1853 \rhs \nonterm{exclusive-OR-expression} \lstinline$^$ \nonterm{AND-expression}
     1855\rhs \nonterm{exclusive-OR-expression} \lstinline@^@ \nonterm{AND-expression}
    18541856\end{syntax}
    18551857
    18561858\rewriterules
    18571859\begin{lstlisting}
    1858 a ^ b @\rewrite@ ?^?( a, b )@\use{?^?}@
     1860a ^ b §\rewrite§ ?^?( a, b )§\use{?^?}§
    18591861\end{lstlisting}
    18601862
     
    18681870long long unsigned int ?^?( long long unsigned int, long long unsigned int );
    18691871\end{lstlisting}
    1870 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1872For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist
    18711873% Don't use predefined: keep this out of prelude.cf.
    18721874\begin{lstlisting}
     
    18831885\lhs{inclusive-OR-expression}
    18841886\rhs \nonterm{exclusive-OR-expression}
    1885 \rhs \nonterm{inclusive-OR-expression} \lstinline$|$ \nonterm{exclusive-OR-expression}
     1887\rhs \nonterm{inclusive-OR-expression} \lstinline@|@ \nonterm{exclusive-OR-expression}
    18861888\end{syntax}
    18871889
    18881890\rewriterules\use{?"|?}
    18891891\begin{lstlisting}
    1890 a | b @\rewrite@ ?|?( a, b )
     1892a | b §\rewrite§ ?|?( a, b )
    18911893\end{lstlisting}
    18921894
     
    19001902long long unsigned int ?|?( long long unsigned int, long long unsigned int );
    19011903\end{lstlisting}
    1902 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1904For every extended integer type \lstinline@X@ with \Index{integer conversion rank} greater than the rank of \lstinline@int@ there exist
    19031905% Don't use predefined: keep this out of prelude.cf.
    19041906\begin{lstlisting}
     
    19151917\lhs{logical-AND-expression}
    19161918\rhs \nonterm{inclusive-OR-expression}
    1917 \rhs \nonterm{logical-AND-expression} \lstinline$&&$ \nonterm{inclusive-OR-expression}
     1919\rhs \nonterm{logical-AND-expression} \lstinline@&&@ \nonterm{inclusive-OR-expression}
    19181920\end{syntax}
    19191921
    1920 \semantics The operands of the expression ``\lstinline$a && b$'' are treated as
    1921 ``\lstinline$(int)((a)!=0)$'' and ``\lstinline$(int)((b)!=0)$'', which shall both be unambiguous.
    1922 The expression has only one interpretation, which is of type \lstinline$int$.
    1923 \begin{rationale}
    1924 When the operands of a logical expression are values of built-in types, and ``\lstinline$!=$'' has not been redefined for those types, the compiler can optimize away the function calls.
    1925 
    1926 A common C idiom omits comparisons to \lstinline$0$ in the controlling expressions of loops and
    1927 \lstinline$if$ statements.
    1928 For instance, the loop below iterates as long as \lstinline$rp$ points at a \lstinline$Rational$ value that is non-zero.
    1929 
    1930 \begin{lstlisting}
    1931 extern otype Rational;@\use{Rational}@
    1932 extern const Rational 0;@\use{0}@
     1922\semantics The operands of the expression ``\lstinline@a && b@'' are treated as
     1923``\lstinline@(int)((a)!=0)@'' and ``\lstinline@(int)((b)!=0)@'', which shall both be unambiguous.
     1924The expression has only one interpretation, which is of type \lstinline@int@.
     1925\begin{rationale}
     1926When the operands of a logical expression are values of built-in types, and ``\lstinline@!=@'' has not been redefined for those types, the compiler can optimize away the function calls.
     1927
     1928A common C idiom omits comparisons to \lstinline@0@ in the controlling expressions of loops and
     1929\lstinline@if@ statements.
     1930For instance, the loop below iterates as long as \lstinline@rp@ points at a \lstinline@Rational@ value that is non-zero.
     1931
     1932\begin{lstlisting}
     1933extern otype Rational;§\use{Rational}§
     1934extern const Rational 0;§\use{0}§
    19331935extern int ?!=?( Rational, Rational );
    19341936Rational *rp;
    19351937while ( rp && *rp ) { ... }
    19361938\end{lstlisting}
    1937 The logical expression calls the \lstinline$Rational$ inequality operator, passing it \lstinline$*rp$ and the \lstinline$Rational 0$, and getting a 1 or 0 as a result.
    1938 In contrast, {\CC} would apply a programmer-defined \lstinline$Rational$-to-\lstinline$int$ conversion to \lstinline$*rp$ in the equivalent situation.
    1939 The conversion to \lstinline$int$ would produce a general integer value, which is unfortunate, and possibly dangerous if the conversion was not written with this situation in mind.
     1939The logical expression calls the \lstinline@Rational@ inequality operator, passing it \lstinline@*rp@ and the \lstinline@Rational 0@, and getting a 1 or 0 as a result.
     1940In contrast, {\CC} would apply a programmer-defined \lstinline@Rational@-to-\lstinline@int@ conversion to \lstinline@*rp@ in the equivalent situation.
     1941The conversion to \lstinline@int@ would produce a general integer value, which is unfortunate, and possibly dangerous if the conversion was not written with this situation in mind.
    19401942\end{rationale}
    19411943
     
    19461948\lhs{logical-OR-expression}
    19471949\rhs \nonterm{logical-AND-expression}
    1948 \rhs \nonterm{logical-OR-expression} \lstinline$||$ \nonterm{logical-AND-expression}
     1950\rhs \nonterm{logical-OR-expression} \lstinline@||@ \nonterm{logical-AND-expression}
    19491951\end{syntax}
    19501952
    19511953\semantics
    19521954
    1953 The operands of the expression ``\lstinline$a || b$'' are treated as ``\lstinline$(int)((a)!=0)$'' and ``\lstinline$(int)((b))!=0)$'', which shall both be unambiguous.
    1954 The expression has only one interpretation, which is of type \lstinline$int$.
     1955The operands of the expression ``\lstinline@a || b@'' are treated as ``\lstinline@(int)((a)!=0)@'' and ``\lstinline@(int)((b))!=0)@'', which shall both be unambiguous.
     1956The expression has only one interpretation, which is of type \lstinline@int@.
    19551957
    19561958
     
    19601962\lhs{conditional-expression}
    19611963\rhs \nonterm{logical-OR-expression}
    1962 \rhs \nonterm{logical-OR-expression} \lstinline$?$ \nonterm{expression}
    1963          \lstinline$:$ \nonterm{conditional-expression}
     1964\rhs \nonterm{logical-OR-expression} \lstinline@?@ \nonterm{expression}
     1965         \lstinline@:@ \nonterm{conditional-expression}
    19641966\end{syntax}
    19651967
    19661968\semantics
    1967 In the conditional expression\use{?:} ``\lstinline$a?b:c$'', if the second and third operands both have an interpretation with \lstinline$void$ type, then the expression has an interpretation with type \lstinline$void$, equivalent to
     1969In the conditional expression\use{?:} ``\lstinline@a?b:c@'', if the second and third operands both have an interpretation with \lstinline@void@ type, then the expression has an interpretation with type \lstinline@void@, equivalent to
    19681970\begin{lstlisting}
    19691971( int)(( a)!=0) ? ( void)( b) : ( void)( c)
    19701972\end{lstlisting}
    19711973
    1972 If the second and third operands both have interpretations with non-\lstinline$void$ types, the expression is treated as if it were the call ``\lstinline$cond((a)!=0, b, c)$'', with \lstinline$cond$ declared as
     1974If the second and third operands both have interpretations with non-\lstinline@void@ types, the expression is treated as if it were the call ``\lstinline@cond((a)!=0, b, c)@'', with \lstinline@cond@ declared as
    19731975\begin{lstlisting}
    19741976forall( otype T ) T cond( int, T, T );
     
    20222024rand() ? i : l;
    20232025\end{lstlisting}
    2024 The best interpretation infers the expression's type to be \lstinline$long$ and applies the safe
    2025 \lstinline$int$-to-\lstinline$long$ conversion to \lstinline$i$.
     2026The best interpretation infers the expression's type to be \lstinline@long@ and applies the safe
     2027\lstinline@int@-to-\lstinline@long@ conversion to \lstinline@i@.
    20262028
    20272029\begin{lstlisting}
     
    20302032rand() ? cip : vip;
    20312033\end{lstlisting}
    2032 The expression has type \lstinline$const volatile int *$, with safe conversions applied to the second and third operands to add \lstinline$volatile$ and \lstinline$const$ qualifiers, respectively.
     2034The expression has type \lstinline@const volatile int *@, with safe conversions applied to the second and third operands to add \lstinline@volatile@ and \lstinline@const@ qualifiers, respectively.
    20332035
    20342036\begin{lstlisting}
    20352037rand() ? cip : 0;
    20362038\end{lstlisting}
    2037 The expression has type \lstinline$const int *$, with a specialization conversion applied to
    2038 \lstinline$0$.
     2039The expression has type \lstinline@const int *@, with a specialization conversion applied to
     2040\lstinline@0@.
    20392041
    20402042
     
    20472049         \nonterm{assignment-expression}
    20482050\lhs{assignment-operator} one of
    2049 \rhs \lstinline$=$\ \ \lstinline$*=$\ \ \lstinline$/=$\ \ \lstinline$%=$\ \ \lstinline$+=$\ \ \lstinline$-=$\ \ 
    2050          \lstinline$<<=$\ \ \lstinline$>>=$\ \ \lstinline$&=$\ \ \lstinline$^=$\ \ \lstinline$|=$
     2051\rhs \lstinline@=@\ \ \lstinline@*=@\ \ \lstinline@/=@\ \ \lstinline@%=@\ \ \lstinline@+=@\ \ \lstinline@-=@\ \ 
     2052         \lstinline@<<=@\ \ \lstinline@>>=@\ \ \lstinline@&=@\ \ \lstinline@^=@\ \ \lstinline@|=@
    20512053\end{syntax}
    20522054
     
    20572059\use{?>>=?}\use{?&=?}\use{?^=?}\use{?"|=?}%use{?<<=?}
    20582060\begin{lstlisting}
    2059 a @$\leftarrow$@ b @\rewrite@ ?@$\leftarrow$@?( &( a ), b )
     2061a §$\leftarrow$§ b §\rewrite§ ?§$\leftarrow$§?( &( a ), b )
    20602062\end{lstlisting}
    20612063
    20622064\semantics
    20632065Each interpretation of the left operand of an assignment expression is considered separately.
    2064 For each interpretation that is a bit-field or is declared with the \lstinline$register$ storage class specifier, the expression has one valid interpretation, with the type of the left operand.
     2066For each interpretation that is a bit-field or is declared with the \lstinline@register@ storage class specifier, the expression has one valid interpretation, with the type of the left operand.
    20652067The right operand is cast to that type, and the assignment expression is ambiguous if either operand is.
    20662068For the remaining interpretations, the expression is rewritten, and the interpretations of the assignment expression are the interpretations of the corresponding function call.
     
    22952297\end{lstlisting}
    22962298\begin{rationale}
    2297 The pattern of overloadings for simple assignment resembles that of pointer increment and decrement, except that the polymorphic pointer assignment functions declare a \lstinline$dtype$ parameter, instead of a \lstinline$type$ parameter, because the left operand may be a pointer to an incomplete type.
    2298 \end{rationale}
    2299 
    2300 For every complete structure or union type \lstinline$S$ there exist
     2299The pattern of overloadings for simple assignment resembles that of pointer increment and decrement, except that the polymorphic pointer assignment functions declare a \lstinline@dtype@ parameter, instead of a \lstinline@type@ parameter, because the left operand may be a pointer to an incomplete type.
     2300\end{rationale}
     2301
     2302For every complete structure or union type \lstinline@S@ there exist
    23012303% Don't use predefined: keep this out of prelude.cf.
    23022304\begin{lstlisting}
     
    23042306\end{lstlisting}
    23052307
    2306 For every extended integer type \lstinline$X$ there exist
     2308For every extended integer type \lstinline@X@ there exist
    23072309% Don't use predefined: keep this out of prelude.cf.
    23082310\begin{lstlisting}
     
    23102312\end{lstlisting}
    23112313
    2312 For every complete enumerated type \lstinline$E$ there exist
     2314For every complete enumerated type \lstinline@E@ there exist
    23132315% Don't use predefined: keep this out of prelude.cf.
    23142316\begin{lstlisting}
     
    23162318\end{lstlisting}
    23172319\begin{rationale}
    2318 The right-hand argument is \lstinline$int$ because enumeration constants have type \lstinline$int$.
     2320The right-hand argument is \lstinline@int@ because enumeration constants have type \lstinline@int@.
    23192321\end{rationale}
    23202322
     
    25772579\end{lstlisting}
    25782580
    2579 For every extended integer type \lstinline$X$ there exist
     2581For every extended integer type \lstinline@X@ there exist
    25802582% Don't use predefined: keep this out of prelude.cf.
    25812583\begin{lstlisting}
     
    25922594\end{lstlisting}
    25932595
    2594 For every complete enumerated type \lstinline$E$ there exist
     2596For every complete enumerated type \lstinline@E@ there exist
    25952597% Don't use predefined: keep this out of prelude.cf.
    25962598\begin{lstlisting}
     
    26132615\lhs{expression}
    26142616\rhs \nonterm{assignment-expression}
    2615 \rhs \nonterm{expression} \lstinline$,$ \nonterm{assignment-expression}
     2617\rhs \nonterm{expression} \lstinline@,@ \nonterm{assignment-expression}
    26162618\end{syntax}
    26172619
    26182620\semantics
    2619 In the comma expression ``\lstinline$a, b$'', the first operand is interpreted as
    2620 ``\lstinline$( void )(a)$'', which shall be unambiguous\index{ambiguous interpretation}.
     2621In the comma expression ``\lstinline@a, b@'', the first operand is interpreted as
     2622``\lstinline@( void )(a)@'', which shall be unambiguous\index{ambiguous interpretation}.
    26212623The interpretations of the expression are the interpretations of the second operand.
    26222624
     
    26532655{ ... }
    26542656\end{lstlisting}
    2655 Without the rule, \lstinline$Complex$ would be a type in the first case, and a parameter name in the second.
     2657Without the rule, \lstinline@Complex@ would be a type in the first case, and a parameter name in the second.
    26562658\end{rationale}
    26572659
     
    26792681\examples
    26802682\begin{lstlisting}
    2681 struct point {@\impl{point}@
     2683struct point {§\impl{point}§
    26822684        int x, y;
    26832685};
    2684 struct color_point {@\impl{color_point}@
     2686struct color_point {§\impl{color_point}§
    26852687        enum { RED, BLUE, GREEN } color;
    26862688        struct point;
     
    26892691cp.x = 0;
    26902692cp.color = RED;
    2691 struct literal {@\impl{literal}@
     2693struct literal {§\impl{literal}§
    26922694        enum { NUMBER, STRING } tag;
    26932695        union {
     
    27102712\begin{syntax}
    27112713\lhs{forall-specifier}
    2712 \rhs \lstinline$forall$ \lstinline$($ \nonterm{type-parameter-list} \lstinline$)$
     2714\rhs \lstinline@forall@ \lstinline@(@ \nonterm{type-parameter-list} \lstinline@)@
    27132715\end{syntax}
    27142716
     
    27222724} mkPair( T, T ); // illegal
    27232725\end{lstlisting}
    2724 If an instance of \lstinline$struct Pair$ was declared later in the current scope, what would the members' type be?
     2726If an instance of \lstinline@struct Pair@ was declared later in the current scope, what would the members' type be?
    27252727\end{rationale}
    27262728\end{comment}
     
    27292731The \nonterm{type-parameter-list}s and assertions of the \nonterm{forall-specifier}s declare type identifiers, function and object identifiers with \Index{no linkage}.
    27302732
    2731 If, in the declaration ``\lstinline$T D$'', \lstinline$T$ contains \nonterm{forall-specifier}s and
    2732 \lstinline$D$ has the form
    2733 \begin{lstlisting}
    2734 D( @\normalsize\nonterm{parameter-type-list}@ )
    2735 \end{lstlisting} then a type identifier declared by one of the \nonterm{forall-specifier}s is an \define{inferred parameter} of the function declarator if and only if it is not an inferred parameter of a function declarator in \lstinline$D$, and it is used in the type of a parameter in the following
     2733If, in the declaration ``\lstinline@T D@'', \lstinline@T@ contains \nonterm{forall-specifier}s and
     2734\lstinline@D@ has the form
     2735\begin{lstlisting}
     2736D( §\normalsize\nonterm{parameter-type-list}§ )
     2737\end{lstlisting} then a type identifier declared by one of the \nonterm{forall-specifier}s is an \define{inferred parameter} of the function declarator if and only if it is not an inferred parameter of a function declarator in \lstinline@D@, and it is used in the type of a parameter in the following
    27362738\nonterm{type-parameter-list} or it and an inferred parameter are used as arguments of a
    27372739\Index{specification} in one of the \nonterm{forall-specifier}s.
     
    27442746If this restriction were lifted, it would be possible to write
    27452747\begin{lstlisting}
    2746 forall( otype T ) T * alloc( void );@\use{alloc}@ int *p = alloc();
    2747 \end{lstlisting}
    2748 Here \lstinline$alloc()$ would receive \lstinline$int$ as an inferred argument, and return an
    2749 \lstinline$int *$.
    2750 In general, if a call to \lstinline$alloc()$ is a subexpression of an expression involving polymorphic functions and overloaded identifiers, there could be considerable distance between the call and the subexpression that causes \lstinline$T$ to be bound.
    2751 
    2752 With the current restriction, \lstinline$alloc()$ must be given an argument that determines
    2753 \lstinline$T$:
    2754 \begin{lstlisting}
    2755 forall( otype T ) T * alloc( T initial_value );@\use{alloc}@
     2748forall( otype T ) T * alloc( void );§\use{alloc}§ int *p = alloc();
     2749\end{lstlisting}
     2750Here \lstinline@alloc()@ would receive \lstinline@int@ as an inferred argument, and return an
     2751\lstinline@int *@.
     2752In general, if a call to \lstinline@alloc()@ is a subexpression of an expression involving polymorphic functions and overloaded identifiers, there could be considerable distance between the call and the subexpression that causes \lstinline@T@ to be bound.
     2753
     2754With the current restriction, \lstinline@alloc()@ must be given an argument that determines
     2755\lstinline@T@:
     2756\begin{lstlisting}
     2757forall( otype T ) T * alloc( T initial_value );§\use{alloc}§
    27562758\end{lstlisting}
    27572759\end{rationale}
     
    27782780forall( otype T ) T fT( T );
    27792781\end{lstlisting}
    2780 \lstinline$fi()$ takes an \lstinline$int$ and returns an \lstinline$int$. \lstinline$fT()$ takes a
    2781 \lstinline$T$ and returns a \lstinline$T$, for any type \lstinline$T$.
     2782\lstinline@fi()@ takes an \lstinline@int@ and returns an \lstinline@int@. \lstinline@fT()@ takes a
     2783\lstinline@T@ and returns a \lstinline@T@, for any type \lstinline@T@.
    27822784\begin{lstlisting}
    27832785int (*pfi )( int ) = fi;
    27842786forall( otype T ) T (*pfT )( T ) = fT;
    27852787\end{lstlisting}
    2786 \lstinline$pfi$ and \lstinline$pfT$ are pointers to functions. \lstinline$pfT$ is not polymorphic, but the function it points at is.
     2788\lstinline@pfi@ and \lstinline@pfT@ are pointers to functions. \lstinline@pfT@ is not polymorphic, but the function it points at is.
    27872789\begin{lstlisting}
    27882790int (*fvpfi( void ))( int ) {
     
    27932795}
    27942796\end{lstlisting}
    2795 \lstinline$fvpfi()$ and \lstinline$fvpfT()$ are functions taking no arguments and returning pointers to functions. \lstinline$fvpfT()$ is monomorphic, but the function that its return value points at is polymorphic.
     2797\lstinline@fvpfi()@ and \lstinline@fvpfT()@ are functions taking no arguments and returning pointers to functions. \lstinline@fvpfT()@ is monomorphic, but the function that its return value points at is polymorphic.
    27962798\begin{lstlisting}
    27972799forall( otype T ) int ( *fTpfi( T ) )( int );
     
    27992801forall( otype T, otype U ) U ( *fTpfU( T ) )( U );
    28002802\end{lstlisting}
    2801 \lstinline$fTpfi()$ is a polymorphic function that returns a pointer to a monomorphic function taking an integer and returning an integer.
    2802 It could return \lstinline$pfi$. \lstinline$fTpfT()$ is subtle: it is a polymorphic function returning a \emph{monomorphic} function taking and returning
    2803 \lstinline$T$, where \lstinline$T$ is an inferred parameter of \lstinline$fTpfT()$.
    2804 For instance, in the expression ``\lstinline$fTpfT(17)$'', \lstinline$T$ is inferred to be \lstinline$int$, and the returned value would have type \lstinline$int ( * )( int )$. ``\lstinline$fTpfT(17)(13)$'' and
    2805 ``\lstinline$fTpfT("yes")("no")$'' are legal, but ``\lstinline$fTpfT(17)("no")$'' is illegal.
    2806 \lstinline$fTpfU()$ is polymorphic ( in type \lstinline$T$), and returns a pointer to a function that is polymorphic ( in type \lstinline$U$). ``\lstinline$f5(17)("no")$'' is a legal expression of type
    2807 \lstinline$char *$.
     2803\lstinline@fTpfi()@ is a polymorphic function that returns a pointer to a monomorphic function taking an integer and returning an integer.
     2804It could return \lstinline@pfi@. \lstinline@fTpfT()@ is subtle: it is a polymorphic function returning a \emph{monomorphic} function taking and returning
     2805\lstinline@T@, where \lstinline@T@ is an inferred parameter of \lstinline@fTpfT()@.
     2806For instance, in the expression ``\lstinline@fTpfT(17)@'', \lstinline@T@ is inferred to be \lstinline@int@, and the returned value would have type \lstinline@int ( * )( int )@. ``\lstinline@fTpfT(17)(13)@'' and
     2807``\lstinline@fTpfT("yes")("no")@'' are legal, but ``\lstinline@fTpfT(17)("no")@'' is illegal.
     2808\lstinline@fTpfU()@ is polymorphic ( in type \lstinline@T@), and returns a pointer to a function that is polymorphic ( in type \lstinline@U@). ``\lstinline@f5(17)("no")@'' is a legal expression of type
     2809\lstinline@char *@.
    28082810\begin{lstlisting}
    28092811forall( otype T, otype U, otype V ) U * f( T *, U, V * const );
    28102812forall( otype U, otype V, otype W ) U * g( V *, U, W * const );
    28112813\end{lstlisting}
    2812 The functions \lstinline$f()$ and \lstinline$g()$ have compatible types.
     2814The functions \lstinline@f()@ and \lstinline@g()@ have compatible types.
    28132815Let \(f\) and \(g\) be their types;
    2814 then \(f_1\) = \lstinline$T$, \(f_2\) = \lstinline$U$, \(f_3\) = \lstinline$V$, \(g_1\)
    2815 = \lstinline$V$, \(g_2\) = \lstinline$U$, and \(g_3\) = \lstinline$W$.
     2816then \(f_1\) = \lstinline@T@, \(f_2\) = \lstinline@U@, \(f_3\) = \lstinline@V@, \(g_1\)
     2817= \lstinline@V@, \(g_2\) = \lstinline@U@, and \(g_3\) = \lstinline@W@.
    28162818Replacing every \(f_i\) by \(g_i\) in \(f\) gives
    28172819\begin{lstlisting}
     
    28192821\end{lstlisting} which has a return type and parameter list that is compatible with \(g\).
    28202822\begin{rationale}
    2821 The word ``\lstinline$type$'' in a forall specifier is redundant at the moment, but I want to leave room for inferred parameters of ordinary types in case parameterized types get added one day.
     2823The word ``\lstinline@type@'' in a forall specifier is redundant at the moment, but I want to leave room for inferred parameters of ordinary types in case parameterized types get added one day.
    28222824
    28232825Even without parameterized types, I might try to allow
     
    28452847\subsection{Type qualifiers}
    28462848
    2847 \CFA defines a new type qualifier \lstinline$lvalue$\impl{lvalue}\index{lvalue}.
     2849\CFA defines a new type qualifier \lstinline@lvalue@\impl{lvalue}\index{lvalue}.
    28482850\begin{syntax}
    28492851\oldlhs{type-qualifier}
    2850 \rhs \lstinline$lvalue$
     2852\rhs \lstinline@lvalue@
    28512853\end{syntax}
    28522854
    28532855\constraints
    2854 \lstinline$restrict$\index{register@{\lstinline$restrict$}} Types other than type parameters and pointer types whose referenced type is an object type shall not be restrict-qualified.
     2856\Indexc{restrict} Types other than type parameters and pointer types whose referenced type is an object type shall not be restrict-qualified.
    28552857
    28562858\semantics
    2857 An object's type may be a restrict-qualified type parameter. \lstinline$restrict$ does not establish any special semantics in that case.
     2859An object's type may be a restrict-qualified type parameter.
     2860\lstinline@restrict@ does not establish any special semantics in that case.
    28582861
    28592862\begin{rationale}
     
    28612864\end{rationale}
    28622865
    2863 \lstinline$lvalue$ may be used to qualify the return type of a function type.
    2864 Let \lstinline$T$ be an unqualified version of a type;
     2866\lstinline@lvalue@ may be used to qualify the return type of a function type.
     2867Let \lstinline@T@ be an unqualified version of a type;
    28652868then the result of calling a function with return type
    2866 \lstinline$lvalue T$ is a \Index{modifiable lvalue} of type \lstinline$T$.
    2867 \lstinline$const$\use{const} and \lstinline$volatile$\use{volatile} qualifiers may also be added to indicate that the function result is a constant or volatile lvalue.
    2868 \begin{rationale}
    2869 The \lstinline$const$ and \lstinline$volatile$ qualifiers can only be sensibly used to qualify the return type of a function if the \lstinline$lvalue$ qualifier is also used.
     2869\lstinline@lvalue T@ is a \Index{modifiable lvalue} of type \lstinline@T@.
     2870\lstinline@const@\use{const} and \lstinline@volatile@\use{volatile} qualifiers may also be added to indicate that the function result is a constant or volatile lvalue.
     2871\begin{rationale}
     2872The \lstinline@const@ and \lstinline@volatile@ qualifiers can only be sensibly used to qualify the return type of a function if the \lstinline@lvalue@ qualifier is also used.
    28702873\end{rationale}
    28712874
     
    28742877
    28752878\begin{rationale}
    2876 \lstinline$lvalue$ provides some of the functionality of {\CC}'s ``\lstinline$T&$'' ( reference to object of type \lstinline$T$) type.
     2879\lstinline@lvalue@ provides some of the functionality of {\CC}'s ``\lstinline@T&@'' ( reference to object of type \lstinline@T@) type.
    28772880Reference types have four uses in {\CC}.
    28782881\begin{itemize}
    28792882\item
    2880 They are necessary for user-defined operators that return lvalues, such as ``subscript'' and
    2881 ``dereference''.
    2882 
    2883 \item
    2884 A reference can be used to define an alias for a complicated lvalue expression, as a way of getting some of the functionality of the Pascal \lstinline$with$ statement.
     2883They are necessary for user-defined operators that return lvalues, such as ``subscript'' and ``dereference''.
     2884
     2885\item
     2886A reference can be used to define an alias for a complicated lvalue expression, as a way of getting some of the functionality of the Pascal \lstinline@with@ statement.
    28852887The following {\CC} code gives an example.
    28862888\begin{lstlisting}
     
    28952897A reference parameter can be used to allow a function to modify an argument without forcing the caller to pass the address of the argument.
    28962898This is most useful for user-defined assignment operators.
    2897 In {\CC}, plain assignment is done by a function called ``\lstinline$operator=$'', and the two expressions
     2899In {\CC}, plain assignment is done by a function called ``\lstinline@operator=@'', and the two expressions
    28982900\begin{lstlisting}
    28992901a = b;
    29002902operator=( a, b );
    29012903\end{lstlisting} are equivalent.
    2902 If \lstinline$a$ and \lstinline$b$ are of type \lstinline$T$, then the first parameter of \lstinline$operator=$ must have type ``\lstinline$T&$''.
     2904If \lstinline@a@ and \lstinline@b@ are of type \lstinline@T@, then the first parameter of \lstinline@operator=@ must have type ``\lstinline@T&@''.
    29032905It cannot have type
    2904 \lstinline$T$, because then assignment couldn't alter the variable, and it can't have type
    2905 ``\lstinline$T *$'', because the assignment would have to be written ``\lstinline$&a = b;$''.
    2906 
    2907 In the case of user-defined operators, this could just as well be handled by using pointer types and by changing the rewrite rules so that ``\lstinline$a = b;$'' is equivalent to
    2908 ``\lstinline$operator=(&( a), b )$''.
    2909 Reference parameters of ``normal'' functions are Bad Things, because they remove a useful property of C function calls: an argument can only be modified by a function if it is preceded by ``\lstinline$&$''.
     2906\lstinline@T@, because then assignment couldn't alter the variable, and it can't have type
     2907``\lstinline@T *@'', because the assignment would have to be written ``\lstinline@&a = b;@''.
     2908
     2909In the case of user-defined operators, this could just as well be handled by using pointer types and by changing the rewrite rules so that ``\lstinline@a = b;@'' is equivalent to
     2910``\lstinline@operator=(&( a), b )@''.
     2911Reference parameters of ``normal'' functions are Bad Things, because they remove a useful property of C function calls: an argument can only be modified by a function if it is preceded by ``\lstinline@&@''.
    29102912
    29112913\item
    29122914References to \Index{const-qualified} types can be used instead of value parameters.  Given the
    2913 {\CC} function call ``\lstinline$fiddle( a_thing )$'', where the type of \lstinline$a_thing$ is
    2914 \lstinline$Thing$, the type of \lstinline$fiddle$ could be either of
     2915{\CC} function call ``\lstinline@fiddle( a_thing )@'', where the type of \lstinline@a_thing@ is
     2916\lstinline@Thing@, the type of \lstinline@fiddle@ could be either of
    29152917\begin{lstlisting}
    29162918void fiddle( Thing );
    29172919void fiddle( const Thing & );
    29182920\end{lstlisting}
    2919 If the second form is used, then constructors and destructors are not invoked to create a temporary variable at the call site ( and it is bad style for the caller to make any assumptions about such things), and within \lstinline$fiddle$ the parameter is subject to the usual problems caused by aliases.
    2920 The reference form might be chosen for efficiency's sake if \lstinline$Thing$s are too large or their constructors or destructors are too expensive.
     2921If the second form is used, then constructors and destructors are not invoked to create a temporary variable at the call site ( and it is bad style for the caller to make any assumptions about such things), and within \lstinline@fiddle@ the parameter is subject to the usual problems caused by aliases.
     2922The reference form might be chosen for efficiency's sake if \lstinline@Thing@s are too large or their constructors or destructors are too expensive.
    29212923An implementation may switch between them without causing trouble for well-behaved clients.
    29222924This leaves the implementor to define ``too large'' and ``too expensive''.
     
    29262928void fiddle( const volatile Thing );
    29272929\end{lstlisting} with call-by-reference.
    2928 Since it knows all about the size of \lstinline$Thing$s and the parameter passing mechanism, it should be able to come up with a better definition of ``too large'', and may be able to make a good guess at ``too expensive''.
     2930Since it knows all about the size of \lstinline@Thing@s and the parameter passing mechanism, it should be able to come up with a better definition of ``too large'', and may be able to make a good guess at ``too expensive''.
    29292931\end{itemize}
    29302932
     
    29462948\begin{syntax}
    29472949\lhs{spec-definition}
    2948 \rhs \lstinline$spec$ \nonterm{identifier}
    2949         \lstinline$($ \nonterm{type-parameter-list} \lstinline$)$
    2950         \lstinline${$ \nonterm{spec-declaration-list}\opt \lstinline$}$
     2950\rhs \lstinline@spec@ \nonterm{identifier}
     2951        \lstinline@(@ \nonterm{type-parameter-list} \lstinline@)@
     2952        \lstinline@{@ \nonterm{spec-declaration-list}\opt \lstinline@}@
    29512953\lhs{spec-declaration-list}
    2952 \rhs \nonterm{spec-declaration} \lstinline$;$
    2953 \rhs \nonterm{spec-declaration-list} \nonterm{spec-declaration} \lstinline$;$
     2954\rhs \nonterm{spec-declaration} \lstinline@;@
     2955\rhs \nonterm{spec-declaration-list} \nonterm{spec-declaration} \lstinline@;@
    29542956\lhs{spec-declaration}
    29552957\rhs \nonterm{specifier-qualifier-list} \nonterm{declarator-list}
    29562958\lhs{declarator-list}
    29572959\rhs \nonterm{declarator}
    2958 \rhs \nonterm{declarator-list} \lstinline$,$ \nonterm{declarator}
     2960\rhs \nonterm{declarator-list} \lstinline@,@ \nonterm{declarator}
    29592961\end{syntax}
    29602962\begin{rationale}
     
    29782980\rhs \nonterm{assertion-list} \nonterm{assertion}
    29792981\lhs{assertion}
    2980 \rhs \lstinline$|$ \nonterm{identifier} \lstinline$($ \nonterm{type-name-list} \lstinline$)$
    2981 \rhs \lstinline$|$ \nonterm{spec-declaration}
     2982\rhs \lstinline@|@ \nonterm{identifier} \lstinline@(@ \nonterm{type-name-list} \lstinline@)@
     2983\rhs \lstinline@|@ \nonterm{spec-declaration}
    29822984\lhs{type-name-list}
    29832985\rhs \nonterm{type-name}
    2984 \rhs \nonterm{type-name-list} \lstinline$,$ \nonterm{type-name}
     2986\rhs \nonterm{type-name-list} \lstinline@,@ \nonterm{type-name}
    29852987\end{syntax}
    29862988
     
    29892991The \nonterm{type-name-list} shall contain one \nonterm{type-name} argument for each \nonterm{type-parameter} in that specification's \nonterm{spec-parameter-list}.
    29902992If the
    2991 \nonterm{type-parameter} uses type-class \lstinline$type$\use{type}, the argument shall be the type name of an \Index{object type};
    2992 if it uses \lstinline$dtype$, the argument shall be the type name of an object type or an \Index{incomplete type};
    2993 and if it uses \lstinline$ftype$, the argument shall be the type name of a \Index{function type}.
     2993\nonterm{type-parameter} uses type-class \lstinline@type@\use{type}, the argument shall be the type name of an \Index{object type};
     2994if it uses \lstinline@dtype@, the argument shall be the type name of an object type or an \Index{incomplete type};
     2995and if it uses \lstinline@ftype@, the argument shall be the type name of a \Index{function type}.
    29942996
    29952997\semantics
     
    30043006\examples
    30053007\begin{lstlisting}
    3006 forall( otype T | T ?*?( T, T ))@\use{?*?}@
    3007 T square( T val ) {@\impl{square}@
     3008forall( otype T | T ?*?( T, T ))§\use{?*?}§
     3009T square( T val ) {§\impl{square}§
    30083010        return val + val;
    30093011}
    3010 trait summable( otype T ) {@\impl{summable}@
    3011         T ?+=?( T *, T );@\use{?+=?}@
    3012         const T 0;@\use{0}@
     3012trait summable( otype T ) {§\impl{summable}§
     3013        T ?+=?( T *, T );§\use{?+=?}§
     3014        const T 0;§\use{0}§
    30133015};
    3014 trait list_of( otype List, otype Element ) {@\impl{list_of}@
     3016trait list_of( otype List, otype Element ) {§\impl{list_of}§
    30153017        Element car( List );
    30163018        List cdr( List );
     
    30213023trait sum_list( otype List, otype Element | summable( Element ) | list_of( List, Element ) ) {};
    30223024\end{lstlisting}
    3023 \lstinline$sum_list$ contains seven declarations, which describe a list whose elements can be added up.
    3024 The assertion ``\lstinline$|sum_list( i_list, int )$''\use{sum_list} produces the assertion parameters
     3025\lstinline@sum_list@ contains seven declarations, which describe a list whose elements can be added up.
     3026The assertion ``\lstinline@|sum_list( i_list, int )@''\use{sum_list} produces the assertion parameters
    30253027\begin{lstlisting}
    30263028int ?+=?( int *, int );
     
    30393041\lhs{type-parameter-list}
    30403042\rhs \nonterm{type-parameter}
    3041 \rhs \nonterm{type-parameter-list} \lstinline$,$ \nonterm{type-parameter}
     3043\rhs \nonterm{type-parameter-list} \lstinline@,@ \nonterm{type-parameter}
    30423044\lhs{type-parameter}
    30433045\rhs \nonterm{type-class} \nonterm{identifier} \nonterm{assertion-list}\opt
    30443046\lhs{type-class}
    3045 \rhs \lstinline$type$
    3046 \rhs \lstinline$dtype$
    3047 \rhs \lstinline$ftype$
     3047\rhs \lstinline@type@
     3048\rhs \lstinline@dtype@
     3049\rhs \lstinline@ftype@
    30483050\lhs{type-declaration}
    3049 \rhs \nonterm{storage-class-specifier}\opt \lstinline$type$ \nonterm{type-declarator-list} \verb|;|
     3051\rhs \nonterm{storage-class-specifier}\opt \lstinline@type@ \nonterm{type-declarator-list} \verb|;|
    30503052\lhs{type-declarator-list}
    30513053\rhs \nonterm{type-declarator}
    3052 \rhs \nonterm{type-declarator-list} \lstinline$,$ \nonterm{type-declarator}
     3054\rhs \nonterm{type-declarator-list} \lstinline@,@ \nonterm{type-declarator}
    30533055\lhs{type-declarator}
    3054 \rhs \nonterm{identifier} \nonterm{assertion-list}\opt \lstinline$=$ \nonterm{type-name}
     3056\rhs \nonterm{identifier} \nonterm{assertion-list}\opt \lstinline@=@ \nonterm{type-name}
    30553057\rhs \nonterm{identifier} \nonterm{assertion-list}\opt
    30563058\end{syntax}
     
    30633065
    30643066An identifier declared by a \nonterm{type-parameter} has \Index{no linkage}.
    3065 Identifiers declared with type-class \lstinline$type$\use{type} are \Index{object type}s;
     3067Identifiers declared with type-class \lstinline@type@\use{type} are \Index{object type}s;
    30663068those declared with type-class
    3067 \lstinline$dtype$\use{dtype} are \Index{incomplete type}s;
     3069\lstinline@dtype@\use{dtype} are \Index{incomplete type}s;
    30683070and those declared with type-class
    3069 \lstinline$ftype$\use{ftype} are \Index{function type}s.
     3071\lstinline@ftype@\use{ftype} are \Index{function type}s.
    30703072The identifier has \Index{block scope} that terminates at the end of the \nonterm{spec-declaration-list} or polymorphic function that contains the \nonterm{type-parameter}.
    30713073
     
    30753077Within the scope of the declaration, \Index{implicit conversion}s can be performed between the defined type and the implementation type, and between pointers to the defined type and pointers to the implementation type.
    30763078
    3077 A type declaration without an \Index{initializer} and without a \Index{storage-class specifier} or with storage-class specifier \lstinline$static$\use{static} defines an \Index{incomplete type}.
     3079A type declaration without an \Index{initializer} and without a \Index{storage-class specifier} or with storage-class specifier \lstinline@static@\use{static} defines an \Index{incomplete type}.
    30783080If a
    30793081\Index{translation unit} or \Index{block} contains one or more such declarations for an identifier, it must contain exactly one definition of the identifier ( but not in an enclosed block, which would define a new type known only within that block).
     
    30953097
    30963098A type declaration without an initializer and with \Index{storage-class specifier}
    3097 \lstinline$extern$\use{extern} is an \define{opaque type declaration}.
     3099\lstinline@extern@\use{extern} is an \define{opaque type declaration}.
    30983100Opaque types are
    30993101\Index{object type}s.
     
    31103112\end{rationale}
    31113113
    3112 An \Index{incomplete type} which is not a qualified version\index{qualified type} of a type is a value of \Index{type-class} \lstinline$dtype$.
    3113 An object type\index{object types} which is not a qualified version of a type is a value of type-classes \lstinline$type$ and \lstinline$dtype$.
     3114An \Index{incomplete type} which is not a qualified version\index{qualified type} of a type is a value of \Index{type-class} \lstinline@dtype@.
     3115An object type\index{object types} which is not a qualified version of a type is a value of type-classes \lstinline@type@ and \lstinline@dtype@.
    31143116A
    3115 \Index{function type} is a value of type-class \lstinline$ftype$.
     3117\Index{function type} is a value of type-class \lstinline@ftype@.
    31163118\begin{rationale}
    31173119Syntactically, a type value is a \nonterm{type-name}, which is a declaration for an object which omits the identifier being declared.
     
    31233125Type qualifiers are a weak point of C's type system.
    31243126Consider the standard library function
    3125 \lstinline$strchr()$ which, given a string and a character, returns a pointer to the first occurrence of the character in the string.
    3126 \begin{lstlisting}
    3127 char *strchr( const char *s, int c ) {@\impl{strchr}@
     3127\lstinline@strchr()@ which, given a string and a character, returns a pointer to the first occurrence of the character in the string.
     3128\begin{lstlisting}
     3129char *strchr( const char *s, int c ) {§\impl{strchr}§
    31283130        char real_c = c; // done because c was declared as int.
    31293131        for ( ; *s != real_c; s++ )
     
    31323134}
    31333135\end{lstlisting}
    3134 The parameter \lstinline$s$ must be \lstinline$const char *$, because \lstinline$strchr()$ might be used to search a constant string, but the return type must be \lstinline$char *$, because the result might be used to modify a non-constant string.
     3136The parameter \lstinline@s@ must be \lstinline@const char *@, because \lstinline@strchr()@ might be used to search a constant string, but the return type must be \lstinline@char *@, because the result might be used to modify a non-constant string.
    31353137Hence the body must perform a cast, and ( even worse)
    3136 \lstinline$strchr()$ provides a type-safe way to attempt to modify constant strings.
    3137 What is needed is some way to say that \lstinline$s$'s type might contain qualifiers, and the result type has exactly the same qualifiers.
     3138\lstinline@strchr()@ provides a type-safe way to attempt to modify constant strings.
     3139What is needed is some way to say that \lstinline@s@'s type might contain qualifiers, and the result type has exactly the same qualifiers.
    31383140Polymorphic functions do not provide a fix for this deficiency\index{deficiencies!pointers to qualified types}, because type qualifiers are not part of type values.
    3139 Instead, overloading can be used to define \lstinline$strchr()$ for each combination of qualifiers.
     3141Instead, overloading can be used to define \lstinline@strchr()@ for each combination of qualifiers.
    31403142\end{rationale}
    31413143
     
    31623164\end{lstlisting}
    31633165Without this restriction, \CFA might require ``module initialization'' code ( since
    3164 \lstinline$Rational$ has external linkage, it must be created before any other translation unit instantiates it), and would force an ordering on the initialization of the translation unit that defines \lstinline$Huge$ and the translation that declares \lstinline$Rational$.
     3166\lstinline@Rational@ has external linkage, it must be created before any other translation unit instantiates it), and would force an ordering on the initialization of the translation unit that defines \lstinline@Huge@ and the translation that declares \lstinline@Rational@.
    31653167
    31663168A benefit of the restriction is that it prevents the declaration in separate translation units of types that contain each other, which would be hard to prevent otherwise.
     
    31793181\nonterm{struct-declaration}, type declarations can not be structure members.
    31803182The form of
    3181 \nonterm{type-declaration} forbids arrays of, pointers to, and functions returning \lstinline$type$.
     3183\nonterm{type-declaration} forbids arrays of, pointers to, and functions returning \lstinline@type@.
    31823184Hence the syntax of \nonterm{type-specifier} does not have to be extended to allow type-valued expressions.
    31833185It also side-steps the problem of type-valued expressions producing different values in different declarations.
     
    31943196#include <stdlib.h>
    31953197T * new( otype T ) { return ( T * )malloc( sizeof( T) ); };
    3196 @\ldots@ int * ip = new( int );
    3197 \end{lstlisting}
    3198 This looks sensible, but \CFA's declaration-before-use rules mean that ``\lstinline$T$'' in the function body refers to the parameter, but the ``\lstinline$T$'' in the return type refers to the meaning of \lstinline$T$ in the scope that contains \lstinline$new$;
     3198§\ldots§ int * ip = new( int );
     3199\end{lstlisting}
     3200This looks sensible, but \CFA's declaration-before-use rules mean that ``\lstinline@T@'' in the function body refers to the parameter, but the ``\lstinline@T@'' in the return type refers to the meaning of \lstinline@T@ in the scope that contains \lstinline@new@;
    31993201it could be undefined, or a type name, or a function or variable name.
    32003202Nothing good can result from such a situation.
     
    32133215f2( v2 );
    32143216\end{lstlisting}
    3215 \lstinline$V1$ is passed by value, so \lstinline$f1()$'s assignment to \lstinline$a[0]$ does not modify v1.  \lstinline$V2$ is converted to a pointer, so \lstinline$f2()$ modifies \lstinline$v2[0]$.
     3217\lstinline@V1@ is passed by value, so \lstinline@f1()@'s assignment to \lstinline@a[0]@ does not modify v1.  \lstinline@V2@ is converted to a pointer, so \lstinline@f2()@ modifies \lstinline@v2[0]@.
    32163218
    32173219A translation unit containing the declarations
    32183220\begin{lstlisting}
    3219 extern type Complex;@\use{Complex}@ // opaque type declaration
    3220 extern float abs( Complex );@\use{abs}@
    3221 \end{lstlisting} can contain declarations of complex numbers, which can be passed to \lstinline$abs$.
    3222 Some other translation unit must implement \lstinline$Complex$ and \lstinline$abs$.
     3221extern type Complex;§\use{Complex}§ // opaque type declaration
     3222extern float abs( Complex );§\use{abs}§
     3223\end{lstlisting} can contain declarations of complex numbers, which can be passed to \lstinline@abs@.
     3224Some other translation unit must implement \lstinline@Complex@ and \lstinline@abs@.
    32233225That unit might contain the declarations
    32243226\begin{lstlisting}
    3225 otype Complex = struct { float re, im; };@\impl{Complex}@
    3226 Complex cplx_i = { 0.0, 1.0 };@\impl{cplx_i}@
    3227 float abs( Complex c ) {@\impl{abs( Complex )}@
     3227otype Complex = struct { float re, im; };§\impl{Complex}§
     3228Complex cplx_i = { 0.0, 1.0 };§\impl{cplx_i}§
     3229float abs( Complex c ) {§\impl{abs( Complex )}§
    32283230        return sqrt( c.re * c.re + c.im * c.im );
    32293231}
    32303232\end{lstlisting}
    3231 Note that \lstinline$c$ is implicitly converted to a \lstinline$struct$ so that its components can be retrieved.
    3232 
    3233 \begin{lstlisting}
    3234 otype Time_of_day = int;@\impl{Time_of_day}@ // seconds since midnight.
    3235 Time_of_day ?+?( Time_of_day t1, int seconds ) {@\impl{?+?}@
     3233Note that \lstinline@c@ is implicitly converted to a \lstinline@struct@ so that its components can be retrieved.
     3234
     3235\begin{lstlisting}
     3236otype Time_of_day = int;§\impl{Time_of_day}§ // seconds since midnight.
     3237Time_of_day ?+?( Time_of_day t1, int seconds ) {§\impl{?+?}§
    32363238        return (( int)t1 + seconds ) % 86400;
    32373239}
    32383240\end{lstlisting}
    3239 \lstinline$t1$ must be cast to its implementation type to prevent infinite recursion.
     3241\lstinline@t1@ must be cast to its implementation type to prevent infinite recursion.
    32403242
    32413243\begin{rationale}
    32423244Within the scope of a type definition, an instance of the type can be viewed as having that type or as having the implementation type.
    3243 In the \lstinline$Time_of_day$ example, the difference is important.
     3245In the \lstinline@Time_of_day@ example, the difference is important.
    32443246Different languages have treated the distinction between the abstraction and the implementation in different ways.
    32453247\begin{itemize}
    32463248\item
    32473249Inside a Clu cluster \cite{CLU}, the declaration of an instance states which view applies.
    3248 Two primitives called \lstinline$up$ and \lstinline$down$ can be used to convert between the views.
     3250Two primitives called \lstinline@up@ and \lstinline@down@ can be used to convert between the views.
    32493251\item
    32503252The Simula class \cite{SIMULA87} is essentially a record type.
    32513253Since the only operations on a record are member selection and assignment, which can not be overloaded, there is never any ambiguity as to whether the abstraction or the implementation view is being used.
    32523254In {\CC}
    3253 \cite{C++}, operations on class instances include assignment and ``\lstinline$&$'', which can be overloaded.
     3255\cite{C++}, operations on class instances include assignment and ``\lstinline@&@'', which can be overloaded.
    32543256A ``scope resolution'' operator can be used inside the class to specify whether the abstract or implementation version of the operation should be used.
    32553257\item
     
    32643266In this case, explicit conversions between the derived type and the old type can be used.
    32653267\end{itemize}
    3266 \CFA's rules are like Clu's, except that implicit conversions and conversion costs allow it to do away with most uses of \lstinline$up$ and \lstinline$down$.
     3268\CFA's rules are like Clu's, except that implicit conversions and conversion costs allow it to do away with most uses of \lstinline@up@ and \lstinline@down@.
    32673269\end{rationale}
    32683270
     
    32703272\subsubsection{Default functions and objects}
    32713273
    3272 A declaration\index{type declaration} of a type identifier \lstinline$T$ with type-class
    3273 \lstinline$type$ implicitly declares a \define{default assignment} function
    3274 \lstinline$T ?=?( T *, T )$\use{?=?}, with the same \Index{scope} and \Index{linkage} as the identifier \lstinline$T$.
     3274A declaration\index{type declaration} of a type identifier \lstinline@T@ with type-class
     3275\lstinline@type@ implicitly declares a \define{default assignment} function
     3276\lstinline@T ?=?( T *, T )@\use{?=?}, with the same \Index{scope} and \Index{linkage} as the identifier \lstinline@T@.
    32753277\begin{rationale}
    32763278Assignment is central to C's imperative programming style, and every existing C object type has assignment defined for it ( except for array types, which are treated as pointer types for purposes of assignment).
    32773279Without this rule, nearly every inferred type parameter would need an accompanying assignment assertion parameter.
    32783280If a type parameter should not have an assignment operation,
    3279 \lstinline$dtype$ should be used.
     3281\lstinline@dtype@ should be used.
    32803282If a type should not have assignment defined, the user can define an assignment function that causes a run-time error, or provide an external declaration but no definition and thus cause a link-time error.
    32813283\end{rationale}
    32823284
    3283 A definition\index{type definition} of a type identifier \lstinline$T$ with \Index{implementation type} \lstinline$I$ and type-class \lstinline$type$ implicitly defines a default assignment function.
    3284 A definition\index{type definition} of a type identifier \lstinline$T$ with implementation type \lstinline$I$ and an assertion list implicitly defines \define{default function}s and
     3285A definition\index{type definition} of a type identifier \lstinline@T@ with \Index{implementation type} \lstinline@I@ and type-class \lstinline@type@ implicitly defines a default assignment function.
     3286A definition\index{type definition} of a type identifier \lstinline@T@ with implementation type \lstinline@I@ and an assertion list implicitly defines \define{default function}s and
    32853287\define{default object}s as declared by the assertion declarations.
    3286 The default objects and functions have the same \Index{scope} and \Index{linkage} as the identifier \lstinline$T$.
     3288The default objects and functions have the same \Index{scope} and \Index{linkage} as the identifier \lstinline@T@.
    32873289Their values are determined as follows:
    32883290\begin{itemize}
    32893291\item
    3290 If at the definition of \lstinline$T$ there is visible a declaration of an object with the same name as the default object, and if the type of that object with all occurrence of \lstinline$I$ replaced by \lstinline$T$ is compatible with the type of the default object, then the default object is initialized with that object.
    3291 Otherwise the scope of the declaration of \lstinline$T$ must contain a definition of the default object.
     3292If at the definition of \lstinline@T@ there is visible a declaration of an object with the same name as the default object, and if the type of that object with all occurrence of \lstinline@I@ replaced by \lstinline@T@ is compatible with the type of the default object, then the default object is initialized with that object.
     3293Otherwise the scope of the declaration of \lstinline@T@ must contain a definition of the default object.
    32923294
    32933295\item
    3294 If at the definition of \lstinline$T$ there is visible a declaration of a function with the same name as the default function, and if the type of that function with all occurrence of \lstinline$I$ replaced by \lstinline$T$ is compatible with the type of the default function, then the default function calls that function after converting its arguments and returns the converted result.
    3295 
    3296 Otherwise, if \lstinline$I$ contains exactly one anonymous member\index{anonymous member} such that at the definition of \lstinline$T$ there is visible a declaration of a function with the same name as the default function, and the type of that function with all occurrences of the anonymous member's type in its parameter list replaced by \lstinline$T$ is compatible with the type of the default function, then the default function calls that function after converting its arguments and returns the result.
    3297 
    3298 Otherwise the scope of the declaration of \lstinline$T$ must contain a definition of the default function.
     3296If at the definition of \lstinline@T@ there is visible a declaration of a function with the same name as the default function, and if the type of that function with all occurrence of \lstinline@I@ replaced by \lstinline@T@ is compatible with the type of the default function, then the default function calls that function after converting its arguments and returns the converted result.
     3297
     3298Otherwise, if \lstinline@I@ contains exactly one anonymous member\index{anonymous member} such that at the definition of \lstinline@T@ there is visible a declaration of a function with the same name as the default function, and the type of that function with all occurrences of the anonymous member's type in its parameter list replaced by \lstinline@T@ is compatible with the type of the default function, then the default function calls that function after converting its arguments and returns the result.
     3299
     3300Otherwise the scope of the declaration of \lstinline@T@ must contain a definition of the default function.
    32993301\end{itemize}
    33003302\begin{rationale}
     
    33023304\end{rationale}
    33033305
    3304 A function or object with the same type and name as a default function or object that is declared within the scope of the definition of \lstinline$T$ replaces the default function or object.
     3306A function or object with the same type and name as a default function or object that is declared within the scope of the definition of \lstinline@T@ replaces the default function or object.
    33053307
    33063308\examples
     
    33123314Pair b = { 1, 1 };
    33133315\end{lstlisting}
    3314 The definition of \lstinline$Pair$ implicitly defines two objects \lstinline$a$ and \lstinline$b$.
    3315 \lstinline$Pair a$ inherits its value from the \lstinline$struct impl a$.
     3316The definition of \lstinline@Pair@ implicitly defines two objects \lstinline@a@ and \lstinline@b@.
     3317\lstinline@Pair a@ inherits its value from the \lstinline@struct impl a@.
    33163318The definition of
    3317 \lstinline$Pair b$ is compulsory because there is no \lstinline$struct impl b$ to construct a value from.
     3319\lstinline@Pair b@ is compulsory because there is no \lstinline@struct impl b@ to construct a value from.
    33183320\begin{lstlisting}
    33193321trait ss( otype T ) {
     
    33213323        void munge( T * );
    33223324}
    3323 otype Whatsit | ss( Whatsit );@\use{Whatsit}@
    3324 otype Doodad | ss( Doodad ) = struct doodad {@\use{Doodad}@
     3325otype Whatsit | ss( Whatsit );§\use{Whatsit}§
     3326otype Doodad | ss( Doodad ) = struct doodad {§\use{Doodad}§
    33253327        Whatsit; // anonymous member
    33263328        int extra;
     
    33283330Doodad clone( Doodad ) { ... }
    33293331\end{lstlisting}
    3330 The definition of \lstinline$Doodad$ implicitly defines three functions:
     3332The definition of \lstinline@Doodad@ implicitly defines three functions:
    33313333\begin{lstlisting}
    33323334Doodad ?=?( Doodad *, Doodad );
     
    33343336void munge( Doodad * );
    33353337\end{lstlisting}
    3336 The assignment function inherits \lstinline$struct doodad$'s assignment function because the types match when \lstinline$struct doodad$ is replaced by \lstinline$Doodad$ throughout.
    3337 \lstinline$munge()$ inherits \lstinline$Whatsit$'s \lstinline$munge()$ because the types match when
    3338 \lstinline$Whatsit$ is replaced by \lstinline$Doodad$ in the parameter list. \lstinline$clone()$ does \emph{not} inherit \lstinline$Whatsit$'s \lstinline$clone()$: replacement in the parameter list yields ``\lstinline$Whatsit clone( Doodad )$'', which is not compatible with
    3339 \lstinline$Doodad$'s \lstinline$clone()$'s type.
     3338The assignment function inherits \lstinline@struct doodad@'s assignment function because the types match when \lstinline@struct doodad@ is replaced by \lstinline@Doodad@ throughout.
     3339\lstinline@munge()@ inherits \lstinline@Whatsit@'s \lstinline@munge()@ because the types match when
     3340\lstinline@Whatsit@ is replaced by \lstinline@Doodad@ in the parameter list. \lstinline@clone()@ does \emph{not} inherit \lstinline@Whatsit@'s \lstinline@clone()@: replacement in the parameter list yields ``\lstinline@Whatsit clone( Doodad )@'', which is not compatible with
     3341\lstinline@Doodad@'s \lstinline@clone()@'s type.
    33403342Hence the definition of
    3341 ``\lstinline$Doodad clone( Doodad )$'' is necessary.
     3343``\lstinline@Doodad clone( Doodad )@'' is necessary.
    33423344
    33433345Default functions and objects are subject to the normal scope rules.
    33443346\begin{lstlisting}
    3345 otype T = @\ldots@;
    3346 T a_T = @\ldots@;               // Default assignment used.
     3347otype T = §\ldots§;
     3348T a_T = §\ldots§;               // Default assignment used.
    33473349T ?=?( T *, T );
    3348 T a_T = @\ldots@;               // Programmer-defined assignment called.
     3350T a_T = §\ldots§;               // Programmer-defined assignment called.
    33493351\end{lstlisting}
    33503352\begin{rationale}
     
    33793381\begin{syntax}
    33803382\oldlhs{labeled-statement}
    3381 \rhs \lstinline$case$ \nonterm{case-value-list} : \nonterm{statement}
     3383\rhs \lstinline@case@ \nonterm{case-value-list} : \nonterm{statement}
    33823384\lhs{case-value-list}
    33833385\rhs \nonterm{case-value}
    3384 \rhs \nonterm{case-value-list} \lstinline$,$ \nonterm{case-value}
     3386\rhs \nonterm{case-value-list} \lstinline@,@ \nonterm{case-value}
    33853387\lhs{case-value}
    33863388\rhs \nonterm{constant-expression}
    33873389\rhs \nonterm{subrange}
    33883390\lhs{subrange}
    3389 \rhs \nonterm{constant-expression} \lstinline$~$ \nonterm{constant-expression}
     3391\rhs \nonterm{constant-expression} \lstinline@~@ \nonterm{constant-expression}
    33903392\end{syntax}
    33913393
     
    34003402case 1~4, 9~14, 27~32:
    34013403\end{lstlisting}
    3402 The \lstinline$case$ and \lstinline$default$ clauses are restricted within the \lstinline$switch$ and \lstinline$choose$ statements, precluding Duff's device.
     3404The \lstinline@case@ and \lstinline@default@ clauses are restricted within the \lstinline@switch@ and \lstinline@choose@ statements, precluding Duff's device.
    34033405
    34043406
    34053407\subsection{Expression and null statements}
    34063408
    3407 The expression in an expression statement is treated as being cast to \lstinline$void$.
     3409The expression in an expression statement is treated as being cast to \lstinline@void@.
    34083410
    34093411
     
    34123414\begin{syntax}
    34133415\oldlhs{selection-statement}
    3414 \rhs \lstinline$choose$ \lstinline$($ \nonterm{expression} \lstinline$)$ \nonterm{statement}
     3416\rhs \lstinline@choose@ \lstinline@(@ \nonterm{expression} \lstinline@)@ \nonterm{statement}
    34153417\end{syntax}
    34163418
    3417 The controlling expression \lstinline$E$ in the \lstinline$switch$ and \lstinline$choose$ statement:
     3419The controlling expression \lstinline@E@ in the \lstinline@switch@ and \lstinline@choose@ statement:
    34183420\begin{lstlisting}
    34193421switch ( E ) ...
     
    34213423\end{lstlisting} may have more than one interpretation, but it shall have only one interpretation with an integral type.
    34223424An \Index{integer promotion} is performed on the expression if necessary.
    3423 The constant expressions in \lstinline$case$ statements with the switch are converted to the promoted type.
     3425The constant expressions in \lstinline@case@ statements with the switch are converted to the promoted type.
    34243426
    34253427
    34263428\setcounter{subsubsection}{3}
    3427 \subsubsection{The \lstinline$choose$ statement}
    3428 
    3429 The \lstinline$choose$ statement is the same as the \lstinline$switch$ statement except control transfers to the end of the \lstinline$choose$ statement at a \lstinline$case$ or \lstinline$default$ labeled statement.
    3430 The \lstinline$fallthru$ statement is used to fall through to the next \lstinline$case$ or \lstinline$default$ labeled statement.
     3429\subsubsection[The choose statement]{The \lstinline@choose@ statement}
     3430
     3431The \lstinline@choose@ statement is the same as the \lstinline@switch@ statement except control transfers to the end of the \lstinline@choose@ statement at a \lstinline@case@ or \lstinline@default@ labeled statement.
     3432The \lstinline@fallthru@ statement is used to fall through to the next \lstinline@case@ or \lstinline@default@ labeled statement.
    34313433The following have identical meaning:
    34323434\begin{flushleft}
     
    34533455\end{tabular}
    34543456\end{flushleft}
    3455 The \lstinline$choose$ statement addresses the problem of accidental fall-through associated with the \lstinline$switch$ statement.
     3457The \lstinline@choose@ statement addresses the problem of accidental fall-through associated with the \lstinline@switch@ statement.
    34563458
    34573459
    34583460\subsection{Iteration statements}
    34593461
    3460 The controlling expression \lstinline$E$ in the loops
     3462The controlling expression \lstinline@E@ in the loops
    34613463\begin{lstlisting}
    34623464if ( E ) ...
    34633465while ( E ) ...
    34643466do ... while ( E );
    3465 \end{lstlisting} is treated as ``\lstinline$( int )((E)!=0)$''.
     3467\end{lstlisting} is treated as ``\lstinline@( int )((E)!=0)@''.
    34663468
    34673469The statement
    34683470\begin{lstlisting}
    3469 for ( a; b; c ) @\ldots@
     3471for ( a; b; c ) §\ldots§
    34703472\end{lstlisting} is treated as
    34713473\begin{lstlisting}
     
    34783480\begin{syntax}
    34793481\oldlhs{jump-statement}
    3480 \rhs \lstinline$continue$ \nonterm{identifier}\opt
    3481 \rhs \lstinline$break$ \nonterm{identifier}\opt
     3482\rhs \lstinline@continue@ \nonterm{identifier}\opt
     3483\rhs \lstinline@break@ \nonterm{identifier}\opt
    34823484\rhs \ldots
    3483 \rhs \lstinline$throw$ \nonterm{assignment-expression}\opt
    3484 \rhs \lstinline$throwResume$ \nonterm{assignment-expression}\opt \nonterm{at-expression}\opt
    3485 \lhs{at-expression} \lstinline$_At$ \nonterm{assignment-expression}
     3485\rhs \lstinline@throw@ \nonterm{assignment-expression}\opt
     3486\rhs \lstinline@throwResume@ \nonterm{assignment-expression}\opt \nonterm{at-expression}\opt
     3487\lhs{at-expression} \lstinline@_At@ \nonterm{assignment-expression}
    34863488\end{syntax}
    34873489
    3488 Labeled \lstinline$continue$ and \lstinline$break$ allow useful but restricted control-flow that reduces the need for the \lstinline$goto$ statement for exiting multiple nested control-structures.
     3490Labeled \lstinline@continue@ and \lstinline@break@ allow useful but restricted control-flow that reduces the need for the \lstinline@goto@ statement for exiting multiple nested control-structures.
    34893491\begin{lstlisting}
    34903492L1: {                                                   // compound
     
    35133515
    35143516\setcounter{subsubsection}{1}
    3515 \subsubsection{The \lstinline$continue$ statement}
    3516 
    3517 The identifier in a \lstinline$continue$ statement shall name a label located on an enclosing iteration statement.
    3518 
    3519 
    3520 \subsubsection{The \lstinline$break$ statement}
    3521 
    3522 The identifier in a \lstinline$break$ statement shall name a label located on an enclosing compound, selection or iteration statement.
    3523 
    3524 
    3525 \subsubsection{The \lstinline$return$ statement}
    3526 
    3527 An expression in a \lstinline$return$ statement is treated as being cast to the result type of the function.
    3528 
    3529 
    3530 \subsubsection{The \lstinline$throw$ statement}
     3517\subsubsection[The continue statement]{The \lstinline@continue@ statement}
     3518
     3519The identifier in a \lstinline@continue@ statement shall name a label located on an enclosing iteration statement.
     3520
     3521
     3522\subsubsection[The break statement]{The \lstinline@break@ statement}
     3523
     3524The identifier in a \lstinline@break@ statement shall name a label located on an enclosing compound, selection or iteration statement.
     3525
     3526
     3527\subsubsection[The return statement]{The \lstinline@return@ statement}
     3528
     3529An expression in a \lstinline@return@ statement is treated as being cast to the result type of the function.
     3530
     3531
     3532\subsubsection[The throw statement]{The \lstinline@throw@ statement}
    35313533
    35323534When an exception is raised, \Index{propagation} directs control from a raise in the source execution to a handler in the faulting execution.
    35333535
    35343536
    3535 \subsubsection{The \lstinline$throwResume$ statement}
     3537\subsubsection[The throwResume statement]{The \lstinline@throwResume@ statement}
    35363538
    35373539
     
    35403542\begin{syntax}
    35413543\lhs{exception-statement}
    3542 \rhs \lstinline$try$ \nonterm{compound-statement} \nonterm{handler-list}
    3543 \rhs \lstinline$try$ \nonterm{compound-statement} \nonterm{finally-clause}
    3544 \rhs \lstinline$try$ \nonterm{compound-statement} \nonterm{handler-list} \nonterm{finally-clause}
     3544\rhs \lstinline@try@ \nonterm{compound-statement} \nonterm{handler-list}
     3545\rhs \lstinline@try@ \nonterm{compound-statement} \nonterm{finally-clause}
     3546\rhs \lstinline@try@ \nonterm{compound-statement} \nonterm{handler-list} \nonterm{finally-clause}
    35453547\lhs{handler-list}
    35463548\rhs \nonterm{handler-clause}
    3547 \rhs \lstinline$catch$ \lstinline$($ \ldots \lstinline$)$ \nonterm{compound-statement}
    3548 \rhs \nonterm{handler-clause} \lstinline$catch$ \lstinline$($ \ldots \lstinline$)$ \nonterm{compound-statement}
    3549 \rhs \lstinline$catchResume$ \lstinline$($ \ldots \lstinline$)$ \nonterm{compound-statement}
    3550 \rhs \nonterm{handler-clause} \lstinline$catchResume$ \lstinline$($ \ldots \lstinline$)$ \nonterm{compound-statement}
     3549\rhs \lstinline@catch@ \lstinline@(@ \ldots \lstinline@)@ \nonterm{compound-statement}
     3550\rhs \nonterm{handler-clause} \lstinline@catch@ \lstinline@(@ \ldots \lstinline@)@ \nonterm{compound-statement}
     3551\rhs \lstinline@catchResume@ \lstinline@(@ \ldots \lstinline@)@ \nonterm{compound-statement}
     3552\rhs \nonterm{handler-clause} \lstinline@catchResume@ \lstinline@(@ \ldots \lstinline@)@ \nonterm{compound-statement}
    35513553\lhs{handler-clause}
    3552 \rhs \lstinline$catch$ \lstinline$($ \nonterm{exception-declaration} \lstinline$)$ \nonterm{compound-statement}
    3553 \rhs \nonterm{handler-clause} \lstinline$catch$ \lstinline$($ \nonterm{exception-declaration} \lstinline$)$ \nonterm{compound-statement}
    3554 \rhs \lstinline$catchResume$ \lstinline$($ \nonterm{exception-declaration} \lstinline$)$ \nonterm{compound-statement}
    3555 \rhs \nonterm{handler-clause} \lstinline$catchResume$ \lstinline$($ \nonterm{exception-declaration} \lstinline$)$ \nonterm{compound-statement}
     3554\rhs \lstinline@catch@ \lstinline@(@ \nonterm{exception-declaration} \lstinline@)@ \nonterm{compound-statement}
     3555\rhs \nonterm{handler-clause} \lstinline@catch@ \lstinline@(@ \nonterm{exception-declaration} \lstinline@)@ \nonterm{compound-statement}
     3556\rhs \lstinline@catchResume@ \lstinline@(@ \nonterm{exception-declaration} \lstinline@)@ \nonterm{compound-statement}
     3557\rhs \nonterm{handler-clause} \lstinline@catchResume@ \lstinline@(@ \nonterm{exception-declaration} \lstinline@)@ \nonterm{compound-statement}
    35563558\lhs{finally-clause}
    3557 \rhs \lstinline$finally$ \nonterm{compound-statement}
     3559\rhs \lstinline@finally@ \nonterm{compound-statement}
    35583560\lhs{exception-declaration}
    35593561\rhs \nonterm{type-specifier}
     
    35633565\rhs \nonterm{new-abstract-declarator-tuple}
    35643566\lhs{asynchronous-statement}
    3565 \rhs \lstinline$enable$ \nonterm{identifier-list} \nonterm{compound-statement}
    3566 \rhs \lstinline$disable$ \nonterm{identifier-list} \nonterm{compound-statement}
     3567\rhs \lstinline@enable@ \nonterm{identifier-list} \nonterm{compound-statement}
     3568\rhs \lstinline@disable@ \nonterm{identifier-list} \nonterm{compound-statement}
    35673569\end{syntax}
    35683570
     
    35703572
    35713573
    3572 \subsubsection{The \lstinline$try$ statement}
    3573 
    3574 The \lstinline$try$ statement is a block with associated handlers, called a \Index{guarded block};
     3574\subsubsection[The try statement]{The \lstinline@try@ statement}
     3575
     3576The \lstinline@try@ statement is a block with associated handlers, called a \Index{guarded block};
    35753577all other blocks are \Index{unguarded block}s.
    3576 A \lstinline$goto$, \lstinline$break$, \lstinline$return$, or \lstinline$continue$ statement can be used to transfer control out of a try block or handler, but not into one.
    3577 
    3578 
    3579 \subsubsection{The \lstinline$enable$/\lstinline$disable$ statements}
    3580 
    3581 The \lstinline$enable$/\lstinline$disable$ statements toggle delivery of \Index{asynchronous exception}s.
     3578A \lstinline@goto@, \lstinline@break@, \lstinline@return@, or \lstinline@continue@ statement can be used to transfer control out of a try block or handler, but not into one.
     3579
     3580
     3581\subsubsection[The enable/disable statements]{The \lstinline@enable@/\lstinline@disable@ statements}
     3582
     3583The \lstinline@enable@/\lstinline@disable@ statements toggle delivery of \Index{asynchronous exception}s.
    35823584
    35833585
     
    35893591\subsection{Predefined macro names}
    35903592
    3591 The implementation shall define the macro names \lstinline$__LINE__$, \lstinline$__FILE__$,
    3592 \lstinline$__DATE__$, and \lstinline$__TIME__$, as in the {\c11} standard.
    3593 It shall not define the macro name \lstinline$__STDC__$.
    3594 
    3595 In addition, the implementation shall define the macro name \lstinline$__CFORALL__$ to be the decimal constant 1.
     3593The implementation shall define the macro names \lstinline@__LINE__@, \lstinline@__FILE__@,
     3594\lstinline@__DATE__@, and \lstinline@__TIME__@, as in the {\c11} standard.
     3595It shall not define the macro name \lstinline@__STDC__@.
     3596
     3597In addition, the implementation shall define the macro name \lstinline@__CFORALL__@ to be the decimal constant 1.
    35963598
    35973599
     
    36103612The pointer, integral, and floating-point types are all \define{scalar types}.
    36113613All of these types can be logically negated and compared.
    3612 The assertion ``\lstinline$scalar( Complex )$'' should be read as ``type \lstinline$Complex$ is scalar''.
    3613 \begin{lstlisting}
    3614 trait scalar( otype T ) {@\impl{scalar}@
     3614The assertion ``\lstinline@scalar( Complex )@'' should be read as ``type \lstinline@Complex@ is scalar''.
     3615\begin{lstlisting}
     3616trait scalar( otype T ) {§\impl{scalar}§
    36153617        int !?( T );
    36163618        int ?<?( T, T ), ?<=?( T, T ), ?==?( T, T ), ?>=?( T, T ), ?>?( T, T ), ?!=?( T, T );
     
    36223624This is equivalent to inheritance of specifications.
    36233625\begin{lstlisting}
    3624 trait arithmetic( otype T | scalar( T ) ) {@\impl{arithmetic}@@\use{scalar}@
     3626trait arithmetic( otype T | scalar( T ) ) {§\impl{arithmetic}§§\use{scalar}§
    36253627        T +?( T ), -?( T );
    36263628        T ?*?( T, T ), ?/?( T, T ), ?+?( T, T ), ?-?( T, T );
     
    36283630\end{lstlisting}
    36293631
    3630 The various flavors of \lstinline$char$ and \lstinline$int$ and the enumerated types make up the
     3632The various flavors of \lstinline@char@ and \lstinline@int@ and the enumerated types make up the
    36313633\define{integral types}.
    36323634\begin{lstlisting}
    3633 trait integral( otype T | arithmetic( T ) ) {@\impl{integral}@@\use{arithmetic}@
     3635trait integral( otype T | arithmetic( T ) ) {§\impl{integral}§§\use{arithmetic}§
    36343636        T ~?( T );
    36353637        T ?&?( T, T ), ?|?( T, T ), ?^?( T, T );
     
    36453647The only operation that can be applied to all modifiable lvalues is simple assignment.
    36463648\begin{lstlisting}
    3647 trait m_lvalue( otype T ) {@\impl{m_lvalue}@
     3649trait m_lvalue( otype T ) {§\impl{m_lvalue}§
    36483650        T ?=?( T *, T );
    36493651};
     
    36553657Scalars can also be incremented and decremented.
    36563658\begin{lstlisting}
    3657 trait m_l_scalar( otype T | scalar( T ) | m_lvalue( T ) ) {@\impl{m_l_scalar}@
    3658         T ?++( T * ), ?--( T * );@\use{scalar}@@\use{m_lvalue}@
     3659trait m_l_scalar( otype T | scalar( T ) | m_lvalue( T ) ) {§\impl{m_l_scalar}§
     3660        T ?++( T * ), ?--( T * );§\use{scalar}§§\use{m_lvalue}§
    36593661        T ++?( T * ), --?( T * );
    36603662};
     
    36623664
    36633665Modifiable arithmetic lvalues are both modifiable scalar lvalues and arithmetic.
    3664 Note that this results in the ``inheritance'' of \lstinline$scalar$ along both paths.
    3665 \begin{lstlisting}
    3666 trait m_l_arithmetic( otype T | m_l_scalar( T ) | arithmetic( T ) ) {@\impl{m_l_arithmetic}@
    3667         T ?/=?( T *, T ), ?*=?( T *, T );@\use{m_l_scalar}@@\use{arithmetic}@
     3666Note that this results in the ``inheritance'' of \lstinline@scalar@ along both paths.
     3667\begin{lstlisting}
     3668trait m_l_arithmetic( otype T | m_l_scalar( T ) | arithmetic( T ) ) {§\impl{m_l_arithmetic}§
     3669        T ?/=?( T *, T ), ?*=?( T *, T );§\use{m_l_scalar}§§\use{arithmetic}§
    36683670        T ?+=?( T *, T ), ?-=?( T *, T );
    36693671};
    3670 trait m_l_integral( otype T | m_l_arithmetic( T ) | integral( T ) ) {@\impl{m_l_integral}@
    3671         T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T );@\use{m_l_arithmetic}@
    3672         T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T );@\use{integral}@
     3672trait m_l_integral( otype T | m_l_arithmetic( T ) | integral( T ) ) {§\impl{m_l_integral}§
     3673        T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T );§\use{m_l_arithmetic}§
     3674        T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T );§\use{integral}§
    36733675};
    36743676\end{lstlisting}
     
    36783680
    36793681Array types can barely be said to exist in {\c11}, since in most cases an array name is treated as a constant pointer to the first element of the array, and the subscript expression
    3680 ``\lstinline$a[i]$'' is equivalent to the dereferencing expression ``\lstinline$(*( a+( i )))$''.
    3681 Technically, pointer arithmetic and pointer comparisons other than ``\lstinline$==$'' and
    3682 ``\lstinline$!=$'' are only defined for pointers to array elements, but the type system does not enforce those restrictions.
     3682``\lstinline@a[i]@'' is equivalent to the dereferencing expression ``\lstinline@(*( a+( i )))@''.
     3683Technically, pointer arithmetic and pointer comparisons other than ``\lstinline@==@'' and
     3684``\lstinline@!=@'' are only defined for pointers to array elements, but the type system does not enforce those restrictions.
    36833685Consequently, there is no need for a separate ``array type'' specification.
    36843686
    36853687Pointer types are scalar types.
    3686 Like other scalar types, they have ``\lstinline$+$'' and
    3687 ``\lstinline$-$'' operators, but the types do not match the types of the operations in
    3688 \lstinline$arithmetic$, so these operators cannot be consolidated in \lstinline$scalar$.
    3689 \begin{lstlisting}
    3690 trait pointer( type P | scalar( P ) ) {@\impl{pointer}@@\use{scalar}@
     3688Like other scalar types, they have ``\lstinline@+@'' and
     3689``\lstinline@-@'' operators, but the types do not match the types of the operations in
     3690\lstinline@arithmetic@, so these operators cannot be consolidated in \lstinline@scalar@.
     3691\begin{lstlisting}
     3692trait pointer( type P | scalar( P ) ) {§\impl{pointer}§§\use{scalar}§
    36913693        P ?+?( P, long int ), ?+?( long int, P ), ?-?( P, long int );
    36923694        ptrdiff_t ?-?( P, P );
    36933695};
    3694 trait m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {@\impl{m_l_pointer}@
     3696trait m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {§\impl{m_l_pointer}§
    36953697        P ?+=?( P *, long int ), ?-=?( P *, long int );
    36963698        P ?=?( P *, void * );
     
    37013703Specifications that define the dereference operator ( or subscript operator ) require two parameters, one for the pointer type and one for the pointed-at ( or element ) type.
    37023704Different specifications are needed for each set of \Index{type qualifier}s, because qualifiers are not included in types.
    3703 The assertion ``\lstinline$|ptr_to( Safe_pointer, int )$'' should be read as
    3704 ``\lstinline$Safe_pointer$ acts like a pointer to \lstinline$int$''.
    3705 \begin{lstlisting}
    3706 trait ptr_to( otype P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@
     3705The assertion ``\lstinline@|ptr_to( Safe_pointer, int )@'' should be read as
     3706``\lstinline@Safe_pointer@ acts like a pointer to \lstinline@int@''.
     3707\begin{lstlisting}
     3708trait ptr_to( otype P | pointer( P ), otype T ) {§\impl{ptr_to}§§\use{pointer}§
    37073709        lvalue T *?( P );
    37083710        lvalue T ?[?]( P, long int );
    37093711};
    3710 trait ptr_to_const( otype P | pointer( P ), otype T ) {@\impl{ptr_to_const}@
     3712trait ptr_to_const( otype P | pointer( P ), otype T ) {§\impl{ptr_to_const}§
    37113713        const lvalue T *?( P );
    3712         const lvalue T ?[?]( P, long int );@\use{pointer}@
     3714        const lvalue T ?[?]( P, long int );§\use{pointer}§
    37133715};
    3714 trait ptr_to_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@
     3716trait ptr_to_volatile( otype P | pointer( P ), otype T ) }§\impl{ptr_to_volatile}§
    37153717        volatile lvalue T *?( P );
    3716         volatile lvalue T ?[?]( P, long int );@\use{pointer}@
     3718        volatile lvalue T ?[?]( P, long int );§\use{pointer}§
    37173719};
    3718 trait ptr_to_const_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@
    3719         const volatile lvalue T *?( P );@\use{pointer}@
     3720trait ptr_to_const_volatile( otype P | pointer( P ), otype T ) }§\impl{ptr_to_const_volatile}§
     3721        const volatile lvalue T *?( P );§\use{pointer}§
    37203722        const volatile lvalue T ?[?]( P, long int );
    37213723};
    37223724\end{lstlisting}
    37233725
    3724 Assignment to pointers is more complicated than is the case with other types, because the target's type can have extra type qualifiers in the pointed-at type: a ``\lstinline$T *$'' can be assigned to a ``\lstinline$const T *$'', a ``\lstinline$volatile T *$'', and a ``\lstinline$const volatile T *$''.
     3726Assignment to pointers is more complicated than is the case with other types, because the target's type can have extra type qualifiers in the pointed-at type: a ``\lstinline@T *@'' can be assigned to a ``\lstinline@const T *@'', a ``\lstinline@volatile T *@'', and a ``\lstinline@const volatile T *@''.
    37253727Again, the pointed-at type is passed in, so that assertions can connect these specifications to the
    3726 ``\lstinline$ptr_to$'' specifications.
    3727 \begin{lstlisting}
    3728 trait m_l_ptr_to( otype P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to}@ otype T | ptr_to( P, T )@\use{ptr_to}@ {
     3728``\lstinline@ptr_to@'' specifications.
     3729\begin{lstlisting}
     3730trait m_l_ptr_to( otype P | m_l_pointer( P ),§\use{m_l_pointer}§§\impl{m_l_ptr_to}§ otype T | ptr_to( P, T )§\use{ptr_to}§ {
    37293731        P ?=?( P *, T * );
    37303732        T * ?=?( T **, P );
    37313733};
    3732 trait m_l_ptr_to_const( otype P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_const}@ otype T | ptr_to_const( P, T )@\use{ptr_to_const}@) {
     3734trait m_l_ptr_to_const( otype P | m_l_pointer( P ),§\use{m_l_pointer}§§\impl{m_l_ptr_to_const}§ otype T | ptr_to_const( P, T )§\use{ptr_to_const}§) {
    37333735        P ?=?( P *, const T * );
    37343736        const T * ?=?( const T **, P );
    37353737};
    3736 trait m_l_ptr_to_volatile( otype P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to_volatile}@ otype T | ptr_to_volatile( P, T )) {@\use{ptr_to_volatile}@
     3738trait m_l_ptr_to_volatile( otype P | m_l_pointer( P ),§\use{m_l_pointer}§§\impl{m_l_ptr_to_volatile}§ otype T | ptr_to_volatile( P, T )) {§\use{ptr_to_volatile}§
    37373739        P ?=?( P *, volatile T * );
    37383740        volatile T * ?=?( volatile T **, P );
    37393741};
    3740 trait m_l_ptr_to_const_volatile( otype P | ptr_to_const_volatile( P ),@\use{ptr_to_const_volatile}@@\impl{m_l_ptr_to_const_volatile}@
    3741                 otype T | m_l_ptr_to_volatile( P, T ) | m_l_ptr_to_const( P )) {@\use{m_l_ptr_to_const}@@\use{m_l_ptr_to_volatile}@
     3742trait m_l_ptr_to_const_volatile( otype P | ptr_to_const_volatile( P ),§\use{ptr_to_const_volatile}§§\impl{m_l_ptr_to_const_volatile}§
     3743                otype T | m_l_ptr_to_volatile( P, T ) | m_l_ptr_to_const( P )) {§\use{m_l_ptr_to_const}§§\use{m_l_ptr_to_volatile}§
    37423744        P ?=?( P *, const volatile T * );
    37433745        const volatile T * ?=?( const volatile T **, P );
     
    37483750An alternative specification can make use of the fact that qualification of the pointed-at type is part of a pointer type to capture that regularity.
    37493751\begin{lstlisting}
    3750 trait m_l_ptr_like( type MyP | m_l_pointer( MyP ),@\use{m_l_pointer}@@\impl{m_l_ptr_like}@ type CP | m_l_pointer( CP ) ) {
     3752trait m_l_ptr_like( type MyP | m_l_pointer( MyP ),§\use{m_l_pointer}§§\impl{m_l_ptr_like}§ type CP | m_l_pointer( CP ) ) {
    37513753        MyP ?=?( MyP *, CP );
    37523754        CP ?=?( CP *, MyP );
    37533755};
    37543756\end{lstlisting}
    3755 The assertion ``\lstinline$| m_l_ptr_like( Safe_ptr, const int * )$'' should be read as
    3756 ``\lstinline$Safe_ptr$ is a pointer type like \lstinline$const int *$''.
     3757The assertion ``\lstinline@| m_l_ptr_like( Safe_ptr, const int * )@'' should be read as
     3758``\lstinline@Safe_ptr@ is a pointer type like \lstinline@const int *@''.
    37573759This specification has two defects, compared to the original four: there is no automatic assertion that dereferencing a
    3758 \lstinline$MyP$ produces an lvalue of the type that \lstinline$CP$ points at, and the
    3759 ``\lstinline$|m_l_pointer( CP )$'' assertion provides only a weak assurance that the argument passed to \lstinline$CP$ really is a pointer type.
     3760\lstinline@MyP@ produces an lvalue of the type that \lstinline@CP@ points at, and the
     3761``\lstinline@|m_l_pointer( CP )@'' assertion provides only a weak assurance that the argument passed to \lstinline@CP@ really is a pointer type.
    37603762
    37613763
     
    37633765
    37643766Different operators often have related meanings;
    3765 for instance, in C, ``\lstinline$+$'',
    3766 ``\lstinline$+=$'', and the two versions of ``\lstinline$++$'' perform variations of addition.
     3767for instance, in C, ``\lstinline@+@'',
     3768``\lstinline@+=@'', and the two versions of ``\lstinline@++@'' perform variations of addition.
    37673769Languages like {\CC} and Ada allow programmers to define operators for new types, but do not require that these relationships be preserved, or even that all of the operators be implemented.
    37683770Completeness and consistency is left to the good taste and discretion of the programmer.
     
    37773779The different comparison operators have obvious relationships, but there is no obvious subset of the operations to use in the implementation of the others.
    37783780However, it is usually convenient to implement a single comparison function that returns a negative integer, 0, or a positive integer if its first argument is respectively less than, equal to, or greater than its second argument;
    3779 the library function \lstinline$strcmp$ is an example.
    3780 
    3781 C and \CFA have an extra, non-obvious comparison operator: ``\lstinline$!$'', logical negation, returns 1 if its operand compares equal to 0, and 0 otherwise.
     3781the library function \lstinline@strcmp@ is an example.
     3782
     3783C and \CFA have an extra, non-obvious comparison operator: ``\lstinline@!@'', logical negation, returns 1 if its operand compares equal to 0, and 0 otherwise.
    37823784\begin{lstlisting}
    37833785trait comparable( otype T ) {
     
    38283830
    38293831Note that, although an arithmetic type would certainly provide comparison functions, and an integral type would provide arithmetic operations, there does not have to be any relationship among
    3830 \lstinline$int_base$, \lstinline$arith_base$ and \lstinline$comparable$.
     3832\lstinline@int_base@, \lstinline@arith_base@ and \lstinline@comparable@.
    38313833Note also that these declarations provide guidance and assistance, but they do not define an absolutely minimal set of requirements.
    3832 A truly minimal implementation of an arithmetic type might only provide
    3833 \lstinline$0$, \lstinline$1$, and \lstinline$?-=?$, which would be used by polymorphic
    3834 \lstinline$?+=?$, \lstinline$?*=?$, and \lstinline$?/=?$ functions.
    3835 
    3836 Note also that \lstinline$short$ is an integer type in C11 terms, but has no operations!
     3834A truly minimal implementation of an arithmetic type might only provide \lstinline@0@, \lstinline@1@, and \lstinline@?-=?@, which would be used by polymorphic \lstinline@?+=?@, \lstinline@?*=?@, and \lstinline@?/=?@ functions.
     3835
     3836Note also that \lstinline@short@ is an integer type in C11 terms, but has no operations!
    38373837
    38383838
     
    38413841
    38423842Restrict allowed to qualify anything, or type/dtype parameters, but only affects pointers.
    3843 This gets into \lstinline$noalias$ territory.
    3844 Qualifying anything (``\lstinline$short restrict rs$'') means pointer parameters of \lstinline$?++$, etc, would need restrict qualifiers.
     3843This gets into \lstinline@noalias@ territory.
     3844Qualifying anything (``\lstinline@short restrict rs@'') means pointer parameters of \lstinline@?++@, etc, would need restrict qualifiers.
    38453845
    38463846Enumerated types.
     
    38523852Color, enum Color ) really make sense? ?++ does, but it adds (int)1.
    38533853
    3854 Operators on {,signed,unsigned} char and other small types. ?<? harmless;
     3854Operators on {,signed,unsigned} char and other small types. \lstinline@?<?@ harmless;
    38553855?*? questionable for chars.
    38563856Generic selections make these choices visible.
     
    38583858``promotion'' function?
    38593859
    3860 \lstinline$register$ assignment might be handled as assignment to a temporary with copying back and forth, but copying must not be done by assignment.
    3861 
    3862 Don't use ptrdiff\_t by name in the predefineds.
     3860\lstinline@register@ assignment might be handled as assignment to a temporary with copying back and forth, but copying must not be done by assignment.
     3861
     3862Don't use \lstinline@ptrdiff_t@ by name in the predefineds.
    38633863
    38643864Polymorphic objects.
  • doc/user/user.tex

    r9243a501 r7cc6bd6  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Thu Apr 21 08:15:37 2016
    14 %% Update Count     : 131
     13%% Last Modified On : Sat Apr 30 13:54:32 2016
     14%% Update Count     : 221
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
    1717% requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended
     18
     19% red highlighting ®...® (registered trademark sumbol)
     20% blue highlighting ©...© (copyright symbol)
     21% latex escape §...§ (section symbol)
     22% keyword escape ¶...¶ (pilcrow symbol)
     23% math escape $...$ (dollar symbol)
    1824
    1925\documentclass[openright,twoside]{article}
     
    226232
    227233
    228 \section{Compiling \CFA Program}
     234\section[Compiling CFA Program]{Compiling \CFA Program}
    229235
    230236The command \lstinline@cfa@ is used to compile \CFA program(s).
    231237This command works like the GNU \lstinline@gcc@\index{gcc} command, e.g.:
    232238\begin{lstlisting}
    233 cfa [ gcc-options ] C/@{\CFA}@-files [ assembler/loader-files ]
    234 \end{lstlisting}
    235 \index{cfa@\lstinline$cfa$}\index{compilation!cfa@\lstinline$cfa$}
     239cfa [ gcc-options ] C/§\CFA§-files [ assembler/loader-files ]
     240\end{lstlisting}
     241\indexc{cfa}\index{compilation!cfa@\lstinline$cfa$}
    236242By default, \CFA programs having the following \lstinline@gcc@ flags turned on:
    237243\begin{description}
    238 \item
    239 \hspace*{-4pt}\lstinline@-std=gnu99@
    240 \index{-std=gnu99@{\lstinline$-std=gnu99$}}\index{compilation option!-std=gnu99@{\lstinline$-std=gnu99$}}
     244\item\hspace*{-4pt}\Indexc{-std=gnu99}\index{compilation option!-std=gnu99@{\lstinline$-std=gnu99$}}
    241245The 1999 C standard plus GNU extensions.
    242 \item
    243 \hspace*{-4pt}\lstinline@-fgnu89-inline@
    244 \index{-fgnu89-inline@{\lstinline$-fgnu89-inline$}}\index{compilation option!-fgnu89-inline@{\lstinline$-fgnu89-inline$}}
     246\item\hspace*{-4pt}\Indexc{-fgnu89-¶inline¶}\index{compilation option!-fgnu89-inline@{\lstinline$-fgnu89-¶inline¶$}}
    245247Use the traditional GNU semantics for inline routines in C99 mode.
    246248\end{description}
    247249The following new \CFA option is available:
    248250\begin{description}
    249 \item
    250 \hspace*{-4pt}\lstinline@-CFA@
    251 \index{-CFA@{\lstinline$-CFA$}}\index{compilation option!-CFA@{\lstinline$-CFA$}}
     251\item\hspace*{-4pt}\Indexc{-CFA}\index{compilation option!-CFA@{\lstinline$-CFA$}}
    252252Only the C preprocessor and the \CFA translator steps are performed and the transformed program is written to standard output, which makes it possible to examine the code generated by the \CFA translator.
    253253\end{description}
     
    255255The following preprocessor variables are available:
    256256\begin{description}
    257 \item
    258 \hspace*{-4pt}\lstinline$__CFA__$
    259 \index{__CFA__@{\lstinline$__CFA__$}}\index{preprocessor variables!__CFA__@{\lstinline$__CFA__$}}
     257\item\hspace*{-4pt}\Indexc{__CFA__}\index{preprocessor variables!__CFA__@{\lstinline$__CFA__$}}
    260258is always available during preprocessing and its value is the current major \Index{version number} of \CFA.\footnote{
    261259The C preprocessor allows only integer values in a preprocessor variable so a value like ``\Version'' is not allowed.
    262260Hence, the need to have three variables for the major, minor and patch version number.}
    263261
    264 \item
    265 \hspace*{-4pt}\lstinline$__CFA_MINOR__$
    266 \index{__CFA_MINOR__@{\lstinline$__CFA_MINOR__$}}\index{preprocessor variables!__CFA_MINOR__@{\lstinline$__CFA_MINOR__$}}
     262\item\hspace*{-4pt}\Indexc{__CFA_MINOR__}\index{preprocessor variables!__CFA_MINOR__@{\lstinline$__CFA_MINOR__$}}
    267263is always available during preprocessing and its value is the current minor \Index{version number} of \CFA.
    268264
    269 \item
    270 \hspace*{-4pt}\lstinline$__CFA_PATCH__$
    271 \index{__CFA_PATCH__@%(__CFA_PATCH__%)}\index{preprocessor variables!__CFA_PATCH__@%(__CFA_PATCH__%)}
     265\item\hspace*{-4pt}\Indexc{__CFA_PATCH__}\index{preprocessor variables!__CFA_PATCH__@\lstinline$__CFA_PATCH__$}
    272266is always available during preprocessing and its value is the current patch \Index{version number} of \CFA.
    273267
    274 \item
    275 \hspace*{-4pt}\lstinline$__CFORALL__$
    276 \index{__CFORALL__@%(__CFORALL__%)}\index{preprocessor variables!__CFORALL__@%(__CFORALL__%)}
     268\item\hspace*{-4pt}\Indexc{__CFORALL__}\index{preprocessor variables!__CFORALL__@\lstinline$__CFORALL__$}
    277269is always available during preprocessing and it has no value.
    278270\end{description}
     
    282274\begin{lstlisting}
    283275#ifndef __CFORALL__
    284 #include <stdio.h>              // C header file
     276#include <stdio.h>                      // C header file
    285277#else
    286 #include <fstream>              // @\CFA{}@ header file
     278#include <fstream>                      // §\CFA{}§ header file
    287279#endif
    288280\end{lstlisting}
     
    294286Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, e.g.:
    295287\begin{lstlisting}
    296 2`_`147`_`483`_`648;                            // decimal constant
     2882®_®147®_®483®_®648;                            // decimal constant
    29728956_ul;                                          // decimal unsigned long constant
    2982900_377;                                          // octal constant
     
    360352\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{C}}        \\
    361353\begin{lstlisting}
    362 `* int x, y;`
     354®* int x, y;®
    363355\end{lstlisting}
    364356&
     
    488480The point of the new syntax is to allow returning multiple values from a routine~\cite{CLU,Galletly96}, e.g.:
    489481\begin{lstlisting}
    490 `[ int o1, int o2, char o3 ]` f( int i1, char i2, char i3 ) {
    491         @\emph{routine body}@
     482®[ int o1, int o2, char o3 ]® f( int i1, char i2, char i3 ) {
     483        §\emph{routine body}§
    492484}
    493485\end{lstlisting}
     
    500492Declaration qualifiers can only appear at the start of a routine definition, e.g.:
    501493\begin{lstlisting}
    502 extern [ int x ] g( int y ) {@\,@}
     494extern [ int x ] g( int y ) {§\,§}
    503495\end{lstlisting}
    504496Lastly, if there are no output parameters or input parameters, the brackets and/or parentheses must still be specified;
    505497in both cases the type is assumed to be void as opposed to old style C defaults of int return type and unknown parameter types, respectively, as in:
    506498\begin{lstlisting}
    507 [@\,@] g(@\,@);                         // no input or output parameters
     499[§\,§] g();                                             // no input or output parameters
    508500[ void ] g( void );                     // no input or output parameters
    509501\end{lstlisting}
     
    556548Because the value in the return variable is automatically returned when a \CFA routine terminates, the \lstinline@return@ statement \emph{does not} contain an expression, as in:
    557549\begin{lstlisting}
    558 `[ int x ]` f() {
     550®[ int x ]® f() {
    559551        ... x = 0; ... x = y; ...
    560         `return;` // implicitly return x
     552        ®return;® // implicitly return x
    561553}
    562554\end{lstlisting}
     
    781773\subsection{Type Nesting}
    782774
    783 \CFA allows \Index{type nesting}, and type qualification of the nested types, where as C hoists\index{type!hoisting} (refactors) nested types into the enclosing scope and has no type qualification.
     775\CFA allows \Index{type nesting}, and type qualification of the nested types, where as C hoists\index{type hoisting} (refactors) nested types into the enclosing scope and has no type qualification.
    784776\begin{quote2}
    785777\begin{tabular}{@{}l@{\hspace{30pt}}l|l@{}}
     
    836828
    837829int fred() {
    838         s.t.c = `S.`R;  // type qualification
    839         struct `S.`T t = { `S.`R, 1, 2 };
    840         enum `S.`C c;
    841         union `S.T.`U u;
     830        s.t.c = ®S.®R;  // type qualification
     831        struct ®S.®T t = { ®S.®R, 1, 2 };
     832        enum ®S.®C c;
     833        union ®S.T.®U u;
    842834}
    843835\end{lstlisting}
     
    863855qsort( ia, size );              // sort ascending order using builtin ?<?
    864856{
    865         `int ?<?( int x, int y ) { return x > y; }` // nested routine
     857        ®int ?<?( int x, int y ) { return x > y; }® // nested routine
    866858        qsort( ia, size );      // sort descending order by local redefinition
    867859}
     
    873865\begin{lstlisting}
    874866[* [int]( int )] foo() {                // int (*foo())( int )
    875         int `i` = 7;
     867        int ®i® = 7;
    876868        int bar( int p ) {
    877                 `i` += 1;                                       // dependent on local variable
    878                 sout | `i` | endl;
     869                ®i® += 1;                                       // dependent on local variable
     870                sout | ®i® | endl;
    879871        }
    880872        return bar;                                     // undefined because of local dependence
     
    897889The general syntax of a tuple is:
    898890\begin{lstlisting}
    899 [ $\emph{exprlist}$ ]
     891[ §\emph{exprlist}§ ]
    900892\end{lstlisting}
    901893where \lstinline@$\emph{exprlist}$@ is a list of one or more expressions separated by commas.
     
    917909The general syntax of a tuple type is:
    918910\begin{lstlisting}
    919 [ @\emph{typelist}@ ]
     911[ §\emph{typelist}§ ]
    920912\end{lstlisting}
    921913where \lstinline@$\emph{typelist}$@ is a list of one or more legal \CFA or C type specifications separated by commas, which may include other tuple type specifications.
     
    10471039Mass assignment has the following form:
    10481040\begin{lstlisting}
    1049 [ @\emph{lvalue}@, ..., @\emph{lvalue}@ ] = @\emph{expr}@;
    1050 \end{lstlisting}
    1051 The left-hand side is a tuple of \lstinline@$\emph{lvalues}$@, which is a list of expressions each yielding an address, i.e., any data object that can appear on the left-hand side of a conventional assignment statement.
     1041[ §\emph{lvalue}§, ..., §\emph{lvalue}§ ] = §\emph{expr}§;
     1042\end{lstlisting}
     1043The left-hand side is a tuple of \emph{lvalues}, which is a list of expressions each yielding an address, i.e., any data object that can appear on the left-hand side of a conventional assignment statement.
    10521044\lstinline@$\emph{expr}$@ is any standard arithmetic expression.
    10531045Clearly, the types of the entities being assigned must be type compatible with the value of the expression.
     
    10861078Multiple assignment has the following form:
    10871079\begin{lstlisting}
    1088 [ @\emph{lvalue}@, . . ., @\emph{lvalue}@ ] = [ @\emph{expr}@, . . ., @\emph{expr}@ ];
    1089 \end{lstlisting}
    1090 The left-hand side is a tuple of \lstinline@$\emph{lvalues}$@, and the right-hand side is a tuple of \lstinline@$\emph{expr}$@s.
    1091 Each \lstinline@$\emph{expr}$@ appearing on the righthand side of a multiple assignment statement is assigned to the corresponding \lstinline@$\emph{lvalues}$@ on the left-hand side of the statement using parallel semantics for each assignment.
     1080[ §\emph{lvalue}§, . . ., §\emph{lvalue}§ ] = [ §\emph{expr}§, . . ., §\emph{expr}§ ];
     1081\end{lstlisting}
     1082The left-hand side is a tuple of \emph{lvalues}, and the right-hand side is a tuple of \emph{expr}s.
     1083Each \emph{expr} appearing on the righthand side of a multiple assignment statement is assigned to the corresponding \emph{lvalues} on the left-hand side of the statement using parallel semantics for each assignment.
    10921084An example of multiple assignment is:
    10931085\begin{lstlisting}
     
    11261118Cascade assignment has the following form:
    11271119\begin{lstlisting}
    1128 @\emph{tuple}@ = @\emph{tuple}@ = ... = @\emph{tuple}@;
     1120§\emph{tuple}§ = §\emph{tuple}§ = ... = §\emph{tuple}§;
    11291121\end{lstlisting}
    11301122and it has the same parallel semantics as for mass and multiple assignment.
     
    11441136Its general form is:
    11451137\begin{lstlisting}
    1146 @\emph{expr}@ . [ @\emph{fieldlist}@ ]
    1147 @\emph{expr}@ -> [ @\emph{fieldlist}@ ]
    1148 \end{lstlisting}
    1149 \lstinline@$\emph{expr}$@ is any expression yielding a value of type record, e.g., \lstinline@struct@, \lstinline@union@.
    1150 Each element of \lstinline@$\emph{ fieldlist}$@ is an element of the record specified by \lstinline@$\emph{expr}$@.
     1138§\emph{expr}§ . [ §\emph{fieldlist}§ ]
     1139§\emph{expr}§ -> [ §\emph{fieldlist}§ ]
     1140\end{lstlisting}
     1141\emph{expr} is any expression yielding a value of type record, e.g., \lstinline@struct@, \lstinline@union@.
     1142Each element of \emph{ fieldlist} is an element of the record specified by \emph{expr}.
    11511143A record-field tuple may be used anywhere a tuple can be used. An example of the use of a record-field tuple is
    11521144the following:
     
    11881180\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{C}}        \\
    11891181\begin{lstlisting}
    1190 `L1:` for ( ... ) {
    1191         `L2:` for ( ... ) {
    1192                 `L3:` for ( ... ) {
    1193                         ... break `L1`; ...
    1194                         ... break `L2`; ...
    1195                         ... break `L3`; // or break
     1182®L1:® for ( ... ) {
     1183        ®L2:® for ( ... ) {
     1184                ®L3:® for ( ... ) {
     1185                        ... break ®L1®; ...
     1186                        ... break ®L2®; ...
     1187                        ... break ®L3®; // or break
    11961188                }
    11971189        }
     
    12181210\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{C}}        \\
    12191211\begin{lstlisting}
    1220 `L1`: for ( ... ) {
    1221         `L2`: for ( ... ) {
    1222                 `L3`: for ( ... ) {
    1223                         ... continue `L1`; ...
    1224                         ... continue `L2`; ...
    1225                         ... continue `L3`; ...
     1212®L1®: for ( ... ) {
     1213        ®L2®: for ( ... ) {
     1214                ®L3®: for ( ... ) {
     1215                        ... continue ®L1®; ...
     1216                        ... continue ®L2®; ...
     1217                        ... continue ®L3®; ...
    12261218
    12271219                }
     
    14591451\begin{lstlisting}
    14601452switch ( i ) {
    1461   `case 1, 3, 5`:
     1453  ®case 1, 3, 5®:
    14621454        ...
    1463   `case 2, 4, 6`:
     1455  ®case 2, 4, 6®:
    14641456        ...
    14651457}
     
    14911483\begin{lstlisting}
    14921484switch ( i ) {
    1493   `case 1~5:`
     1485  ®case 1~5:®
    14941486        ...
    1495   `case 10~15:`
     1487  ®case 10~15:®
    14961488        ...
    14971489}
     
    20482040For example, given
    20492041\begin{lstlisting}
    2050 auto j = `...`
     2042auto j = ®...®
    20512043\end{lstlisting}
    20522044and the need to write a routine to compute using \lstinline@j@
    20532045\begin{lstlisting}
    2054 void rtn( `...` parm );
     2046void rtn( ®...® parm );
    20552047rtn( j );
    20562048\end{lstlisting}
     
    23722364To make this work, a space is required after the field selection:
    23732365\begin{lstlisting}
    2374 `s.@\textvisiblespace@0` = 0;
    2375 `s.@\textvisiblespace@1` = 1;
     2366®s.§\textvisiblespace§0® = 0;
     2367®s.§\textvisiblespace§1® = 1;
    23762368\end{lstlisting}
    23772369While this sytact is awkward, it is unlikely many programers will name fields of a structure 0 or 1.
    2378 Like the \CC lexical problem with closing template-syntax, e.g, \lstinline@Foo<Bar<int`>>`@, this issue can be solved with a more powerful lexer/parser.
     2370Like the \CC lexical problem with closing template-syntax, e.g, \lstinline@Foo<Bar<int®>>®@, this issue can be solved with a more powerful lexer/parser.
    23792371
    23802372There are several ambiguous cases with operator identifiers, e.g., \lstinline@int *?*?()@, where the string \lstinline@*?*?@ can be lexed as \lstinline@*@/\lstinline@?*?@ or \lstinline@*?@/\lstinline@*?@.
     
    23832375The first case is for the function-call identifier \lstinline@?()@:
    23842376\begin{lstlisting}
    2385 int *@\textvisiblespace@?()();  // declaration: space required after '*'
    2386 *@\textvisiblespace@?()();              // expression: space required after '*'
     2377int *§\textvisiblespace§?()();  // declaration: space required after '*'
     2378*§\textvisiblespace§?()();              // expression: space required after '*'
    23872379\end{lstlisting}
    23882380Without the space, the string \lstinline@*?()@ is ambiguous without N character look ahead;
     
    23912383The 4 remaining cases occur in expressions:
    23922384\begin{lstlisting}
    2393 i++@\textvisiblespace@?i:0;             // space required before '?'
    2394 i--@\textvisiblespace@?i:0;             // space required before '?'
    2395 i@\textvisiblespace@?++i:0;             // space required after '?'
    2396 i@\textvisiblespace@?--i:0;             // space required after '?'
     2385i++§\textvisiblespace§?i:0;             // space required before '?'
     2386i--§\textvisiblespace§?i:0;             // space required before '?'
     2387i§\textvisiblespace§?++i:0;             // space required after '?'
     2388i§\textvisiblespace§?--i:0;             // space required after '?'
    23972389\end{lstlisting}
    23982390In the first two cases, the string \lstinline@i++?@ is ambiguous, where this string can be lexed as \lstinline@i@ / \lstinline@++?@ or \lstinline@i++@ / \lstinline@?@;
     
    33253317
    33263318
    3327 \subsection{Comparing Key Features of \CFA}
     3319\subsection[Comparing Key Features of CFA]{Comparing Key Features of \CFA}
    33283320
    33293321
     
    36993691
    37003692\begin{comment}
    3701 \subsubsection{Modules/Packages}
     3693\subsubsection{Modules / Packages}
    37023694
    37033695\begin{lstlisting}
     
    39413933
    39423934
    3943 \subsubsection{\CC}
     3935\subsubsection[C++]{\CC}
    39443936
    39453937\CC is a general-purpose programming language.
     
    40794071Given that nested types in C are equivalent to not using them, i.e., they are essentially useless, it is unlikely there are any realistic usages that break because of this incompatibility.
    40804072
    4081 
    40824073\item
    40834074Change: In C++, the name of a nested class is local to its enclosing class.
     
    40904081struct Y yy; // valid C, invalid C++
    40914082\end{lstlisting}
    4092 Rationale: C++ classes have member functions which require that classes establish scopes. The C rule
    4093 would leave classes as an incomplete scope mechanism which would prevent C++ programmers from maintaining
    4094 locality within a class. A coherent set of scope rules for C++ based on the C rule would be very
    4095 complicated and C++ programmers would be unable to predict reliably the meanings of nontrivial examples
    4096 involving nested or local functions.
    4097 Effect on original feature: Change of semantics of welldefined
    4098 feature.
    4099 Difficulty of converting: Semantic transformation. To make the struct type name visible in the scope of
    4100 the enclosing struct, the struct tag could be declared in the scope of the enclosing struct, before the enclosing
    4101 struct is defined. Example:
     4083Rationale: C++ classes have member functions which require that classes establish scopes.
     4084The C rule would leave classes as an incomplete scope mechanism which would prevent C++ programmers from maintaining locality within a class. A coherent set of scope rules for C++ based on the C rule would be very complicated and C++ programmers would be unable to predict reliably the meanings of nontrivial examples involving nested or local functions.
     4085Effect on original feature: Change of semantics of welldefined feature.
     4086Difficulty of converting: Semantic transformation. To make the struct type name visible in the scope of the enclosing struct, the struct tag could be declared in the scope of the enclosing struct, before the enclosing struct is defined. Example:
    41024087\begin{lstlisting}
    41034088struct Y; // struct Y and struct X are at the same scope
     
    41064091};
    41074092\end{lstlisting}
    4108 All the definitions of C struct types enclosed in other struct definitions and accessed outside the scope of
    4109 the enclosing struct could be exported to the scope of the enclosing struct. Note: this is a consequence of
    4110 the difference in scope rules, which is documented in 3.3.
     4093All the definitions of C struct types enclosed in other struct definitions and accessed outside the scope of the enclosing struct could be exported to the scope of the enclosing struct.
     4094Note: this is a consequence of the difference in scope rules, which is documented in 3.3.
    41114095How widely used: Seldom.
    41124096\end{enumerate}
     
    41244108\begin{lstlisting}
    41254109int x = 0, y = 1, z = 2;
    4126 `sout` `|` x `|` y `|` z `| endl`;
     4110®sout® ®|® x ®|® y ®|® z ®| endl®;
    41274111\end{lstlisting}
    41284112&
     
    41334117\end{tabular}
    41344118\end{quote2}
    4135 The \CFA form is half as many characters, and is similar to Python I/O with respect to implicit separators.
     4119The \CFA form is half as many characters, and is similar to \Index{Python} I/O with respect to implicit separators.
    41364120
    41374121The logical-or operator is used because it is the lowest-priority overloadable operator, other than assignment.
     
    41604144A seperator does not appear at the start or end of a line.
    41614145\begin{lstlisting}[belowskip=0pt]
    4162 sout 1 | 2 | 3 | endl;
     4146sout | 1 | 2 | 3 | endl;
    41634147\end{lstlisting}
    41644148\begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    41794163which is a local mechanism to disable insertion of the separator character.
    41804164\item
    4181 A seperator does not appear before a C string starting with the \Index{extended ASCII}\index{ASCII} characters: \lstinline[mathescape=off]@([{$£¥¿«@
     4165A seperator does not appear before a C string starting with the (extended) \Index{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off]@([{$£¥¡¿«@
    41824166%$
    41834167\begin{lstlisting}[mathescape=off]
    4184 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x $" | 4 | "x £" | 5 | "x ¥" | 6 | "x ¿" | 7 | "x «" | 8 | endl;
     4168sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x $" | 4 | "x £" | 5 | "x ¥" | 6 | "x ¡" | 7 | "x ¿" | 8 | "x «" | 9 | endl;
    41854169\end{lstlisting}
    41864170%$
    41874171\begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4188 x (1 x [2 x {3 x $4 x £5 x ¥6 x ¿7 x «8
     4172x (1 x [2 x {3 x $4 x £5 x ¥6 x ¡7 x ¿8 x «9
    41894173\end{lstlisting}
    41904174%$
    41914175\item
    4192 A seperator does not appear after a C string ending with the extended ASCII characters: \lstinline@,.:;!?)]}%¢»@
     4176A seperator does not appear after a C string ending with the (extended) \Index{ASCII}\index{ASCII!extended} characters: \lstinline@,.:;!?)]}%¢»@
    41934177\begin{lstlisting}[belowskip=0pt]
    41944178sout | 1 | ", x" | 2 | ". x" | 3 | ": x" | 4 | "; x" | 5 | "! x" | 6 | "? x" | 7 | ") x" | 8 | "] x" | 9 | "} x"
    4195          | 10 | "% x" | 11 | L"¢ x" | 12 | L"» x" | endl;
     4179         | 10 | "% x" | 11 | "¢ x" | 12 | "» x" | endl;
    41964180\end{lstlisting}
    41974181\begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    41994183\end{lstlisting}
    42004184\item
    4201 A seperator does not appear before or after a C string begining/ending with the characters: \lstinline@\f\n\r\t\v\`'"@
     4185A seperator does not appear before or after a C string begining/ending with the \Index{ASCII} quote or whitespace characters: \lstinline[showspaces=true]@`'" \t\v\f\r\n@
    42024186\begin{lstlisting}[belowskip=0pt]
    4203 sout | "x '" | 1 | "' x \`" | 2 | "\` x \"" | 3 | "\" x" | endl;
    4204 \end{lstlisting}
    4205 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4206 x '1' x \`2\` x "3" x
    4207 \end{lstlisting}
    4208 \begin{lstlisting}[showtabs=true,aboveskip=0pt]
    4209 sout | "x\t" | 1 | "\tx" | endl;
    4210 x       1       x
     4187sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x" | "x " | 4 | " x" | "x\t" | 1 | "\tx" | endl;
     4188\end{lstlisting}
     4189\begin{lstlisting}[mathescape=off,showspaces=true,showtabs=true,aboveskip=0pt,belowskip=0pt]
     4190x`1`x'2'x"3"x x 4 x x   1       x
    42114191\end{lstlisting}
    42124192\end{enumerate}
     
    42404220\end{lstlisting}
    42414221\begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4242 1 2 3
     4222 1 2 3
    42434223\end{lstlisting}
    42444224\begin{lstlisting}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt]
     
    42514231\end{lstlisting}
    42524232%$
    4253 \VRef[Figure]{f:ExampleIO} shows an example of input and output I/O in \CFA.
    4254 
    4255 \begin{figure}
    4256 \begin{lstlisting}[mathescape=off]
     4233\begin{comment}
    42574234#include <fstream>
    42584235
    42594236int main() {
    4260         char c;                                                                                                         // basic types
    4261         short int si;
    4262         unsigned short int usi;
    4263         int i;
    4264         unsigned int ui;
    4265         long int li;
    4266         unsigned long int uli;
    4267         long long int lli;
    4268         unsigned long long int ulli;
    4269         float f;
    4270         double d;
    4271         long double ld;
    4272         float _Complex fc;
    4273         double _Complex dc;
    4274         long double _Complex ldc;
    4275         char s1[10], s2[10];
    4276 
    4277         ifstream in;                                                                                            // create / open file
    4278         open( &in, "input.data", "r" );
    4279 
    4280         &in | &c                                                                                                        // character
    4281                 | &si | &usi | &i | &ui | &li | &uli | &lli | &ulli             // integral
    4282                 | &f | &d | &ld                                                                                 // floating point
    4283                 | &fc | &dc | &ldc                                                                              // floating-point complex
    4284                 | cstr( s1 ) | cstr( s2, 10 );                                                  // C string, length unchecked and checked
    4285 
    4286         sout | c | ' ' | endl                                                                           // character
    4287                  | si | usi | i | ui | li | uli | lli | ulli | endl             // integral
    4288                  | f | d | ld | endl                                                                    // floating point
    4289                  | fc | dc | ldc | endl;                                                                // complex
    4290         sout | endl;
    4291         sout | f | "" | d | "" | ld | endl                                                      // floating point without separator
    4292                  | sepDisable | fc | dc | ldc | sepEnable | endl                // complex without separator
    4293                  | sepOn | s1 | sepOff | s2 | endl                                              // local separator removal
    4294                  | s1 | "" | s2 | endl;                                                                 // C string withou separator
    4295         sout | endl;
    4296         sepSet( sout, ", $" );                                                                          // change separator, maximum of 15 characters
    4297         sout | f | d | ld | endl                                                                        // floating point without separator
    4298                  | fc | dc | ldc | endl                                                                 // complex without separator
    4299                  | s1 | s2 | endl;
    4300 }
    4301 
    4302 $ cat input.data
    4303 A 1 2 3 4 5 6 7 8 1.1 1.2 1.3 1.1+2.3 1.1-2.3 1.1-2.3 abc xyz
    4304 $ a.out
    4305 A
    4306 1 2 3 4 5 6 7 8
    4307 1.1 1.2 1.3
    4308 1.1+2.3i 1.1-2.3i 1.1-2.3i
    4309 
    4310 1.11.21.3
    4311 1.1+2.3i1.1-2.3i1.1-2.3i
    4312  abcxyz
    4313 abcxyz
    4314 
    4315 1.1, $1.2, $1.3
    4316 1.1+2.3i, $1.1-2.3i, $1.1-2.3i
    4317 abc, $xyz
    4318 \end{lstlisting}
    4319 \caption{Example I/O}
    4320 \label{f:ExampleIO}
    4321 \end{figure}
     4237        int x = 3, y = 5, z = 7;
     4238        sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
     4239        sout | 1 | 2 | 3 | endl;
     4240        sout | '1' | '2' | '3' | endl;
     4241        sout | 1 | "" | 2 | "" | 3 | endl;
     4242        sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x $" | 4 | "x £" | 5 | "x ¥" | 6 | "x ¡" | 7 | "x ¿" | 8 | "x «" | 9 | endl;
     4243        sout | 1 | ", x" | 2 | ". x" | 3 | ": x" | 4 | "; x" | 5 | "! x" | 6 | "? x" | 7 | ") x" | 8 | "] x" | 9 | "} x"
     4244                 | 10 | "% x" | 11 | "¢ x" | 12 | "» x" | endl;
     4245        sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x" | "x " | 4 | " x" | "x\t" | 1 | "\tx" | endl;
     4246        sout | sepOn | 1 | 2 | 3 | sepOn | endl;        // separator at start of line
     4247        sout | 1 | sepOff | 2 | 3 | endl;                       // turn off implicit separator temporarily
     4248        sout | sepDisable | 1 | 2 | 3 | endl;           // turn off implicit separation, affects all subsequent prints
     4249        sout | 1 | sepOn | 2 | 3 | endl;                        // turn on implicit separator temporarily
     4250        sout | sepEnable | 1 | 2 | 3 | endl;            // turn on implicit separation, affects all subsequent prints
     4251        sepSet( sout, ", $" );                                          // change separator from " " to ", $"
     4252        sout | 1 | 2 | 3 | endl;
     4253
     4254}
     4255
     4256// Local Variables: //
     4257// tab-width: 4 //
     4258// End: //
     4259\end{comment}
     4260%$
    43224261
    43234262
     
    43314270
    43324271\begin{lstlisting}
    4333 forall( otype T ) T * malloc( void );
     4272forall( otype T ) T * malloc( void );§\indexc{malloc}§
    43344273forall( otype T ) T * malloc( char fill );
    43354274forall( otype T ) T * malloc( T * ptr, size_t size );
    43364275forall( otype T ) T * malloc( T * ptr, size_t size, unsigned char fill );
    4337 forall( otype T ) T * calloc( size_t size );
    4338 forall( otype T ) T * realloc( T * ptr, size_t size );
     4276forall( otype T ) T * calloc( size_t nmemb );§\indexc{calloc}§
     4277forall( otype T ) T * realloc( T * ptr, size_t size );§\indexc{ato}§
    43394278forall( otype T ) T * realloc( T * ptr, size_t size, unsigned char fill );
    43404279
    4341 forall( otype T ) T * aligned_alloc( size_t alignment );
     4280forall( otype T ) T * aligned_alloc( size_t alignment );§\indexc{ato}§
    43424281forall( otype T ) T * memalign( size_t alignment );             // deprecated
    43434282forall( otype T ) int posix_memalign( T ** ptr, size_t alignment );
     
    43484287
    43494288
    4350 \subsection{ato/strto}
    4351 
    4352 \begin{lstlisting}
    4353 int ato( const char * ptr );
     4289\subsection{ato / strto}
     4290
     4291\begin{lstlisting}
     4292int ato( const char * ptr );§\indexc{ato}§
    43544293unsigned int ato( const char * ptr );
    43554294long int ato( const char * ptr );
     
    43794318
    43804319
    4381 \subsection{bsearch/qsort}
     4320\subsection{bsearch / qsort}
    43824321
    43834322\begin{lstlisting}
    43844323forall( otype T | { int ?<?( T, T ); } )
    4385 T * bsearch( const T key, const T * arr, size_t dimension );
     4324T * bsearch( const T key, const T * arr, size_t dimension );§\indexc{bsearch}§
    43864325
    43874326forall( otype T | { int ?<?( T, T ); } )
    4388 void qsort( const T * arr, size_t dimension );
     4327void qsort( const T * arr, size_t dimension );§\indexc{qsort}§
    43894328\end{lstlisting}
    43904329
     
    43934332
    43944333\begin{lstlisting}
    4395 char abs( char );
    4396 extern "C" {
    4397 int abs( int );                         // use default C routine for int
    4398 } // extern "C"
     4334char abs( char );§\indexc{abs}§
     4335int abs( int );
    43994336long int abs( long int );
    44004337long long int abs( long long int );
     
    44024339double abs( double );
    44034340long double abs( long double );
    4404 float _Complex abs( float _Complex );
    4405 double _Complex abs( double _Complex );
    4406 long double _Complex abs( long double _Complex );
    4407 \end{lstlisting}
    4408 
    4409 
    4410 \subsection{floor/ceil}
    4411 
    4412 \begin{lstlisting}
    4413 float floor( float );
    4414 extern "C" {
    4415 double floor( double );         // use C routine for double
    4416 } // extern "C"
    4417 long double floor( long double );
    4418 
    4419 float ceil( float );
    4420 extern "C" {
    4421 double ceil( double );          // use C routine for double
    4422 } // extern "C"
    4423 long double ceil( long double );
     4341float abs( float _Complex );
     4342double abs( double _Complex );
     4343long double abs( long double _Complex );
    44244344\end{lstlisting}
    44254345
     
    44284348
    44294349\begin{lstlisting}
    4430 void rand48seed( long int s );
    4431 char rand48();
     4350void rand48seed( long int s );§\indexc{rand48seed}§
     4351char rand48();§\indexc{rand48}§
    44324352int rand48();
    44334353unsigned int rand48();
     
    44424362
    44434363
    4444 \subsection{min/max/swap}
     4364\subsection{min / max / swap}
    44454365
    44464366\begin{lstlisting}
    44474367forall( otype T | { int ?<?( T, T ); } )
    4448 T min( const T t1, const T t2 );
     4368T min( const T t1, const T t2 );§\indexc{min}§
    44494369
    44504370forall( otype T | { int ?>?( T, T ); } )
    4451 T max( const T t1, const T t2 );
     4371T max( const T t1, const T t2 );§\indexc{max}§
    44524372
    44534373forall( otype T )
    4454 void swap( T * t1, T * t2 );
     4374void swap( T * t1, T * t2 );§\indexc{swap}§
     4375\end{lstlisting}
     4376
     4377
     4378\section{Math Library}
     4379\label{s:Math Library}
     4380
     4381The goal of the \CFA math-library is to wrap many of the existing C math library-routines that are explicitly polymorphic into implicitly polymorphic versions.
     4382
     4383
     4384\subsection{General}
     4385
     4386\begin{lstlisting}
     4387float fabs( float );§\indexc{fabs}§
     4388double fabs( double );
     4389long double fabs( long double );
     4390float cabs( float _Complex );
     4391double cabs( double _Complex );
     4392long double cabs( long double _Complex );
     4393
     4394float ?%?( float, float );§\indexc{fmod}§
     4395float fmod( float, float );
     4396double ?%?( double, double );
     4397double fmod( double, double );
     4398long double ?%?( long double, long double );
     4399long double fmod( long double, long double );
     4400
     4401float remainder( float, float );§\indexc{remainder}§
     4402double remainder( double, double );
     4403long double remainder( long double, long double );
     4404
     4405[ int, float ] remquo( float, float );§\indexc{remquo}§
     4406float remquo( float, float, int * );
     4407[ int, double ] remquo( double, double );
     4408double remquo( double, double, int * );
     4409[ int, long double ] remquo( long double, long double );
     4410long double remquo( long double, long double, int * );
     4411
     4412[ int, float ] div( float, float );                                             // alternative name for remquo
     4413float div( float, float, int * );§\indexc{div}§
     4414[ int, double ] div( double, double );
     4415double div( double, double, int * );
     4416[ int, long double ] div( long double, long double );
     4417long double div( long double, long double, int * );
     4418
     4419float fma( float, float, float );§\indexc{fma}§
     4420double fma( double, double, double );
     4421long double fma( long double, long double, long double );
     4422
     4423float fdim( float, float );§\indexc{fdim}§
     4424double fdim( double, double );
     4425long double fdim( long double, long double );
     4426
     4427float nan( const char * );§\indexc{nan}§
     4428double nan( const char * );
     4429long double nan( const char * );
     4430\end{lstlisting}
     4431
     4432
     4433\subsection{Exponential}
     4434
     4435\begin{lstlisting}
     4436float exp( float );§\indexc{exp}§
     4437double exp( double );
     4438long double exp( long double );
     4439float _Complex exp( float _Complex );
     4440double _Complex exp( double _Complex );
     4441long double _Complex exp( long double _Complex );
     4442
     4443float exp2( float );§\indexc{exp2}§
     4444double exp2( double );
     4445long double exp2( long double );
     4446float _Complex exp2( float _Complex );
     4447double _Complex exp2( double _Complex );
     4448long double _Complex exp2( long double _Complex );
     4449
     4450float expm1( float );§\indexc{expm1}§
     4451double expm1( double );
     4452long double expm1( long double );
     4453
     4454float log( float );§\indexc{log}§
     4455double log( double );
     4456long double log( long double );
     4457float _Complex log( float _Complex );
     4458double _Complex log( double _Complex );
     4459long double _Complex log( long double _Complex );
     4460
     4461float log2( float );§\indexc{log2}§
     4462double log2( double );
     4463long double log2( long double );
     4464float _Complex log2( float _Complex );
     4465double _Complex log2( double _Complex );
     4466long double _Complex log2( long double _Complex );
     4467
     4468float log10( float );§\indexc{log10}§
     4469double log10( double );
     4470long double log10( long double );
     4471float _Complex log10( float _Complex );
     4472double _Complex log10( double _Complex );
     4473long double _Complex log10( long double _Complex );
     4474
     4475float log1p( float );§\indexc{log1p}§
     4476double log1p( double );
     4477long double log1p( long double );
     4478
     4479int ilogb( float );§\indexc{ilogb}§
     4480int ilogb( double );
     4481int ilogb( long double );
     4482
     4483float logb( float );§\indexc{logb}§
     4484double logb( double );
     4485long double logb( long double );
     4486\end{lstlisting}
     4487
     4488
     4489\subsection{Power}
     4490
     4491\begin{lstlisting}
     4492float sqrt( float );§\indexc{sqrt}§
     4493double sqrt( double );
     4494long double sqrt( long double );
     4495float _Complex sqrt( float _Complex );
     4496double _Complex sqrt( double _Complex );
     4497long double _Complex sqrt( long double _Complex );
     4498
     4499float cbrt( float );§\indexc{cbrt}§
     4500double cbrt( double );
     4501long double cbrt( long double );
     4502
     4503float hypot( float, float );§\indexc{hypot}§
     4504double hypot( double, double );
     4505long double hypot( long double, long double );
     4506
     4507float pow( float, float );§\indexc{pow}§
     4508double pow( double, double );
     4509long double pow( long double, long double );
     4510float _Complex pow( float _Complex, float _Complex );
     4511double _Complex pow( double _Complex, double _Complex );
     4512long double _Complex pow( long double _Complex, long double _Complex );
     4513\end{lstlisting}
     4514
     4515
     4516\subsection{Trigonometric}
     4517
     4518\begin{lstlisting}
     4519float sin( float );§\indexc{sin}§
     4520double sin( double );
     4521long double sin( long double );
     4522float _Complex sin( float _Complex );
     4523double _Complex sin( double _Complex );
     4524long double _Complex sin( long double _Complex );
     4525
     4526float cos( float );§\indexc{cos}§
     4527double cos( double );
     4528long double cos( long double );
     4529float _Complex cos( float _Complex );
     4530double _Complex cos( double _Complex );
     4531long double _Complex cos( long double _Complex );
     4532
     4533float tan( float );§\indexc{tan}§
     4534double tan( double );
     4535long double tan( long double );
     4536float _Complex tan( float _Complex );
     4537double _Complex tan( double _Complex );
     4538long double _Complex tan( long double _Complex );
     4539
     4540float asin( float );§\indexc{asin}§
     4541double asin( double );
     4542long double asin( long double );
     4543float _Complex asin( float _Complex );
     4544double _Complex asin( double _Complex );
     4545long double _Complex asin( long double _Complex );
     4546
     4547float acos( float );§\indexc{acos}§
     4548double acos( double );
     4549long double acos( long double );
     4550float _Complex acos( float _Complex );
     4551double _Complex acos( double _Complex );
     4552long double _Complex acos( long double _Complex );
     4553
     4554float atan( float );§\indexc{atan}§
     4555double atan( double );
     4556long double atan( long double );
     4557float _Complex atan( float _Complex );
     4558double _Complex atan( double _Complex );
     4559long double _Complex atan( long double _Complex );
     4560
     4561float atan2( float, float );§\indexc{atan2}§
     4562double atan2( double, double );
     4563long double atan2( long double, long double );
     4564
     4565float atan( float, float );                                                             // alternative name for atan2
     4566double atan( double, double );§\indexc{atan}§
     4567long double atan( long double, long double );
     4568\end{lstlisting}
     4569
     4570
     4571\subsection{Hyperbolic}
     4572
     4573\begin{lstlisting}
     4574float sinh( float );§\indexc{sinh}§
     4575double sinh( double );
     4576long double sinh( long double );
     4577float _Complex sinh( float _Complex );
     4578double _Complex sinh( double _Complex );
     4579long double _Complex sinh( long double _Complex );
     4580
     4581float cosh( float );§\indexc{cosh}§
     4582double cosh( double );
     4583long double cosh( long double );
     4584float _Complex cosh( float _Complex );
     4585double _Complex cosh( double _Complex );
     4586long double _Complex cosh( long double _Complex );
     4587
     4588float tanh( float );§\indexc{tanh}§
     4589double tanh( double );
     4590long double tanh( long double );
     4591float _Complex tanh( float _Complex );
     4592double _Complex tanh( double _Complex );
     4593long double _Complex tanh( long double _Complex );
     4594
     4595float asinh( float );§\indexc{asinh}§
     4596double asinh( double );
     4597long double asinh( long double );
     4598float _Complex asinh( float _Complex );
     4599double _Complex asinh( double _Complex );
     4600long double _Complex asinh( long double _Complex );
     4601
     4602float acosh( float );§\indexc{acosh}§
     4603double acosh( double );
     4604long double acosh( long double );
     4605float _Complex acosh( float _Complex );
     4606double _Complex acosh( double _Complex );
     4607long double _Complex acosh( long double _Complex );
     4608
     4609float atanh( float );§\indexc{atanh}§
     4610double atanh( double );
     4611long double atanh( long double );
     4612float _Complex atanh( float _Complex );
     4613double _Complex atanh( double _Complex );
     4614long double _Complex atanh( long double _Complex );
     4615\end{lstlisting}
     4616
     4617
     4618\subsection{Error / Gamma}
     4619
     4620\begin{lstlisting}
     4621float erf( float );§\indexc{erf}§
     4622double erf( double );
     4623long double erf( long double );
     4624float _Complex erf( float _Complex );
     4625double _Complex erf( double _Complex );
     4626long double _Complex erf( long double _Complex );
     4627
     4628float erfc( float );§\indexc{erfc}§
     4629double erfc( double );
     4630long double erfc( long double );
     4631float _Complex erfc( float _Complex );
     4632double _Complex erfc( double _Complex );
     4633long double _Complex erfc( long double _Complex );
     4634
     4635float lgamma( float );§\indexc{lgamma}§
     4636double lgamma( double );
     4637long double lgamma( long double );
     4638float lgamma( float, int * );
     4639double lgamma( double, int * );
     4640long double lgamma( long double, int * );
     4641
     4642float tgamma( float );§\indexc{tgamma}§
     4643double tgamma( double );
     4644long double tgamma( long double );
     4645\end{lstlisting}
     4646
     4647
     4648\subsection{Nearest Integer}
     4649
     4650\begin{lstlisting}
     4651float floor( float );§\indexc{floor}§
     4652double floor( double );
     4653long double floor( long double );
     4654
     4655float ceil( float );§\indexc{ceil}§
     4656double ceil( double );
     4657long double ceil( long double );
     4658
     4659float trunc( float );§\indexc{trunc}§
     4660double trunc( double );
     4661long double trunc( long double );
     4662
     4663float rint( float );§\indexc{rint}§
     4664long double rint( long double );
     4665long int rint( float );
     4666long int rint( double );
     4667long int rint( long double );
     4668long long int rint( float );
     4669long long int rint( double );
     4670long long int rint( long double );
     4671
     4672long int lrint( float );§\indexc{lrint}§
     4673long int lrint( double );
     4674long int lrint( long double );
     4675long long int llrint( float );
     4676long long int llrint( double );
     4677long long int llrint( long double );
     4678
     4679float nearbyint( float );§\indexc{nearbyint}§
     4680double nearbyint( double );
     4681long double nearbyint( long double );
     4682
     4683float round( float );§\indexc{round}§
     4684long double round( long double );
     4685long int round( float );
     4686long int round( double );
     4687long int round( long double );
     4688long long int round( float );
     4689long long int round( double );
     4690long long int round( long double );
     4691
     4692long int lround( float );§\indexc{lround}§
     4693long int lround( double );
     4694long int lround( long double );
     4695long long int llround( float );
     4696long long int llround( double );
     4697long long int llround( long double );
     4698\end{lstlisting}
     4699
     4700
     4701\subsection{Manipulation}
     4702
     4703\begin{lstlisting}
     4704float copysign( float, float );§\indexc{copysign}§
     4705double copysign( double, double );
     4706long double copysign( long double, long double );
     4707
     4708float frexp( float, int * );§\indexc{frexp}§
     4709double frexp( double, int * );
     4710long double frexp( long double, int * );
     4711
     4712float ldexp( float, int );§\indexc{ldexp}§
     4713double ldexp( double, int );
     4714long double ldexp( long double, int );
     4715
     4716[ float, float ] modf( float );§\indexc{modf}§
     4717float modf( float, float * );
     4718[ double, double ] modf( double );
     4719double modf( double, double * );
     4720[ long double, long double ] modf( long double );
     4721long double modf( long double, long double * );
     4722
     4723float nextafter( float, float );§\indexc{nextafter}§
     4724double nextafter( double, double );
     4725long double nextafter( long double, long double );
     4726
     4727float nexttoward( float, long double );§\indexc{nexttoward}§
     4728double nexttoward( double, long double );
     4729long double nexttoward( long double, long double );
     4730
     4731float scalbn( float, int );§\indexc{scalbn}§
     4732double scalbn( double, int );
     4733long double scalbn( long double, int );
     4734
     4735float scalbln( float, long int );§\indexc{scalbln}§
     4736double scalbln( double, long int );
     4737long double scalbln( long double, long int );
    44554738\end{lstlisting}
    44564739
     
    44644747\begin{lstlisting}
    44654748// implementation
    4466 struct Rational {
     4749struct Rational {§\indexc{Rational}§
    44674750        long int numerator, denominator;                                        // invariant: denominator > 0
    44684751}; // Rational
  • src/CodeGen/CodeGenerator.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CodeGenerator.cc -- 
     7// CodeGenerator.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:32:16 2016
    13 // Update Count     : 243
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 27 11:59:36 2016
     13// Update Count     : 255
    1414//
    1515
     
    6767        string mangleName( DeclarationWithType *decl ) {
    6868                if ( decl->get_mangleName() != "" ) {
    69                         return decl->get_mangleName();
     69                        // need to incorporate scope level in order to differentiate names for destructors
     70                        return decl->get_scopedMangleName();
    7071                } else {
    7172                        return decl->get_name();
     
    99100                handleStorageClass( objectDecl );
    100101                output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
    101        
     102
    102103                if ( objectDecl->get_init() ) {
    103104                        output << " = ";
     
    113114                if ( aggDecl->get_name() != "" )
    114115                        output << aggDecl->get_name();
    115        
     116
    116117                std::list< Declaration * > &memb = aggDecl->get_members();
    117118
     
    119120                        output << " {" << endl;
    120121
    121                         cur_indent += CodeGenerator::tabsize; 
     122                        cur_indent += CodeGenerator::tabsize;
    122123                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    123                                 output << indent; 
     124                                output << indent;
    124125                                (*i)->accept( *this );
    125126                                output << ";" << endl;
    126127                        }
    127128
    128                         cur_indent -= CodeGenerator::tabsize; 
     129                        cur_indent -= CodeGenerator::tabsize;
    129130
    130131                        output << indent << "}";
     
    141142                handleAggregate( aggregateDecl );
    142143        }
    143  
     144
    144145        void CodeGenerator::visit( EnumDecl *aggDecl ) {
    145146                output << "enum ";
     
    147148                if ( aggDecl->get_name() != "" )
    148149                        output << aggDecl->get_name();
    149        
     150
    150151                std::list< Declaration* > &memb = aggDecl->get_members();
    151152
     
    153154                        output << " {" << endl;
    154155
    155                         cur_indent += CodeGenerator::tabsize; 
     156                        cur_indent += CodeGenerator::tabsize;
    156157                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    157158                                ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
    158159                                assert( obj );
    159                                 output << indent << mangleName( obj ); 
     160                                output << indent << mangleName( obj );
    160161                                if ( obj->get_init() ) {
    161162                                        output << " = ";
     
    165166                        } // for
    166167
    167                         cur_indent -= CodeGenerator::tabsize; 
     168                        cur_indent -= CodeGenerator::tabsize;
    168169
    169170                        output << indent << "}";
    170171                } // if
    171172        }
    172  
     173
    173174        void CodeGenerator::visit( TraitDecl *aggregateDecl ) {}
    174  
     175
    175176        void CodeGenerator::visit( TypedefDecl *typeDecl ) {
    176177                output << "typedef ";
    177178                output << genType( typeDecl->get_base(), typeDecl->get_name() );
    178179        }
    179  
     180
    180181        void CodeGenerator::visit( TypeDecl *typeDecl ) {
    181182                // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
     
    213214                printDesignators( init->get_designators() );
    214215                output << "{ ";
    215                 genCommaList( init->begin_initializers(), init->end_initializers() );
     216                if ( init->begin_initializers() == init->end_initializers() ) {
     217                        // illegal to leave initializer list empty for scalar initializers,
     218                        // but always legal to have 0
     219                        output << "0";
     220                } else {
     221                        genCommaList( init->begin_initializers(), init->end_initializers() );
     222                }
    216223                output << " }";
    217224        }
    218225
    219         void CodeGenerator::visit( Constant *constant ) { 
     226        void CodeGenerator::visit( Constant *constant ) {
    220227                output << constant->get_value() ;
    221228        }
     
    231238                                  case OT_POSTFIXASSIGN:
    232239                                  case OT_INFIXASSIGN:
     240                                  case OT_CTOR:
     241                                  case OT_DTOR:
    233242                                        {
    234243                                                assert( arg != applicationExpr->get_args().end() );
    235244                                                if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
    236                
     245                                                        // remove & from first assignment/ctor argument
    237246                                                        *arg = addrExpr->get_arg();
    238247                                                } else {
     248                                                        // no address-of operator, so must be a pointer - add dereference
    239249                                                        UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
    240250                                                        newExpr->get_args().push_back( *arg );
     
    243253                                                break;
    244254                                        }
    245              
     255
    246256                                  default:
    247257                                        // do nothing
    248258                                        ;
    249259                                }
    250            
     260
    251261                                switch ( opInfo.type ) {
    252262                                  case OT_INDEX:
     
    257267                                        output << "]";
    258268                                        break;
    259              
     269
    260270                                  case OT_CALL:
    261271                                        // there are no intrinsic definitions of the function call operator
    262272                                        assert( false );
    263273                                        break;
    264              
     274
     275                                  case OT_CTOR:
     276                                  case OT_DTOR:
     277                                        if ( applicationExpr->get_args().size() == 1 ) {
     278                                                // the expression fed into a single parameter constructor or destructor
     279                                                // may contain side effects - output as a void expression
     280                                                output << "((void)(";
     281                                                (*arg++)->accept( *this );
     282                                                output << ")) /* " << opInfo.inputName << " */";
     283                                        } else if ( applicationExpr->get_args().size() == 2 ) {
     284                                                // intrinsic two parameter constructors are essentially bitwise assignment
     285                                                output << "(";
     286                                                (*arg++)->accept( *this );
     287                                                output << opInfo.symbol;
     288                                                (*arg)->accept( *this );
     289                                                output << ") /* " << opInfo.inputName << " */";
     290                                        } else {
     291                                                // no constructors with 0 or more than 2 parameters
     292                                                assert( false );
     293                                        }
     294                                        break;
     295
    265296                                  case OT_PREFIX:
    266297                                  case OT_PREFIXASSIGN:
     
    271302                                        output << ")";
    272303                                        break;
    273              
     304
    274305                                  case OT_POSTFIX:
    275306                                  case OT_POSTFIXASSIGN:
     
    278309                                        output << opInfo.symbol;
    279310                                        break;
     311
    280312
    281313                                  case OT_INFIX:
     
    288320                                        output << ")";
    289321                                        break;
    290              
     322
    291323                                  case OT_CONSTANT:
    292324                                  case OT_LABELADDRESS:
     
    307339                } // if
    308340        }
    309  
     341
    310342        void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
    311343                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     
    321353                                        output << "]";
    322354                                        break;
    323              
     355
    324356                                  case OT_CALL:
    325357                                        assert( false );
    326                                         break;
    327              
     358
     359
     360                                  case OT_CTOR:
     361                                  case OT_DTOR:
     362                                        if ( untypedExpr->get_args().size() == 1 ) {
     363                                                // the expression fed into a single parameter constructor or destructor
     364                                                // may contain side effects - output as a void expression
     365                                                output << "((void)(";
     366                                                (*arg++)->accept( *this );
     367                                                output << ")) /* " << opInfo.inputName << " */";
     368                                        } else if ( untypedExpr->get_args().size() == 2 ) {
     369                                                // intrinsic two parameter constructors are essentially bitwise assignment
     370                                                output << "(";
     371                                                (*arg++)->accept( *this );
     372                                                output << opInfo.symbol;
     373                                                (*arg)->accept( *this );
     374                                                output << ") /* " << opInfo.inputName << " */";
     375                                        } else {
     376                                                // no constructors with 0 or more than 2 parameters
     377                                                assert( false );
     378                                        }
     379                                        break;
     380
    328381                                  case OT_PREFIX:
    329382                                  case OT_PREFIXASSIGN:
     
    335388                                        output << ")";
    336389                                        break;
    337              
     390
    338391                                  case OT_POSTFIX:
    339392                                  case OT_POSTFIXASSIGN:
     
    342395                                        output << opInfo.symbol;
    343396                                        break;
    344  
     397
    345398                                  case OT_INFIX:
    346399                                  case OT_INFIXASSIGN:
     
    352405                                        output << ")";
    353406                                        break;
    354                                        
     407
    355408                                  case OT_CONSTANT:
    356409                                        // there are no intrinsic definitions of 0 or 1 as functions
     
    370423                } // if
    371424        }
    372  
     425
    373426        void CodeGenerator::visit( NameExpr *nameExpr ) {
    374427                OperatorInfo opInfo;
     
    380433                } // if
    381434        }
    382  
     435
    383436        void CodeGenerator::visit( AddressExpr *addressExpr ) {
    384437                output << "(&";
     
    409462                output << ")";
    410463        }
    411  
     464
    412465        void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
    413466                assert( false );
    414467        }
    415  
     468
    416469        void CodeGenerator::visit( MemberExpr *memberExpr ) {
    417470                memberExpr->get_aggregate()->accept( *this );
    418471                output << "." << mangleName( memberExpr->get_member() );
    419472        }
    420  
     473
    421474        void CodeGenerator::visit( VariableExpr *variableExpr ) {
    422475                OperatorInfo opInfo;
     
    427480                } // if
    428481        }
    429  
     482
    430483        void CodeGenerator::visit( ConstantExpr *constantExpr ) {
    431484                assert( constantExpr->get_constant() );
    432485                constantExpr->get_constant()->accept( *this );
    433486        }
    434  
     487
    435488        void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
    436489                output << "sizeof(";
     
    469522                assert( false && "OffsetPackExpr should not reach code generation" );
    470523        }
    471  
     524
    472525        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
    473526                output << "(";
     
    481534                output << ")";
    482535        }
    483  
     536
    484537        void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
    485538                output << "(";
     
    491544                output << ")";
    492545        }
    493  
     546
    494547        void CodeGenerator::visit( CommaExpr *commaExpr ) {
    495548                output << "(";
     
    499552                output << ")";
    500553        }
    501  
     554
    502555        void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
    503  
     556
    504557        void CodeGenerator::visit( TypeExpr *typeExpr ) {}
    505558
     
    532585                        }
    533586                }
    534                 cur_indent -= CodeGenerator::tabsize; 
     587                cur_indent -= CodeGenerator::tabsize;
    535588
    536589                output << indent << "}";
     
    538591
    539592        void CodeGenerator::visit( ExprStmt *exprStmt ) {
    540                 // I don't see why this check is necessary. 
    541                 // If this starts to cause problems then put it back in, 
     593                // I don't see why this check is necessary.
     594                // If this starts to cause problems then put it back in,
    542595                // with an explanation
    543596                assert( exprStmt );
     
    589642                switchStmt->get_condition()->accept( *this );
    590643                output << " ) ";
    591                
     644
    592645                output << "{" << std::endl;
    593646                cur_indent += CodeGenerator::tabsize;
     
    609662                } // if
    610663                output << ":\n";
    611                
     664
    612665                std::list<Statement *> sts = caseStmt->get_statements();
    613666
     
    626679                        if ( ! branchStmt->get_target().empty() )
    627680                                output << "goto " << branchStmt->get_target();
    628                         else { 
     681                        else {
    629682                                if ( branchStmt->get_computedTarget() != 0 ) {
    630683                                        output << "goto *";
     
    677730
    678731        void CodeGenerator::visit( ForStmt *forStmt ) {
    679                 // initialization is always hoisted, so don't 
    680                 // bother doing anything with that 
     732                // initialization is always hoisted, so don't
     733                // bother doing anything with that
    681734                output << "for (;";
    682735
     
    702755        void CodeGenerator::visit( DeclStmt *declStmt ) {
    703756                declStmt->get_decl()->accept( *this );
    704        
     757
    705758                if ( doSemicolon( declStmt->get_decl() ) ) {
    706759                        output << ";";
  • src/CodeGen/FixNames.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // FixNames.cc -- 
     7// FixNames.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 23:36:42 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 11 15:38:10 2016
    1313// Update Count     : 1
    1414//
     
    2626                virtual void visit( ObjectDecl *objectDecl );
    2727                virtual void visit( FunctionDecl *functionDecl );
     28
     29                virtual void visit( CompoundStmt *compoundStmt );
     30
     31          private:
     32                int scopeLevel = 1;
     33
     34                void fixDWT( DeclarationWithType *dwt );
    2835        };
    2936
     
    3340        }
    3441
    35         void fixDWT( DeclarationWithType *dwt ) {
     42        void FixNames::fixDWT( DeclarationWithType *dwt ) {
    3643                if ( dwt->get_name() != "" ) {
    3744                        if ( LinkageSpec::isDecoratable( dwt->get_linkage() ) ) {
    3845                                dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) );
     46                                dwt->set_scopeLevel( scopeLevel );
    3947                        } // if
    4048                } // if
     
    5058                fixDWT( functionDecl );
    5159        }
     60
     61        void FixNames::visit( CompoundStmt *compoundStmt ) {
     62                scopeLevel++;
     63                Visitor::visit( compoundStmt );
     64                scopeLevel--;
     65        }
    5266} // namespace CodeGen
    5367
  • src/CodeGen/OperatorTable.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // OperatorTable.cc -- 
     7// OperatorTable.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jun 23 17:41:14 2015
    13 // Update Count     : 5
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 16:48:27 2016
     13// Update Count     : 9
    1414//
    1515
     
    2121                const OperatorInfo tableValues[] = {
    2222                        {       "?[?]",         "",             "_operator_index",                              OT_INDEX                        },
     23                        {       "?{}",          "=",            "_constructor",                                 OT_CTOR                         },
     24                        {       "^?{}",         "",             "_destructor",                                  OT_DTOR                         },
    2325                        {       "?()",          "",             "_operator_call",                               OT_CALL                         },
    2426                        {       "?++",          "++",   "_operator_postincr",                   OT_POSTFIXASSIGN        },
  • src/CodeGen/OperatorTable.h

    r9243a501 r7cc6bd6  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jun 23 16:09:27 2015
    13 // Update Count     : 3
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Jun 24 16:17:57 2015
     13// Update Count     : 5
    1414//
    1515
     
    2222        enum OperatorType {
    2323                OT_INDEX,
     24                OT_CTOR,
     25                OT_DTOR,
    2426                OT_CALL,
    2527                OT_PREFIX,
  • src/GenPoly/Box.cc

    r9243a501 r7cc6bd6  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb  5 16:45:07 2016
    13 // Update Count     : 286
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue May 03 16:44:47 2016
     13// Update Count     : 295
    1414//
    1515
     
    133133                        Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const {
    134134                                TypeList typeList( params );
    135                                
     135
    136136                                // scan scopes for matches to the key
    137137                                for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) {
     
    160160                        virtual Declaration *mutate( UnionDecl *unionDecl );
    161161                };
    162                
     162
    163163                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    164164                class Pass1 : public PolyMutator {
     
    208208                        ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;  ///< Currently known assignment operators
    209209                        ScopedMap< std::string, DeclarationWithType* > adapters;     ///< Set of adapter functions in the current scope
    210                        
     210
    211211                        DeclarationWithType *retval;
    212212                        bool useRetval;
     
    226226                        virtual Type *mutate( PointerType *pointerType );
    227227                        virtual Type *mutate( FunctionType *funcType );
    228                        
     228
    229229                  private:
    230230                        void addAdapters( FunctionType *functionType );
     
    297297                        /// Exits the type-variable scope
    298298                        void endTypeScope();
    299                        
     299
    300300                        ScopedSet< std::string > knownLayouts;          ///< Set of generic type layouts known in the current scope, indexed by sizeofName
    301301                        ScopedSet< std::string > knownOffsets;          ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName
     
    351351                PolyGenericCalculator polyCalculator;
    352352                Pass3 pass3;
    353                
     353
    354354                layoutBuilder.mutateDeclarationList( translationUnit );
    355355                mutateTranslationUnit/*All*/( translationUnit, pass1 );
     
    370370                return functionDecl;
    371371        }
    372        
     372
    373373        /// Get a list of type declarations that will affect a layout function
    374374        std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
     
    380380                        }
    381381                }
    382                
     382
    383383                return otypeDecls;
    384384        }
     
    387387        void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {
    388388                BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    389                
     389
    390390                for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    391391                        TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
     
    444444                return makeCond( ifCond, ifExpr );
    445445        }
    446        
     446
    447447        /// adds an expression to a compound statement
    448448        void addExpr( CompoundStmt *stmts, Expression *expr ) {
     
    454454                stmts->get_kids().push_back( stmt );
    455455        }
    456        
     456
    457457        Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
    458458                // do not generate layout function for "empty" tag structs
     
    467467                BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    468468                PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    469                
     469
    470470                ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    471471                layoutFnType->get_parameters().push_back( sizeParam );
     
    497497                                addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
    498498                        }
    499                        
     499
    500500                        // place current size in the current offset index
    501501                        addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ),
     
    505505                        // add member size to current size
    506506                        addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    507                        
     507
    508508                        // take max of member alignment and global alignment
    509509                        addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
     
    515515                return structDecl;
    516516        }
    517        
     517
    518518        Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
    519519                // do not generate layout function for "empty" tag unions
    520520                if ( unionDecl->get_members().empty() ) return unionDecl;
    521                
     521
    522522                // get parameters that can change layout, exiting early if none
    523523                std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
     
    528528                BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    529529                PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    530                
     530
    531531                ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    532532                layoutFnType->get_parameters().push_back( sizeParam );
     
    545545                        assert( dwt );
    546546                        Type *memberType = dwt->get_type();
    547                        
     547
    548548                        // take max member size and global size
    549549                        addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    550                        
     550
    551551                        // take max of member alignment and global alignment
    552552                        addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
     
    558558                return unionDecl;
    559559        }
    560        
     560
    561561        ////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
    562562
     
    619619                        return 0;
    620620                }
    621                
     621
    622622                /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise
    623623                /// Only picks assignments where neither parameter is cv-qualified
     
    631631                                                Type *paramType2 = funType->get_parameters().back()->get_type();
    632632                                                if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0;
    633                                                
     633
    634634                                                if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) {
    635635                                                        Type *baseType1 = pointerType->get_base();
     
    784784                                                arg++;
    785785                                        } else {
    786                                                 throw SemanticError( "unbound type variable in application ", appExpr );
     786                                                /// xxx - should this be an assertion?
     787                                                throw SemanticError( "unbound type variable: " + tyParm->first + " in application ", appExpr );
    787788                                        } // if
    788789                                } // if
     
    803804                                passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes );
    804805                        }
    805                        
     806
    806807                        // add type information args for presently unseen types in parameter list
    807808                        for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) {
     
    882883                        assert( env );
    883884                        Type *concrete = replaceWithConcrete( appExpr, polyType );
    884                         // add out-parameter for return value   
     885                        // add out-parameter for return value
    885886                        return addRetParam( appExpr, function, concrete, arg );
    886887                }
     
    910911                                } else if ( arg->get_results().front()->get_isLvalue() ) {
    911912                                        // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
     913                                        // xxx - need to test that this code is still reachable
    912914                                        if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) {
    913915                                                commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) );
     
    12911293                        } else if ( needsAdapter( function, scopeTyVars ) ) {
    12921294                                // std::cerr << "needs adapter: ";
    1293                                 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) {
    1294                                 //      std::cerr << i->first << " ";
    1295                                 // }
    1296                                 // std::cerr << "\n";
     1295                                // printTyVarMap( std::cerr, scopeTyVars );
     1296                                // std::cerr << *env << std::endl;
    12971297                                // change the application so it calls the adapter rather than the passed function
    12981298                                ret = applyAdapter( appExpr, function, arg, scopeTyVars );
     
    13451345                                } // if
    13461346                        } // if
     1347                        // isPolyType check needs to happen before mutating addrExpr arg, so pull it forward
     1348                        // out of the if condition.
     1349                        bool polytype = isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env );
    13471350                        addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    1348                         if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env ) || needs ) {
     1351                        if ( polytype || needs ) {
    13491352                                Expression *ret = addrExpr->get_arg();
    13501353                                delete ret->get_results().front();
     
    13661369                        return new VariableExpr( functionObj );
    13671370                }
    1368                
     1371
    13691372                Statement * Pass1::mutate( ReturnStmt *returnStmt ) {
    13701373                        if ( retval && returnStmt->get_expr() ) {
     
    18861889                                }
    18871890                        }
    1888                        
     1891
    18891892                        Type *ret = Mutator::mutate( funcType );
    18901893
     
    19051908
    19061909                                        std::list<Expression*> designators;
    1907                                         objectDecl->set_init( new SingleInit( alloc, designators ) );
     1910                                        objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed
    19081911                                }
    19091912                        }
     
    19461949                        return derefdVar;
    19471950                }
    1948                
     1951
    19491952                Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) {
    19501953                        // mutate, exiting early if no longer MemberExpr
     
    21442147                        Type *ty = offsetofExpr->get_type();
    21452148                        if ( ! findGeneric( ty ) ) return offsetofExpr;
    2146                        
     2149
    21472150                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
    21482151                                // replace offsetof expression by index into offset array
  • src/GenPoly/CopyParams.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // CopyParams.cc -- 
     7// CopyParams.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
     11// Last Modified By : Rob Schluntz
    1212// Last Modified On : Tue May 19 07:33:31 2015
    1313// Update Count     : 1
     
    2929          public:
    3030                CopyParams();
    31  
     31
    3232                virtual void visit( FunctionDecl *funcDecl );
    3333                virtual void visit( AddressExpr *addrExpr );
     
    5050                if ( funcDecl->get_statements() ) {
    5151                        funcDecl->get_statements()->accept( *this );
    52        
     52
    5353                        if ( ! modVars.empty() ) {
    5454                                std::map< std::string, DeclarationWithType* > assignOps;
     
    5757                                        if ( (*tyVar)->get_kind() == TypeDecl::Any ) {
    5858                                                assert( !(*tyVar)->get_assertions().empty() );
     59                                                assert( (*tyVar)->get_assertions().front()->get_name() == "?=?" );
    5960                                                assignOps[ (*tyVar)->get_name() ] = (*tyVar)->get_assertions().front();
    6061                                        } // if
  • src/GenPoly/GenPoly.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // GenPoly.cc -- 
     7// GenPoly.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec 15 16:11:18 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon May 02 14:53:33 2016
    1313// Update Count     : 13
    1414//
     
    8181                return 0;
    8282        }
    83        
     83
    8484        Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
    8585                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) {
     
    112112                return 0;
    113113        }
    114        
     114
    115115        Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) {
    116116                if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) {
     
    146146                return isPolyType( type, env );
    147147        }
    148        
     148
    149149        Type * hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels, const TypeSubstitution *env ) {
    150150                int dummy;
     
    192192                                if ( ! fn || fn->get_name() != std::string("*?") ) return 0;
    193193                                expr = *untypedExpr->begin_args();
     194                        } else if ( CommaExpr *commaExpr = dynamic_cast< CommaExpr* >( expr ) ) {
     195                                // copy constructors insert comma exprs, look at second argument which contains the variable
     196                                expr = commaExpr->get_arg2();
     197                                continue;
    194198                        } else break;
    195199
     
    209213                }
    210214        }
    211        
     215
    212216        void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) {
    213217                for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
  • src/GenPoly/PolyMutator.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // PolyMutator.cc -- 
     7// PolyMutator.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri Aug 14 15:28:50 2015
     12// Last Modified On : Mon May 02 14:50:58 2016
    1313// Update Count     : 11
    1414//
     
    6363                                env = expr->get_env();
    6464                        }
     65                        // xxx - should env be cloned (or moved) onto the result of the mutate?
    6566                        return expr->acceptMutator( *this );
    6667                } else {
     
    144145                return untypedExpr;
    145146        }
    146  
    147  
     147
     148
    148149        Initializer *PolyMutator::mutate( SingleInit *singleInit ) {
    149150                singleInit->set_value( mutateExpression( singleInit->get_value() ) );
  • src/GenPoly/Specialize.cc

    r9243a501 r7cc6bd6  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Jan 20 12:40:33 2016
    13 // Update Count     : 18
     12// Last Modified On : Thu Apr 28 15:17:45 2016
     13// Update Count     : 24
    1414//
    1515
     
    4141                virtual Expression * mutate( AddressExpr *castExpr );
    4242                virtual Expression * mutate( CastExpr *castExpr );
    43                 virtual Expression * mutate( LogicalExpr *logicalExpr );
    44                 virtual Expression * mutate( ConditionalExpr *conditionalExpr );
    45                 virtual Expression * mutate( CommaExpr *commaExpr );
     43                // virtual Expression * mutate( LogicalExpr *logicalExpr );
     44                // virtual Expression * mutate( ConditionalExpr *conditionalExpr );
     45                // virtual Expression * mutate( CommaExpr *commaExpr );
    4646
    4747          private:
     
    142142
    143143        Expression * Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams ) {
    144                 assert( ! actual->get_results().empty() );
     144                assert( ! actual->get_results().empty() ); // using front, should have this assert
    145145                if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) {
    146146                        FunctionType *funType;
     
    212212        }
    213213
    214         Expression * Specialize::mutate( LogicalExpr *logicalExpr ) {
    215                 return logicalExpr;
    216         }
    217 
    218         Expression * Specialize::mutate( ConditionalExpr *condExpr ) {
    219                 return condExpr;
    220         }
    221 
    222         Expression * Specialize::mutate( CommaExpr *commaExpr ) {
    223                 return commaExpr;
    224         }
     214        // Removing these for now. Richard put these in for some reason, but it's not clear why.
     215        // In particular, copy constructors produce a comma expression, and with this code the parts
     216        // of that comma expression are not specialized, which causes problems.
     217
     218        // Expression * Specialize::mutate( LogicalExpr *logicalExpr ) {
     219        //      return logicalExpr;
     220        // }
     221
     222        // Expression * Specialize::mutate( ConditionalExpr *condExpr ) {
     223        //      return condExpr;
     224        // }
     225
     226        // Expression * Specialize::mutate( CommaExpr *commaExpr ) {
     227        //      return commaExpr;
     228        // }
    225229} // namespace GenPoly
    226230
  • src/InitTweak/InitModel.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // InitModel.cc -- 
     7// InitModel.cc --
    88//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 16:37:08 2015
    13 // Update Count     : 1
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Jan 07 13:38:46 2016
     13// Update Count     : 5
    1414//
    1515
     
    198198                assert(init == 0 && single != 0);
    199199                std::list< Expression * > empty;
    200                 init = new SingleInit( single->get_expr(), empty );
     200                init = new SingleInit( single->get_expr(), empty, false ); // cannot be constructed
    201201                return;
    202202        }
     
    214214                        } // if
    215215
    216                 init = new ListInit( contents );
     216                std::list< Expression * > desig;
     217                init = new ListInit( contents, desig, false ); // cannot be constructed
    217218                return;
    218219        }
  • src/InitTweak/module.mk

    r9243a501 r7cc6bd6  
    1111## Created On       : Mon Jun  1 17:49:17 2015
    1212## Last Modified By : Rob Schluntz
    13 ## Last Modified On : Mon Jan 11 14:40:16 2016
    14 ## Update Count     : 2
     13## Last Modified On : Thu Apr 28 12:23:17 2016
     14## Update Count     : 3
    1515###############################################################################
    1616
    17 SRC += InitTweak/RemoveInit.cc
    18 
     17SRC += InitTweak/GenInit.cc \
     18        InitTweak/FixInit.cc
  • src/MakeLibCfa.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // MakeLibCfa.cc -- 
     7// MakeLibCfa.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 10:33:33 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jun 26 16:52:59 2015
    13 // Update Count     : 14
    14 // 
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri Apr 22 13:54:15 2016
     13// Update Count     : 40
     14//
    1515
    1616#include "MakeLibCfa.h"
     
    2929                void visit( FunctionDecl* funcDecl );
    3030                void visit( ObjectDecl* objDecl );
    31  
     31
    3232                std::list< Declaration* > &get_newDecls() { return newDecls; }
    3333          private:
     
    4343        void MakeLibCfa::visit( FunctionDecl* origFuncDecl ) {
    4444                if ( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
    45  
     45                if ( origFuncDecl->get_statements() ) return;
     46
    4647                FunctionDecl *funcDecl = origFuncDecl->clone();
    4748                CodeGen::OperatorInfo opInfo;
     
    5455                assert( param != funcDecl->get_functionType()->get_parameters().end() );
    5556
    56                 if ( (*param)->get_name() == "" ) {
    57                         (*param)->set_name( paramNamer.newName() );
    58                         (*param)->set_linkage( LinkageSpec::C );
    59                 } // if
     57                for ( ; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
     58                        if ( (*param)->get_name() == "" ) {
     59                                (*param)->set_name( paramNamer.newName() );
     60                                (*param)->set_linkage( LinkageSpec::C );
     61                        }
     62                        newExpr->get_args().push_back( new VariableExpr( *param ) );
     63                } // for
     64
     65                funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
     66                newDecls.push_back( funcDecl );
    6067
    6168                switch ( opInfo.type ) {
     
    6572                  case CodeGen::OT_POSTFIX:
    6673                  case CodeGen::OT_INFIX:
    67                         newExpr->get_args().push_back( new VariableExpr( *param ) );
    68                         break;
    6974                  case CodeGen::OT_PREFIXASSIGN:
    7075                  case CodeGen::OT_POSTFIXASSIGN:
    7176                  case CodeGen::OT_INFIXASSIGN:
    72                         {
    73                                 newExpr->get_args().push_back( new VariableExpr( *param ) );
    74                                 // UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    75                                 // deref->get_args().push_back( new VariableExpr( *param ) );
    76                                 // newExpr->get_args().push_back( deref );
     77                                funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
    7778                                break;
    78                         }
     79                  case CodeGen::OT_CTOR:
     80                        // ctors don't return a value
     81                        if ( funcDecl->get_functionType()->get_parameters().size() == 1 ) {
     82                                // intrinsic default constructors should do nothing
     83                                // delete newExpr;
     84                                break;
     85                        } else {
     86                                assert( funcDecl->get_functionType()->get_parameters().size() == 2 );
     87                                // anything else is a single parameter constructor that is effectively a C-style assignment
     88                                // delete newExpr->get_function();
     89                                assert(newExpr->get_args().size()==2);
     90                                newExpr->set_function( new NameExpr( "?=?" ) );
     91                                funcDecl->get_statements()->get_kids().push_back( new ExprStmt( std::list< Label >(), newExpr ) );
     92                        }
     93                        break;
     94                  case CodeGen::OT_DTOR:
     95                        // intrinsic destructors should do nothing
     96                        // delete newExpr;
     97                        break;
    7998                  case CodeGen::OT_CONSTANT:
    8099                  case CodeGen::OT_LABELADDRESS:
     
    82101                        assert( false );
    83102                } // switch
    84 
    85                 for ( param++; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
    86                         if ( (*param)->get_name() == "" ) {
    87                                 (*param)->set_name( paramNamer.newName() );
    88                                 (*param)->set_linkage( LinkageSpec::C );
    89                         }
    90                         newExpr->get_args().push_back( new VariableExpr( *param ) );
    91                 } // for
    92                 funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) );
    93                 funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) );
    94                 newDecls.push_back( funcDecl );
    95103        }
    96104
    97105        void MakeLibCfa::visit( ObjectDecl* origObjDecl ) {
    98106                if ( origObjDecl->get_linkage() != LinkageSpec::Intrinsic ) return;
    99  
     107
    100108                ObjectDecl *objDecl = origObjDecl->clone();
    101109                assert( ! objDecl->get_init() );
    102110                std::list< Expression* > noDesignators;
    103                 objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators ) );
     111                objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators, false ) ); // cannot be constructed
    104112                newDecls.push_back( objDecl );
    105113        }
    106114} // namespace LibCfa
    107 
    108 // Local Variables: //
    109 // tab-width: 4 //
    110 // mode: c++ //
    111 // compile-command: "make install" //
    112 // End: //
  • src/Makefile.in

    r9243a501 r7cc6bd6  
    123123        GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \
    124124        GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \
    125         InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT) \
     125        InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT) \
     126        InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT) \
    126127        Parser/driver_cfa_cpp-parser.$(OBJEXT) \
    127128        Parser/driver_cfa_cpp-lex.$(OBJEXT) \
     
    159160        SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT) \
    160161        SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT) \
     162        SymTab/driver_cfa_cpp-Autogen.$(OBJEXT) \
    161163        SynTree/driver_cfa_cpp-Type.$(OBJEXT) \
    162164        SynTree/driver_cfa_cpp-VoidType.$(OBJEXT) \
     
    345347        GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
    346348        GenPoly/CopyParams.cc GenPoly/FindFunction.cc \
    347         GenPoly/DeclMutator.cc InitTweak/RemoveInit.cc \
    348         Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \
    349         Parser/ParseNode.cc Parser/DeclarationNode.cc \
    350         Parser/ExpressionNode.cc Parser/StatementNode.cc \
    351         Parser/InitializerNode.cc Parser/TypeData.cc \
    352         Parser/LinkageSpec.cc Parser/parseutility.cc Parser/Parser.cc \
     349        GenPoly/DeclMutator.cc InitTweak/GenInit.cc \
     350        InitTweak/FixInit.cc Parser/parser.yy Parser/lex.ll \
     351        Parser/TypedefTable.cc Parser/ParseNode.cc \
     352        Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
     353        Parser/StatementNode.cc Parser/InitializerNode.cc \
     354        Parser/TypeData.cc Parser/LinkageSpec.cc \
     355        Parser/parseutility.cc Parser/Parser.cc \
    353356        ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \
    354357        ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \
     
    362365        SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \
    363366        SymTab/ImplementationType.cc SymTab/TypeEquality.cc \
    364         SynTree/Type.cc SynTree/VoidType.cc SynTree/BasicType.cc \
    365         SynTree/PointerType.cc SynTree/ArrayType.cc \
    366         SynTree/FunctionType.cc SynTree/ReferenceToType.cc \
    367         SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \
     367        SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \
     368        SynTree/BasicType.cc SynTree/PointerType.cc \
     369        SynTree/ArrayType.cc SynTree/FunctionType.cc \
     370        SynTree/ReferenceToType.cc SynTree/TupleType.cc \
     371        SynTree/TypeofType.cc SynTree/AttrType.cc \
    368372        SynTree/VarArgsType.cc SynTree/Constant.cc \
    369373        SynTree/Expression.cc SynTree/TupleExpr.cc \
     
    561565        @$(MKDIR_P) InitTweak/$(DEPDIR)
    562566        @: > InitTweak/$(DEPDIR)/$(am__dirstamp)
    563 InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT):  \
    564         InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)
     567InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
     568        InitTweak/$(DEPDIR)/$(am__dirstamp)
     569InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
     570        InitTweak/$(DEPDIR)/$(am__dirstamp)
    565571Parser/parser.h: Parser/parser.cc
    566572        @if test ! -f $@; then rm -f Parser/parser.cc; else :; fi
     
    670676SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT): SymTab/$(am__dirstamp) \
    671677        SymTab/$(DEPDIR)/$(am__dirstamp)
     678SymTab/driver_cfa_cpp-Autogen.$(OBJEXT): SymTab/$(am__dirstamp) \
     679        SymTab/$(DEPDIR)/$(am__dirstamp)
    672680SynTree/$(am__dirstamp):
    673681        @$(MKDIR_P) SynTree
     
    792800        -rm -f GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT)
    793801        -rm -f GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT)
    794         -rm -f InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT)
     802        -rm -f InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT)
     803        -rm -f InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT)
    795804        -rm -f Parser/driver_cfa_cpp-DeclarationNode.$(OBJEXT)
    796805        -rm -f Parser/driver_cfa_cpp-ExpressionNode.$(OBJEXT)
     
    822831        -rm -f ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT)
    823832        -rm -f ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT)
     833        -rm -f SymTab/driver_cfa_cpp-Autogen.$(OBJEXT)
    824834        -rm -f SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT)
    825835        -rm -f SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT)
     
    897907@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@
    898908@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Specialize.Po@am__quote@
    899 @AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-RemoveInit.Po@am__quote@
     909@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po@am__quote@
     910@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po@am__quote@
    900911@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po@am__quote@
    901912@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Po@am__quote@
     
    927938@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Po@am__quote@
    928939@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po@am__quote@
     940@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po@am__quote@
    929941@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po@am__quote@
    930942@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po@am__quote@
     
    13661378@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-DeclMutator.obj `if test -f 'GenPoly/DeclMutator.cc'; then $(CYGPATH_W) 'GenPoly/DeclMutator.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/DeclMutator.cc'; fi`
    13671379
    1368 InitTweak/driver_cfa_cpp-RemoveInit.o: InitTweak/RemoveInit.cc
    1369 @am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-RemoveInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-RemoveInit.Tpo -c -o InitTweak/driver_cfa_cpp-RemoveInit.o `test -f 'InitTweak/RemoveInit.cc' || echo '$(srcdir)/'`InitTweak/RemoveInit.cc
    1370 @am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-RemoveInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-RemoveInit.Po
    1371 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/RemoveInit.cc' object='InitTweak/driver_cfa_cpp-RemoveInit.o' libtool=no @AMDEPBACKSLASH@
    1372 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1373 @am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-RemoveInit.o `test -f 'InitTweak/RemoveInit.cc' || echo '$(srcdir)/'`InitTweak/RemoveInit.cc
    1374 
    1375 InitTweak/driver_cfa_cpp-RemoveInit.obj: InitTweak/RemoveInit.cc
    1376 @am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-RemoveInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-RemoveInit.Tpo -c -o InitTweak/driver_cfa_cpp-RemoveInit.obj `if test -f 'InitTweak/RemoveInit.cc'; then $(CYGPATH_W) 'InitTweak/RemoveInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/RemoveInit.cc'; fi`
    1377 @am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-RemoveInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-RemoveInit.Po
    1378 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/RemoveInit.cc' object='InitTweak/driver_cfa_cpp-RemoveInit.obj' libtool=no @AMDEPBACKSLASH@
    1379 @AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    1380 @am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-RemoveInit.obj `if test -f 'InitTweak/RemoveInit.cc'; then $(CYGPATH_W) 'InitTweak/RemoveInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/RemoveInit.cc'; fi`
     1380InitTweak/driver_cfa_cpp-GenInit.o: InitTweak/GenInit.cc
     1381@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-GenInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo -c -o InitTweak/driver_cfa_cpp-GenInit.o `test -f 'InitTweak/GenInit.cc' || echo '$(srcdir)/'`InitTweak/GenInit.cc
     1382@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po
     1383@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/GenInit.cc' object='InitTweak/driver_cfa_cpp-GenInit.o' libtool=no @AMDEPBACKSLASH@
     1384@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1385@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-GenInit.o `test -f 'InitTweak/GenInit.cc' || echo '$(srcdir)/'`InitTweak/GenInit.cc
     1386
     1387InitTweak/driver_cfa_cpp-GenInit.obj: InitTweak/GenInit.cc
     1388@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-GenInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo -c -o InitTweak/driver_cfa_cpp-GenInit.obj `if test -f 'InitTweak/GenInit.cc'; then $(CYGPATH_W) 'InitTweak/GenInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/GenInit.cc'; fi`
     1389@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po
     1390@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/GenInit.cc' object='InitTweak/driver_cfa_cpp-GenInit.obj' libtool=no @AMDEPBACKSLASH@
     1391@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1392@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-GenInit.obj `if test -f 'InitTweak/GenInit.cc'; then $(CYGPATH_W) 'InitTweak/GenInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/GenInit.cc'; fi`
     1393
     1394InitTweak/driver_cfa_cpp-FixInit.o: InitTweak/FixInit.cc
     1395@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixInit.o `test -f 'InitTweak/FixInit.cc' || echo '$(srcdir)/'`InitTweak/FixInit.cc
     1396@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po
     1397@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.o' libtool=no @AMDEPBACKSLASH@
     1398@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1399@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixInit.o `test -f 'InitTweak/FixInit.cc' || echo '$(srcdir)/'`InitTweak/FixInit.cc
     1400
     1401InitTweak/driver_cfa_cpp-FixInit.obj: InitTweak/FixInit.cc
     1402@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixInit.obj `if test -f 'InitTweak/FixInit.cc'; then $(CYGPATH_W) 'InitTweak/FixInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixInit.cc'; fi`
     1403@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po
     1404@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.obj' libtool=no @AMDEPBACKSLASH@
     1405@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1406@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixInit.obj `if test -f 'InitTweak/FixInit.cc'; then $(CYGPATH_W) 'InitTweak/FixInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixInit.cc'; fi`
    13811407
    13821408Parser/driver_cfa_cpp-parser.o: Parser/parser.cc
     
    18691895@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    18701896@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-TypeEquality.obj `if test -f 'SymTab/TypeEquality.cc'; then $(CYGPATH_W) 'SymTab/TypeEquality.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/TypeEquality.cc'; fi`
     1897
     1898SymTab/driver_cfa_cpp-Autogen.o: SymTab/Autogen.cc
     1899@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Autogen.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo -c -o SymTab/driver_cfa_cpp-Autogen.o `test -f 'SymTab/Autogen.cc' || echo '$(srcdir)/'`SymTab/Autogen.cc
     1900@am__fastdepCXX_TRUE@   $(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po
     1901@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='SymTab/Autogen.cc' object='SymTab/driver_cfa_cpp-Autogen.o' libtool=no @AMDEPBACKSLASH@
     1902@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1903@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Autogen.o `test -f 'SymTab/Autogen.cc' || echo '$(srcdir)/'`SymTab/Autogen.cc
     1904
     1905SymTab/driver_cfa_cpp-Autogen.obj: SymTab/Autogen.cc
     1906@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-Autogen.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo -c -o SymTab/driver_cfa_cpp-Autogen.obj `if test -f 'SymTab/Autogen.cc'; then $(CYGPATH_W) 'SymTab/Autogen.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Autogen.cc'; fi`
     1907@am__fastdepCXX_TRUE@   $(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po
     1908@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='SymTab/Autogen.cc' object='SymTab/driver_cfa_cpp-Autogen.obj' libtool=no @AMDEPBACKSLASH@
     1909@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1910@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-Autogen.obj `if test -f 'SymTab/Autogen.cc'; then $(CYGPATH_W) 'SymTab/Autogen.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/Autogen.cc'; fi`
    18711911
    18721912SynTree/driver_cfa_cpp-Type.o: SynTree/Type.cc
  • src/Parser/DeclarationNode.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // DeclarationNode.cc -- 
     7// DeclarationNode.cc --
    88//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 12:34:05 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr 13 16:53:17 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:38:09 2016
    1313// Update Count     : 161
    1414//
     
    9797                os << endl << string( indent + 2, ' ' ) << "with initializer ";
    9898                initializer->printOneLine( os );
     99                os << " maybe constructed? " << initializer->get_maybeConstructed();
     100
    99101        } // if
    100102
     
    353355        } // if
    354356}
    355          
     357
    356358DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) {
    357359        if ( q ) {
     
    504506                assert( false );
    505507        } // switch
    506        
     508
    507509        return this;
    508510}
     
    615617                assert( a->type->kind == TypeData::Array );
    616618                TypeData *lastArray = findLast( a->type );
    617                 if ( type ) { 
     619                if ( type ) {
    618620                        switch ( type->kind ) {
    619621                          case TypeData::Aggregate:
     
    659661        } // if
    660662}
    661        
     663
    662664DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) {
    663665        type = addIdListToType( type, ids );
     
    864866Type *DeclarationNode::buildType() const {
    865867        assert( type );
    866  
     868
    867869        switch ( type->kind ) {
    868870          case TypeData::Enum:
  • src/Parser/InitializerNode.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // InitializerNode.cc -- 
    8 // 
     7// InitializerNode.cc --
     8//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:20:24 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Oct  8 17:18:55 2015
    13 // Update Count     : 4
    14 // 
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Jan 07 13:32:57 2016
     13// Update Count     : 13
     14//
    1515
    1616#include <cassert>
     
    2323
    2424InitializerNode::InitializerNode( ExpressionNode *_expr, bool aggrp, ExpressionNode *des )
    25         : expr( _expr ), aggregate( aggrp ), designator( des ), kids( 0 ) {
     25        : expr( _expr ), aggregate( aggrp ), designator( des ), kids( 0 ), maybeConstructed( true ) {
    2626        if ( aggrp )
    2727                kids = dynamic_cast< InitializerNode *>( get_link() );
     
    3232
    3333InitializerNode::InitializerNode( InitializerNode *init, bool aggrp, ExpressionNode *des )
    34         : expr( 0 ), aggregate( aggrp ), designator( des ), kids( 0 ) {
     34        : expr( 0 ), aggregate( aggrp ), designator( des ), kids( 0 ), maybeConstructed( true ) {
    3535        if ( init != 0 )
    3636                set_link(init);
     
    9191                } // if
    9292
    93                 return new ListInit( initlist, designlist );
     93                return new ListInit( initlist, designlist, maybeConstructed );
    9494        } else {
    9595                std::list< Expression *> designators;
     
    9999
    100100                if ( get_expression() != 0)
    101                         return new SingleInit( get_expression()->build(), designators );
     101                        return new SingleInit( get_expression()->build(), designators, maybeConstructed );
    102102        } // if
    103103
  • src/Parser/ParseNode.h

    r9243a501 r7cc6bd6  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon Apr 11 11:50:52 2016
     12// Last Modified On : Thu Apr 14 15:37:52 2016
    1313// Update Count     : 205
    1414//
     
    185185                                // monadic
    186186                                UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress,
     187                                Ctor, Dtor,
    187188        };
    188189
     
    525526        ExpressionNode *get_designators() const { return designator; }
    526527
     528        InitializerNode *set_maybeConstructed( bool value ) { maybeConstructed = value; return this; }
     529        bool get_maybeConstructed() const { return maybeConstructed; }
     530
    527531        InitializerNode *next_init() const { return kids; }
    528532
     
    536540        ExpressionNode *designator; // may be list
    537541        InitializerNode *kids;
     542        bool maybeConstructed;
    538543};
    539544
  • src/Parser/TypeData.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TypeData.cc -- 
     7// TypeData.cc --
    88//
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:12:51 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:26:45 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 06 16:57:53 2016
    1313// Update Count     : 49
    1414//
     
    449449        for ( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) {
    450450                if ( (*i)->get_kind() == TypeDecl::Any ) {
     451                        // add assertion parameters to `type' tyvars in reverse order
     452                        // add dtor:  void ^?{}(T *)
     453                        FunctionType *dtorType = new FunctionType( Type::Qualifiers(), false );
     454                        dtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
     455                        (*i)->get_assertions().push_front( new FunctionDecl( "^?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, dtorType, 0, false, false ) );
     456
     457                        // add copy ctor:  void ?{}(T *, T)
     458                        FunctionType *copyCtorType = new FunctionType( Type::Qualifiers(), false );
     459                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
     460                        copyCtorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ), 0 ) );
     461                        (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, copyCtorType, 0, false, false ) );
     462
     463                        // add default ctor:  void ?{}(T *)
     464                        FunctionType *ctorType = new FunctionType( Type::Qualifiers(), false );
     465                        ctorType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
     466                        (*i)->get_assertions().push_front( new FunctionDecl( "?{}", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, ctorType, 0, false, false ) );
     467
     468                        // add assignment operator:  T * ?=?(T *, T)
    451469                        FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    452470                        assignType->get_parameters().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), (*i)->get_name(), *i ) ), 0 ) );
     
    902920                if ( cur->get_enumeratorValue() != NULL ) {
    903921                        ObjectDecl *member = dynamic_cast<ObjectDecl *>(*members);
    904                         member->set_init( new SingleInit( maybeBuild< Expression >( cur->get_enumeratorValue() ) ) );
     922                        member->set_init( new SingleInit( maybeBuild< Expression >( cur->get_enumeratorValue() ), std::list< Expression * >() ) );
    905923                } // if
    906924        } // for
  • src/Parser/parser.cc

    r9243a501 r7cc6bd6  
    74687468/* Line 1806 of yacc.c  */
    74697469#line 1704 "parser.yy"
    7470     { (yyval.in) = (yyvsp[(2) - (2)].in); }
     7470    { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); }
    74717471    break;
    74727472
  • src/Parser/parser.yy

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // cfa.y -- 
    8 // 
     7// cfa.y --
     8//
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep  1 20:22:55 2001
     
    1212// Last Modified On : Wed Apr 13 16:58:43 2016
    1313// Update Count     : 1519
    14 // 
     14//
    1515
    1616// This grammar is based on the ANSI99/11 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on the C
     
    17021702                { $$ = $2; }
    17031703        | ATassign initializer
    1704                 { $$ = $2; }
     1704                { $$ = $2->set_maybeConstructed( false ); }
    17051705        ;
    17061706
  • src/ResolvExpr/AlternativeFinder.cc

    r9243a501 r7cc6bd6  
    1010// Created On       : Sat May 16 23:52:08 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Feb 10 17:00:04 2016
     12// Last Modified On : Wed Apr 20 14:24:03 2016
    1313// Update Count     : 24
    1414//
     
    982982                } // for
    983983        }
     984
     985        void AlternativeFinder::visit( ImplicitCopyCtorExpr * impCpCtorExpr ) {
     986                alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) );
     987        }
    984988} // namespace ResolvExpr
    985989
  • src/ResolvExpr/AlternativeFinder.h

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AlternativeFinder.h -- 
     7// AlternativeFinder.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sat May 16 23:56:12 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat May 16 23:58:43 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Apr 19 11:44:53 2016
    1313// Update Count     : 2
    14 // 
     14//
    1515
    1616#ifndef ALTERNATIVEFINDER_H
     
    5454                virtual void visit( NameExpr *variableExpr );
    5555                virtual void visit( VariableExpr *variableExpr );
    56                 virtual void visit( ConstantExpr *constantExpr ); 
     56                virtual void visit( ConstantExpr *constantExpr );
    5757                virtual void visit( SizeofExpr *sizeofExpr );
    5858                virtual void visit( AlignofExpr *alignofExpr );
     
    6565                virtual void visit( CommaExpr *commaExpr );
    6666                virtual void visit( TupleExpr *tupleExpr );
     67                virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr );
    6768          public:  // xxx - temporary hack - should make Tuples::TupleAssignment a friend
    6869                template< typename InputIterator, typename OutputIterator >
  • src/ResolvExpr/Resolver.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Resolver.cc -- 
     7// Resolver.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:17:01 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 24 16:43:11 2016
    13 // Update Count     : 181
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Apr 26 16:08:21 2016
     13// Update Count     : 203
    1414//
    1515
     
    3333          public:
    3434                Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
    35  
     35
    3636                virtual void visit( FunctionDecl *functionDecl );
    3737                virtual void visit( ObjectDecl *functionDecl );
     
    5454                virtual void visit( SingleInit *singleInit );
    5555                virtual void visit( ListInit *listInit );
     56                virtual void visit( ConstructorInit *ctorInit );
    5657          private:
    5758        typedef std::list< Initializer * >::iterator InitIterator;
     
    5960          void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & );
    6061          void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
    61 
     62          void fallbackInit( ConstructorInit * ctorInit );
    6263                std::list< Type * > functionReturn;
    6364                Type *initContext;
     
    8283        }
    8384
     85
    8486        namespace {
    8587                void finishExpr( Expression *expr, const TypeEnvironment &env ) {
     
    8789                        env.makeSubstitution( *expr->get_env() );
    8890                }
    89 
    90                 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    91                         global_renamer.reset();
    92                         TypeEnvironment env;
    93                         Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
    94                         finishExpr( newExpr, env );
    95                         return newExpr;
    96                 }
    97  
     91        } // namespace
     92
     93        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     94                global_renamer.reset();
     95                TypeEnvironment env;
     96                Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
     97                finishExpr( newExpr, env );
     98                return newExpr;
     99        }
     100
     101        namespace {
    98102                Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    99103                        TypeEnvironment env;
     
    126130                        } // if
    127131                }
    128  
     132
    129133                Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    130134                        TypeEnvironment env;
     
    159163                        return newExpr;
    160164                }
    161  
    162         }
    163  
     165
     166        }
     167
    164168        void Resolver::visit( ObjectDecl *objectDecl ) {
    165169                Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
     
    258262                        forStmt->set_condition( newExpr );
    259263                } // if
    260                
     264
    261265                if ( forStmt->get_increment() ) {
    262266                        Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
     
    272276                delete switchStmt->get_condition();
    273277                switchStmt->set_condition( newExpr );
    274  
     278
    275279                visitor.Visitor::visit( switchStmt );
    276280        }
     
    314318        bool isCharType( T t ) {
    315319                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
    316                         return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || 
     320                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
    317321                                bt->get_kind() == BasicType::UnsignedChar;
    318322                }
     
    326330                                string n = ne->get_name();
    327331                                if (n == "0") {
    328                                         initContext = new BasicType(Type::Qualifiers(), 
     332                                        initContext = new BasicType(Type::Qualifiers(),
    329333                                                                                                BasicType::SignedInt);
    330334                                } else {
     
    332336                                        initContext = decl->get_type();
    333337                                }
    334                         } else if (ConstantExpr * e = 
     338                        } else if (ConstantExpr * e =
    335339                                           dynamic_cast<ConstantExpr*>(singleInit->get_value())) {
    336340                                Constant *c = e->get_constant();
     
    355359                                                        singleInit->set_value( ce->get_arg() );
    356360                                                        ce->set_arg( NULL );
    357                                                         delete ce;                                                                     
     361                                                        delete ce;
    358362                                                }
    359363                                        }
     
    471475#endif
    472476        }
     477
     478        // ConstructorInit - fall back on C-style initializer
     479        void Resolver::fallbackInit( ConstructorInit * ctorInit ) {
     480                // could not find valid constructor, or found an intrinsic constructor
     481                // fall back on C-style initializer
     482                delete ctorInit->get_ctor();
     483                ctorInit->set_ctor( NULL );
     484                maybeAccept( ctorInit->get_init(), *this );
     485        }
     486
     487        void Resolver::visit( ConstructorInit *ctorInit ) {
     488                try {
     489                        maybeAccept( ctorInit->get_ctor(), *this );
     490                        maybeAccept( ctorInit->get_dtor(), *this );
     491                } catch ( SemanticError ) {
     492                        // no alternatives for the constructor initializer - fallback on C-style initializer
     493                        // xxx- not sure if this makes a ton of sense - should maybe never be able to have this situation?
     494                        fallbackInit( ctorInit );
     495                        return;
     496                }
     497
     498                // found a constructor - can get rid of C-style initializer
     499                delete ctorInit->get_init();
     500                ctorInit->set_init( NULL );
     501        }
    473502} // namespace ResolvExpr
    474503
  • src/ResolvExpr/Resolver.h

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Resolver.h -- 
     7// Resolver.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:18:34 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun May 17 12:19:32 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:06:53 2016
    1313// Update Count     : 2
    1414//
     
    2424        void resolve( std::list< Declaration * > translationUnit );
    2525        Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer );
     26        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer );
    2627} // namespace ResolvExpr
    2728
  • src/SymTab/AddVisit.h

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // AddVisit.h -- 
     7// AddVisit.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 16:14:32 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr  7 14:42:21 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:52:42 2016
    1313// Update Count     : 5
    1414//
     
    4848        //      maybeAccept( caseStmt->get_condition(), visitor );
    4949        // }
     50
     51        template< typename Visitor >
     52        void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) {
     53                std::list< Declaration * >::iterator i = translationUnit.begin();
     54                while ( i != translationUnit.end() ) {
     55                        (*i)->accept( visitor );
     56                        std::list< Declaration * >::iterator next = i;
     57                        next++;
     58                        if ( ! visitor.get_declsToAdd().empty() ) {
     59                                translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
     60                        } // if
     61                        i = next;
     62                } // while
     63        }
     64
    5065} // namespace SymTab
    5166
  • src/SymTab/Validate.cc

    r9243a501 r7cc6bd6  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr 13 16:39:30 2016
    13 // Update Count     : 251
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:37:23 2016
     13// Update Count     : 297
    1414//
    1515
     
    5656#include "MakeLibCfa.h"
    5757#include "TypeEquality.h"
     58#include "Autogen.h"
    5859#include "ResolvExpr/typeops.h"
    5960
     
    122123
    123124                const Indexer *indexer;
    124         };
    125 
    126         class AutogenerateRoutines : public Visitor {
    127           public:
    128                 /// Generates assignment operators for aggregate types as required
    129                 static void autogenerateRoutines( std::list< Declaration * > &translationUnit );
    130 
    131                 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; }
    132 
    133                 virtual void visit( EnumDecl *enumDecl );
    134                 virtual void visit( StructDecl *structDecl );
    135                 virtual void visit( UnionDecl *structDecl );
    136                 virtual void visit( TypeDecl *typeDecl );
    137                 virtual void visit( TraitDecl *ctxDecl );
    138                 virtual void visit( FunctionDecl *functionDecl );
    139 
    140                 virtual void visit( FunctionType *ftype );
    141                 virtual void visit( PointerType *ftype );
    142 
    143                 virtual void visit( CompoundStmt *compoundStmt );
    144                 virtual void visit( SwitchStmt *switchStmt );
    145                 virtual void visit( ChooseStmt *chooseStmt );
    146                 // virtual void visit( CaseStmt *caseStmt );
    147 
    148                 AutogenerateRoutines() : functionNesting( 0 ) {}
    149           private:
    150                 template< typename StmtClass > void visitStatement( StmtClass *stmt );
    151 
    152                 std::list< Declaration * > declsToAdd;
    153                 std::set< std::string > structsDone;
    154                 unsigned int functionNesting;                   // current level of nested functions
    155125        };
    156126
     
    192162                template<typename AggDecl>
    193163                void addImplicitTypedef( AggDecl * aggDecl );
    194                
     164
    195165                typedef std::map< std::string, std::pair< TypedefDecl *, int > > TypedefMap;
    196166                TypedefMap typedefNames;
    197167                int scopeLevel;
    198168        };
     169
     170        class VerifyCtorDtor : public Visitor {
     171        public:
     172                /// ensure that constructors and destructors have at least one
     173                /// parameter, the first of which must be a pointer, and no
     174                /// return values.
     175                static void verify( std::list< Declaration * > &translationUnit );
     176
     177                virtual void visit( FunctionDecl *funcDecl );
     178};
    199179
    200180        class CompoundLiteral : public GenPoly::DeclMutator {
     
    217197                ReturnChecker::checkFunctionReturns( translationUnit );
    218198                mutateAll( translationUnit, compoundliteral );
    219                 AutogenerateRoutines::autogenerateRoutines( translationUnit );
     199                autogenerateRoutines( translationUnit );
    220200                acceptAll( translationUnit, pass3 );
     201                VerifyCtorDtor::verify( translationUnit );
    221202        }
    222203
     
    228209                type->accept( pass2 );
    229210                type->accept( pass3 );
    230         }
    231 
    232         template< typename Visitor >
    233         void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor, bool addBefore ) {
    234                 std::list< Declaration * >::iterator i = translationUnit.begin();
    235                 while ( i != translationUnit.end() ) {
    236                         (*i)->accept( visitor );
    237                         std::list< Declaration * >::iterator next = i;
    238                         next++;
    239                         if ( ! visitor.get_declsToAdd().empty() ) {
    240                                 translationUnit.splice( addBefore ? i : next, visitor.get_declsToAdd() );
    241                         } // if
    242                         i = next;
    243                 } // while
    244211        }
    245212
     
    503470        }
    504471
    505         static const std::list< std::string > noLabels;
    506 
    507         void AutogenerateRoutines::autogenerateRoutines( std::list< Declaration * > &translationUnit ) {
    508                 AutogenerateRoutines visitor;
    509                 acceptAndAdd( translationUnit, visitor, false );
    510         }
    511 
    512         template< typename OutputIterator >
    513         void makeScalarAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, OutputIterator out ) {
    514                 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( member );
    515                 // unnamed bit fields are not copied as they cannot be accessed
    516                 if ( obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL ) return;
    517 
    518                 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    519 
    520                 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    521                 derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    522 
    523                 // do something special for unnamed members
    524                 Expression *dstselect = new AddressExpr( new MemberExpr( member, derefExpr ) );
    525                 assignExpr->get_args().push_back( dstselect );
    526 
    527                 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    528                 assignExpr->get_args().push_back( srcselect );
    529 
    530                 *out++ = new ExprStmt( noLabels, assignExpr );
    531         }
    532 
    533         template< typename OutputIterator >
    534         void makeArrayAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, DeclarationWithType *member, ArrayType *array, OutputIterator out ) {
    535                 static UniqueName indexName( "_index" );
    536 
    537                 // for a flexible array member nothing is done -- user must define own assignment
    538                 if ( ! array->get_dimension() ) return;
    539 
    540                 ObjectDecl *index = new ObjectDecl( indexName.newName(), DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), 0 );
    541                 *out++ = new DeclStmt( noLabels, index );
    542 
    543                 UntypedExpr *init = new UntypedExpr( new NameExpr( "?=?" ) );
    544                 init->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    545                 init->get_args().push_back( new NameExpr( "0" ) );
    546                 Statement *initStmt = new ExprStmt( noLabels, init );
    547                 std::list<Statement *> initList;
    548                 initList.push_back( initStmt );
    549 
    550                 UntypedExpr *cond = new UntypedExpr( new NameExpr( "?<?" ) );
    551                 cond->get_args().push_back( new VariableExpr( index ) );
    552                 cond->get_args().push_back( array->get_dimension()->clone() );
    553 
    554                 UntypedExpr *inc = new UntypedExpr( new NameExpr( "++?" ) );
    555                 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) );
    556 
    557                 UntypedExpr *assignExpr = new UntypedExpr( new NameExpr( "?=?" ) );
    558 
    559                 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    560                 derefExpr->get_args().push_back( new VariableExpr( dstParam ) );
    561 
    562                 Expression *dstselect = new MemberExpr( member, derefExpr );
    563                 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?+?" ) );
    564                 dstIndex->get_args().push_back( dstselect );
    565                 dstIndex->get_args().push_back( new VariableExpr( index ) );
    566                 assignExpr->get_args().push_back( dstIndex );
    567 
    568                 Expression *srcselect = new MemberExpr( member, new VariableExpr( srcParam ) );
    569                 UntypedExpr *srcIndex = new UntypedExpr( new NameExpr( "?[?]" ) );
    570                 srcIndex->get_args().push_back( srcselect );
    571                 srcIndex->get_args().push_back( new VariableExpr( index ) );
    572                 assignExpr->get_args().push_back( srcIndex );
    573 
    574                 *out++ = new ForStmt( noLabels, initList, cond, inc, new ExprStmt( noLabels, assignExpr ) );
    575         }
    576 
    577         template< typename OutputIterator >
    578         void makeUnionFieldsAssignment( ObjectDecl *srcParam, ObjectDecl *dstParam, UnionInstType *unionType, OutputIterator out ) {
    579                 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) );
    580                 copy->get_args().push_back( new VariableExpr( dstParam ) );
    581                 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) );
    582                 copy->get_args().push_back( new SizeofExpr( unionType ) );
    583 
    584                 *out++ = new ExprStmt( noLabels, copy );
    585         }
    586 
    587         //E ?=?(E volatile*, int),
    588         //  ?=?(E _Atomic volatile*, int);
    589         void makeEnumAssignment( EnumDecl *enumDecl, EnumInstType *refType, unsigned int functionNesting, std::list< Declaration * > &declsToAdd ) {
    590                 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    591 
    592                 ObjectDecl *returnVal = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, refType->clone(), 0 );
    593                 assignType->get_returnVals().push_back( returnVal );
    594 
    595                 // need two assignment operators with different types
    596                 FunctionType * assignType2 = assignType->clone();
    597 
    598                 // E ?=?(E volatile *, E)
    599                 Type *etype = refType->clone();
    600                 // etype->get_qualifiers() += Type::Qualifiers(false, true, false, false, false, false);
    601 
    602                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), etype ), 0 );
    603                 assignType->get_parameters().push_back( dstParam );
    604 
    605                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, etype->clone(), 0 );
    606                 assignType->get_parameters().push_back( srcParam );
    607 
    608                 // E ?=?(E volatile *, int)
    609                 assignType2->get_parameters().push_back( dstParam->clone() );
    610                 BasicType * paramType = new BasicType(Type::Qualifiers(), BasicType::SignedInt);
    611                 ObjectDecl *srcParam2 = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, paramType, 0 );
    612                 assignType2->get_parameters().push_back( srcParam2 );
    613 
    614                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    615                 // because each unit generates copies of the default routines for each aggregate.
    616 
    617                 // since there is no definition, these should not be inline
    618                 // make these intrinsic so that the code generator does not make use of them
    619                 FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType, 0, false, false );
    620                 assignDecl->fixUniqueId();
    621                 FunctionDecl *assignDecl2 = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::Intrinsic, assignType2, 0, false, false );
    622                 assignDecl2->fixUniqueId();
    623 
    624                 // these should be built in the same way that the prelude
    625                 // functions are, so build a list containing the prototypes
    626                 // and allow MakeLibCfa to autogenerate the bodies.
    627                 std::list< Declaration * > assigns;
    628                 assigns.push_back( assignDecl );
    629                 assigns.push_back( assignDecl2 );
    630 
    631                 LibCfa::makeLibCfa( assigns );
    632 
    633                 // need to remove the prototypes, since this may be nested in a routine
    634                 for (int start = 0, end = assigns.size()/2; start < end; start++) {
    635                         delete assigns.front();
    636                         assigns.pop_front();
    637                 } // for
    638 
    639                 declsToAdd.insert( declsToAdd.begin(), assigns.begin(), assigns.end() );
    640         }
    641 
    642         /// Clones a reference type, replacing any parameters it may have with a clone of the provided list
    643         template< typename GenericInstType >
    644         GenericInstType *cloneWithParams( GenericInstType *refType, const std::list< Expression* >& params ) {
    645                 GenericInstType *clone = refType->clone();
    646                 clone->get_parameters().clear();
    647                 cloneAll( params, clone->get_parameters() );
    648                 return clone;
    649         }
    650 
    651         /// Creates a new type decl that's the same as src, but renamed and with only the ?=? assertion (for complete types only)
    652         TypeDecl *cloneAndRename( TypeDecl *src, const std::string &name ) {
    653                 TypeDecl *dst = new TypeDecl( name, src->get_storageClass(), 0, src->get_kind() );
    654 
    655                 if ( src->get_kind() == TypeDecl::Any ) {
    656                         // just include assignment operator assertion
    657                         TypeInstType *assignParamType = new TypeInstType( Type::Qualifiers(), name, dst );
    658                         FunctionType *assignFunctionType = new FunctionType( Type::Qualifiers(), false );
    659                         assignFunctionType->get_returnVals().push_back(
    660                                 new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType->clone(), 0 ) );
    661                         assignFunctionType->get_parameters().push_back(
    662                                 new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), assignParamType->clone() ), 0 ) );
    663                         assignFunctionType->get_parameters().push_back(
    664                                 new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, assignParamType, 0 ) );
    665                         FunctionDecl *assignAssert = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, assignFunctionType, 0, false, false );
    666                         dst->get_assertions().push_back( assignAssert );
    667                 }
    668 
    669                 return dst;
    670         }
    671 
    672         Declaration *makeStructAssignment( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting ) {
    673                 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    674 
    675                 // Make function polymorphic in same parameters as generic struct, if applicable
    676                 bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)
    677                 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    678                 std::list< Expression* > structParams;  // List of matching parameters to put on types
    679                 TypeSubstitution genericSubs; // Substitutions to make to member types of struct
    680                 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    681                         isGeneric = true;
    682                         TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
    683                         assignType->get_forall().push_back( typeParam );
    684                         TypeInstType *newParamType = new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam );
    685                         genericSubs.add( (*param)->get_name(), newParamType );
    686                         structParams.push_back( new TypeExpr( newParamType ) );
    687                 }
    688 
    689                 ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    690                 assignType->get_returnVals().push_back( returnVal );
    691 
    692                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, structParams ) ), 0 );
    693                 assignType->get_parameters().push_back( dstParam );
    694 
    695                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, structParams ), 0 );
    696                 assignType->get_parameters().push_back( srcParam );
    697 
    698                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    699                 // because each unit generates copies of the default routines for each aggregate.
    700                 FunctionDecl *assignDecl = new FunctionDecl( "?=?", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
    701                 assignDecl->fixUniqueId();
    702 
    703                 for ( std::list< Declaration * >::const_iterator member = aggregateDecl->get_members().begin(); member != aggregateDecl->get_members().end(); ++member ) {
    704                         if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member ) ) {
    705                                 // query the type qualifiers of this field and skip assigning it if it is marked const.
    706                                 // If it is an array type, we need to strip off the array layers to find its qualifiers.
    707                                 Type * type = dwt->get_type();
    708                                 while ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) {
    709                                         type = at->get_base();
    710                                 }
    711 
    712                                 if ( type->get_qualifiers().isConst ) {
    713                                         // don't assign const members
    714                                         continue;
    715                                 }
    716 
    717                                 if ( isGeneric ) {
    718                                         // rewrite member type in terms of the type variables on this operator
    719                                         DeclarationWithType *fixedMember = dwt->clone();
    720                                         genericSubs.apply( fixedMember );
    721 
    722                                         // assign to both destination and return value
    723                                         if ( ArrayType *array = dynamic_cast< ArrayType * >( fixedMember->get_type() ) ) {
    724                                                 makeArrayAssignment( srcParam, dstParam, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    725                                                 makeArrayAssignment( srcParam, returnVal, fixedMember, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    726                                         } else {
    727                                                 makeScalarAssignment( srcParam, dstParam, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) );
    728                                                 makeScalarAssignment( srcParam, returnVal, fixedMember, back_inserter( assignDecl->get_statements()->get_kids() ) );
    729                                         } // if
    730                                 } else {
    731                                         // assign to destination
    732                                         if ( ArrayType *array = dynamic_cast< ArrayType * >( dwt->get_type() ) ) {
    733                                                 makeArrayAssignment( srcParam, dstParam, dwt, array, back_inserter( assignDecl->get_statements()->get_kids() ) );
    734                                         } else {
    735                                                 makeScalarAssignment( srcParam, dstParam, dwt, back_inserter( assignDecl->get_statements()->get_kids() ) );
    736                                         } // if
    737                                 } // if
    738                         } // if
    739                 } // for
    740                 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    741 
    742                 return assignDecl;
    743         }
    744 
    745         Declaration *makeUnionAssignment( UnionDecl *aggregateDecl, UnionInstType *refType, unsigned int functionNesting ) {
    746                 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false );
    747 
    748                 // Make function polymorphic in same parameters as generic union, if applicable
    749                 bool isGeneric = false;  // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for struct)
    750                 std::list< TypeDecl* >& genericParams = aggregateDecl->get_parameters();
    751                 std::list< Expression* > unionParams;  // List of matching parameters to put on types
    752                 for ( std::list< TypeDecl* >::const_iterator param = genericParams.begin(); param != genericParams.end(); ++param ) {
    753                         isGeneric = true;
    754                         TypeDecl *typeParam = cloneAndRename( *param, "_autoassign_" + aggregateDecl->get_name() + "_" + (*param)->get_name() );
    755                         assignType->get_forall().push_back( typeParam );
    756                         unionParams.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeParam->get_name(), typeParam ) ) );
    757                 }
    758 
    759                 ObjectDecl *returnVal = new ObjectDecl( "_ret", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    760                 assignType->get_returnVals().push_back( returnVal );
    761 
    762                 ObjectDecl *dstParam = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), cloneWithParams( refType, unionParams ) ), 0 );
    763                 assignType->get_parameters().push_back( dstParam );
    764 
    765                 ObjectDecl *srcParam = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, cloneWithParams( refType, unionParams ), 0 );
    766                 assignType->get_parameters().push_back( srcParam );
    767 
    768                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    769                 // because each unit generates copies of the default routines for each aggregate.
    770                 FunctionDecl *assignDecl = new FunctionDecl( "?=?",  functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, assignType, new CompoundStmt( noLabels ), true, false );
    771                 assignDecl->fixUniqueId();
    772 
    773                 makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    774                 if ( isGeneric ) makeUnionFieldsAssignment( srcParam, returnVal, cloneWithParams( refType, unionParams ), back_inserter( assignDecl->get_statements()->get_kids() ) );
    775                
    776                 if ( ! isGeneric ) assignDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    777 
    778                 return assignDecl;
    779         }
    780 
    781         void AutogenerateRoutines::visit( EnumDecl *enumDecl ) {
    782                 if ( ! enumDecl->get_members().empty() ) {
    783                         EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() );
    784                         // enumInst->set_baseEnum( enumDecl );
    785                         // declsToAdd.push_back(
    786                         makeEnumAssignment( enumDecl, enumInst, functionNesting, declsToAdd );
    787                 }
    788         }
    789 
    790         void AutogenerateRoutines::visit( StructDecl *structDecl ) {
    791                 if ( ! structDecl->get_members().empty() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) {
    792                         StructInstType structInst( Type::Qualifiers(), structDecl->get_name() );
    793                         structInst.set_baseStruct( structDecl );
    794                         declsToAdd.push_back( makeStructAssignment( structDecl, &structInst, functionNesting ) );
    795                         structsDone.insert( structDecl->get_name() );
    796                 } // if
    797         }
    798 
    799         void AutogenerateRoutines::visit( UnionDecl *unionDecl ) {
    800                 if ( ! unionDecl->get_members().empty() ) {
    801                         UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() );
    802                         unionInst.set_baseUnion( unionDecl );
    803                         declsToAdd.push_back( makeUnionAssignment( unionDecl, &unionInst, functionNesting ) );
    804                 } // if
    805         }
    806 
    807         void AutogenerateRoutines::visit( TypeDecl *typeDecl ) {
    808                 CompoundStmt *stmts = 0;
    809                 TypeInstType *typeInst = new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), false );
    810                 typeInst->set_baseType( typeDecl );
    811                 ObjectDecl *src = new ObjectDecl( "_src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, typeInst->clone(), 0 );
    812                 ObjectDecl *dst = new ObjectDecl( "_dst", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), typeInst->clone() ), 0 );
    813                 if ( typeDecl->get_base() ) {
    814                         stmts = new CompoundStmt( std::list< Label >() );
    815                         UntypedExpr *assign = new UntypedExpr( new NameExpr( "?=?" ) );
    816                         assign->get_args().push_back( new CastExpr( new VariableExpr( dst ), new PointerType( Type::Qualifiers(), typeDecl->get_base()->clone() ) ) );
    817                         assign->get_args().push_back( new CastExpr( new VariableExpr( src ), typeDecl->get_base()->clone() ) );
    818                         stmts->get_kids().push_back( new ReturnStmt( std::list< Label >(), assign ) );
    819                 } // if
    820                 FunctionType *type = new FunctionType( Type::Qualifiers(), false );
    821                 type->get_returnVals().push_back( new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, typeInst, 0 ) );
    822                 type->get_parameters().push_back( dst );
    823                 type->get_parameters().push_back( src );
    824                 FunctionDecl *func = new FunctionDecl( "?=?", DeclarationNode::NoStorageClass, LinkageSpec::AutoGen, type, stmts, false, false );
    825                 declsToAdd.push_back( func );
    826         }
    827 
    828         void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) {
    829                 for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) {
    830                         statements.insert( i, new DeclStmt( noLabels, *decl ) );
    831                 } // for
    832                 declsToAdd.clear();
    833         }
    834 
    835         void AutogenerateRoutines::visit( FunctionType *) {
    836                 // ensure that we don't add assignment ops for types defined as part of the function
    837         }
    838 
    839         void AutogenerateRoutines::visit( PointerType *) {
    840                 // ensure that we don't add assignment ops for types defined as part of the pointer
    841         }
    842 
    843         void AutogenerateRoutines::visit( TraitDecl *) {
    844                 // ensure that we don't add assignment ops for types defined as part of the context
    845         }
    846 
    847         template< typename StmtClass >
    848         inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) {
    849                 std::set< std::string > oldStructs = structsDone;
    850                 addVisit( stmt, *this );
    851                 structsDone = oldStructs;
    852         }
    853 
    854         void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) {
    855                 maybeAccept( functionDecl->get_functionType(), *this );
    856                 acceptAll( functionDecl->get_oldDecls(), *this );
    857                 functionNesting += 1;
    858                 maybeAccept( functionDecl->get_statements(), *this );
    859                 functionNesting -= 1;
    860         }
    861 
    862         void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) {
    863                 visitStatement( compoundStmt );
    864         }
    865 
    866         void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) {
    867                 visitStatement( switchStmt );
    868         }
    869 
    870         void AutogenerateRoutines::visit( ChooseStmt *switchStmt ) {
    871                 visitStatement( switchStmt );
    872         }
    873 
    874         // void AutogenerateRoutines::visit( CaseStmt *caseStmt ) {
    875         //      visitStatement( caseStmt );
    876         // }
    877 
    878472        void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
    879473                ReturnChecker checker;
     
    1033627                return aggDecl;
    1034628        }
    1035        
     629
    1036630        template<typename AggDecl>
    1037631        void EliminateTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
     
    1072666        }
    1073667
     668        void VerifyCtorDtor::verify( std::list< Declaration * > & translationUnit ) {
     669                VerifyCtorDtor verifier;
     670                acceptAll( translationUnit, verifier );
     671        }
     672
     673        void VerifyCtorDtor::visit( FunctionDecl * funcDecl ) {
     674                FunctionType * funcType = funcDecl->get_functionType();
     675                std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();
     676                std::list< DeclarationWithType * > &params = funcType->get_parameters();
     677
     678                if ( funcDecl->get_name() == "?{}" || funcDecl->get_name() == "^?{}" ) {
     679                        if ( params.size() == 0 ) {
     680                                throw SemanticError( "Constructors and destructors require at least one parameter ", funcDecl );
     681                        }
     682                        if ( ! dynamic_cast< PointerType * >( params.front()->get_type() ) ) {
     683                                throw SemanticError( "First parameter of a constructor or destructor must be a pointer ", funcDecl );
     684                        }
     685                        if ( returnVals.size() != 0 ) {
     686                                throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
     687                        }
     688                }
     689
     690                Visitor::visit( funcDecl );
     691                // original idea: modify signature of ctor/dtors and insert appropriate return statements
     692                // to cause desired behaviour
     693                // new idea: add comma exprs to every ctor call to produce first parameter.
     694                // this requires some memoization of the first parameter, because it can be a
     695                // complicated expression with side effects (see: malloc). idea: add temporary variable
     696                // that is assigned address of constructed object in ctor argument position and
     697                // return the temporary. It should also be done after all implicit ctors are
     698                // added, so not in this pass!
     699        }
     700
    1074701        DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {
    1075702                storageclass = objectDecl->get_storageClass();
  • src/SymTab/module.mk

    r9243a501 r7cc6bd6  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## module.mk -- 
     8## module.mk --
    99##
    1010## Author           : Richard C. Bilson
     
    2020       SymTab/FixFunction.cc \
    2121       SymTab/ImplementationType.cc \
    22        SymTab/TypeEquality.cc
     22       SymTab/TypeEquality.cc \
     23       SymTab/Autogen.cc
  • src/SynTree/CommaExpr.cc

    r9243a501 r7cc6bd6  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon May 02 15:11:29 2016
     12// Last Modified On : Mon May 02 15:19:44 2016
    1313// Update Count     : 1
    1414//
  • src/SynTree/CompoundStmt.cc

    r9243a501 r7cc6bd6  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Mon May 02 15:10:47 2016
     12// Last Modified On : Mon May 02 15:19:17 2016
    1313// Update Count     : 3
    1414//
     
    1818#include <algorithm>
    1919#include <functional>
     20#include "Expression.h"
     21#include "Declaration.h"
    2022
    2123using std::string;
    2224using std::endl;
     25
     26class VarExprReplacer : public Visitor {
     27public:
     28  typedef std::map< DeclarationWithType *, DeclarationWithType * > DeclMap;
     29private:
     30  const DeclMap & declMap;
     31public:
     32  VarExprReplacer( const DeclMap & declMap ) : declMap( declMap ) {}
     33
     34  // replace variable with new node from decl map
     35  virtual void visit( VariableExpr * varExpr ) {
     36    if ( declMap.count( varExpr->get_var() ) ) {
     37      varExpr->set_var( declMap.at( varExpr->get_var() ) );
     38    }
     39  }
     40};
     41
    2342
    2443CompoundStmt::CompoundStmt( std::list<Label> labels ) : Statement( labels ) {
     
    2746CompoundStmt::CompoundStmt( const CompoundStmt &other ) : Statement( other ) {
    2847        cloneAll( other.kids, kids );
     48
     49  // when cloning a compound statement, we may end up cloning declarations which
     50  // are referred to by VariableExprs throughout the block. Cloning a VariableExpr
     51  // does a shallow copy, so the VariableExpr will end up pointing to the original
     52  // declaration. If the original declaration is deleted, e.g. because the original
     53  // CompoundStmt is deleted, then we have a dangling pointer. To avoid this case,
     54  // find all DeclarationWithType nodes (since a VariableExpr must point to a
     55  // DeclarationWithType) in the original CompoundStmt and map them to the cloned
     56  // node in the new CompoundStmt ('this'), then replace the Declarations referred to
     57  // by each VariableExpr according to the constructed map. Note that only the declarations
     58  // in the current level are collected into the map, because child CompoundStmts will
     59  // recursively execute this routine. There may be more efficient ways of doing
     60  // this.
     61  VarExprReplacer::DeclMap declMap;
     62  std::list< Statement * >::const_iterator origit = other.kids.begin();
     63  for ( Statement * s : kids ) {
     64    assert( origit != other.kids.end() );
     65    if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( s ) ) {
     66      DeclStmt * origDeclStmt = dynamic_cast< DeclStmt * >( *origit );
     67      assert( origDeclStmt );
     68      if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * > ( declStmt->get_decl() ) ) {
     69        DeclarationWithType * origdwt = dynamic_cast< DeclarationWithType * > ( origDeclStmt->get_decl() );
     70        assert( origdwt );
     71        declMap[ origdwt ] = dwt;
     72      }
     73    }
     74  }
     75  if ( ! declMap.empty() ) {
     76    VarExprReplacer replacer( declMap );
     77    accept( replacer );
     78  }
    2979}
    3080
  • src/SynTree/Declaration.h

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Declaration.h -- 
     7// Declaration.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:28:11 2016
    13 // Update Count     : 33
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 11 16:55:12 2016
     13// Update Count     : 36
    1414//
    1515
     
    2222#include "Parser/LinkageSpec.h"
    2323#include "Parser/ParseNode.h"
     24#include <string>
    2425
    2526class Declaration {
     
    6768        void set_mangleName( std::string newValue ) { mangleName = newValue; }
    6869
     70        std::string get_scopedMangleName() const { return mangleName + "_" + std::to_string(scopeLevel); }
     71
     72        int get_scopeLevel() const { return scopeLevel; }
     73        void set_scopeLevel( int newValue ) { scopeLevel = newValue; }
     74
    6975        virtual DeclarationWithType *clone() const = 0;
    7076        virtual DeclarationWithType *acceptMutator( Mutator &m ) = 0;
     
    7581        // this represents the type with all types and typedefs expanded it is generated by SymTab::Validate::Pass2
    7682        std::string mangleName;
     83        // need to remember the scope level at which the variable was declared, so that
     84        // shadowed identifiers can be accessed
     85        int scopeLevel = 0;
    7786};
    7887
  • src/SynTree/DeclarationWithType.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // DeclarationWithType.cc -- 
     7// DeclarationWithType.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jun 13 08:08:07 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon Apr 11 15:35:27 2016
    1313// Update Count     : 3
    1414//
     
    2323
    2424DeclarationWithType::DeclarationWithType( const DeclarationWithType &other )
    25                 : Declaration( other ), mangleName( other.mangleName ) {
     25                : Declaration( other ), mangleName( other.mangleName ), scopeLevel( other.scopeLevel ) {
    2626}
    2727
  • src/SynTree/Expression.cc

    r9243a501 r7cc6bd6  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed May 04 12:14:09 2016
     12// Last Modified On : Wed May 04 12:17:51 2016
    1313// Update Count     : 40
    1414//
     
    7979
    8080VariableExpr::VariableExpr( DeclarationWithType *_var, Expression *_aname ) : Expression( _aname ), var( _var ) {
     81        assert( var );
     82        assert( var->get_type() );
    8183        add_result( var->get_type()->clone() );
    8284        for ( std::list< Type* >::iterator i = get_results().begin(); i != get_results().end(); ++i ) {
     
    463465}
    464466
     467
     468ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) {
     469        assert( callExpr );
     470        cloneAll( callExpr->get_results(), results );
     471}
     472
     473ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other ) : Expression( other ), callExpr( maybeClone( other.callExpr ) ) {
     474        cloneAll( other.tempDecls, tempDecls );
     475        cloneAll( other.returnDecls, returnDecls );
     476        cloneAll( other.dtors, dtors );
     477}
     478
     479ImplicitCopyCtorExpr::~ImplicitCopyCtorExpr() {
     480        delete callExpr;
     481        deleteAll( tempDecls );
     482        deleteAll( returnDecls );
     483        deleteAll( dtors );
     484}
     485
     486void ImplicitCopyCtorExpr::print( std::ostream &os, int indent ) const {
     487        os << std::string( indent, ' ' ) <<  "Implicit Copy Constructor Expression: " << std::endl;
     488        assert( callExpr );
     489        callExpr->print( os, indent + 2 );
     490        os << std::endl << std::string( indent, ' ' ) << "with temporaries:" << std::endl;
     491        printAll(tempDecls, os, indent+2);
     492        os << std::endl << std::string( indent, ' ' ) << "with return temporaries:" << std::endl;
     493        printAll(returnDecls, os, indent+2);
     494        Expression::print( os, indent );
     495}
     496
    465497UntypedValofExpr::UntypedValofExpr( const UntypedValofExpr & other ) : Expression( other ), body ( maybeClone( other.body ) ) {}
    466498
  • src/SynTree/Expression.h

    r9243a501 r7cc6bd6  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  8 17:18:06 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 27 17:06:49 2016
    1313// Update Count     : 21
    1414//
     
    2222#include "Mutator.h"
    2323#include "Constant.h"
     24#include "Common/UniqueName.h"
    2425
    2526/// Expression is the root type for all expressions
     
    559560};
    560561
     562/// ImplicitCopyCtorExpr represents the application of a function to a set of parameters,
     563/// along with a set of copy constructor calls, one for each argument.
     564class ImplicitCopyCtorExpr : public Expression {
     565public:
     566        ImplicitCopyCtorExpr( ApplicationExpr * callExpr );
     567        ImplicitCopyCtorExpr( const ImplicitCopyCtorExpr & other );
     568        virtual ~ImplicitCopyCtorExpr();
     569
     570        ApplicationExpr *get_callExpr() const { return callExpr; }
     571        void set_callExpr( ApplicationExpr *newValue ) { callExpr = newValue; }
     572
     573        std::list< ObjectDecl * > & get_tempDecls() { return tempDecls; }
     574        void set_tempDecls( std::list< ObjectDecl * > newValue ) { tempDecls = newValue; }
     575
     576        std::list< ObjectDecl * > & get_returnDecls() { return returnDecls; }
     577        void set_returnDecls( std::list< ObjectDecl * > newValue ) { returnDecls = newValue; }
     578
     579        std::list< Expression * > & get_dtors() { return dtors; }
     580        void set_dtors( std::list< Expression * > newValue ) { dtors = newValue; }
     581
     582        virtual ImplicitCopyCtorExpr *clone() const { return new ImplicitCopyCtorExpr( *this ); }
     583        virtual void accept( Visitor &v ) { v.visit( this ); }
     584        virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     585        virtual void print( std::ostream &os, int indent = 0 ) const;
     586  private:
     587        ApplicationExpr * callExpr;
     588        std::list< ObjectDecl * > tempDecls;
     589        std::list< ObjectDecl * > returnDecls;
     590        std::list< Expression * > dtors;
     591};
     592
    561593/// ValofExpr represents a GCC 'lambda expression'
    562594class UntypedValofExpr : public Expression {
  • src/SynTree/Initializer.cc

    r9243a501 r7cc6bd6  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Apr 26 12:50:47 2016
     12// Last Modified On : Tue Apr 26 15:51:35 2016
    1313// Update Count     : 28
    1414//
     
    1616#include "Initializer.h"
    1717#include "Expression.h"
     18#include "Statement.h"
    1819#include "Common/utility.h"
    1920
    20 Initializer::Initializer() {}
     21Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {}
    2122
    2223Initializer::~Initializer() {}
     
    3132void Initializer::print( std::ostream &os, int indent ) {}
    3233
    33 SingleInit::SingleInit( Expression *v, std::list< Expression *> &_designators ) : value ( v ), designators( _designators ) {
     34SingleInit::SingleInit( Expression *v, const std::list< Expression *> &_designators, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ), designators( _designators ) {
    3435}
    3536
    36 SingleInit::SingleInit( const SingleInit &other ) : value ( other.value ) {
     37SingleInit::SingleInit( const SingleInit &other ) : Initializer(other), value ( maybeClone( other.value ) ) {
    3738        cloneAll(other.designators, designators );
    3839}
     
    5556}
    5657
    57 ListInit::ListInit( std::list<Initializer*> &_initializers, std::list<Expression *> &_designators )
    58         : initializers( _initializers ), designators( _designators ) {
     58ListInit::ListInit( const std::list<Initializer*> &_initializers, const std::list<Expression *> &_designators, bool maybeConstructed )
     59        : Initializer( maybeConstructed), initializers( _initializers ), designators( _designators ) {
    5960}
    6061
     
    8081                (*i)->print( os, indent + 2 );
    8182}
     83
     84
     85ConstructorInit::ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init ) : Initializer( true ), ctor( ctor ), dtor( dtor ), init( init ) {}
     86ConstructorInit::~ConstructorInit() {
     87        delete ctor;
     88        delete init;
     89}
     90
     91ConstructorInit *ConstructorInit::clone() const {
     92        return new ConstructorInit( *this );
     93}
     94
     95void ConstructorInit::print( std::ostream &os, int indent ) {
     96        os << std::endl << std::string(indent, ' ') << "Constructor initializer: " << std::endl;
     97        if ( ctor ) {
     98                os << std::string(indent+2, ' ');
     99                os << "initially constructed with ";
     100                ctor->print( os, indent+4 );
     101        } // if
     102
     103        if ( dtor ) {
     104                os << std::string(indent+2, ' ');
     105                os << "destructed with ";
     106                dtor->print( os, indent+4 );
     107        }
     108
     109        if ( init ) {
     110                os << std::string(indent+2, ' ');
     111                os << "with fallback C-style initializer: ";
     112                init->print( os, indent+4 );
     113        }
     114}
     115
     116std::ostream & operator<<( std::ostream & out, Initializer * init ) {
     117        init->print( out );
     118        return out;
     119}
     120
    82121// Local Variables: //
    83122// tab-width: 4 //
  • src/SynTree/Initializer.h

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Initializer.h -- 
     7// Initializer.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 09:03:48 2015
    13 // Update Count     : 1
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Apr 12 13:49:13 2016
     13// Update Count     : 19
    1414//
    1515
     
    2727  public:
    2828        //      Initializer( std::string _name = std::string(""), int _pos = 0 );
    29         Initializer( );
     29        Initializer( bool maybeConstructed );
    3030        virtual ~Initializer();
    3131
     
    4343        }
    4444
     45        bool get_maybeConstructed() { return maybeConstructed; }
     46
    4547        virtual Initializer *clone() const = 0;
    4648        virtual void accept( Visitor &v ) = 0;
     
    5052        //      std::string name;
    5153        //      int pos;
     54        bool maybeConstructed;
    5255};
    5356
     
    5558class SingleInit : public Initializer {
    5659  public:
    57         SingleInit( Expression *value, std::list< Expression *> &designators = *(new std::list<Expression *>()) );
     60        SingleInit( Expression *value, const std::list< Expression *> &designators = std::list< Expression * >(), bool maybeConstructed = false );
    5861        SingleInit( const SingleInit &other );
    5962        virtual ~SingleInit();
    60        
     63
    6164        Expression *get_value() { return value; }
    6265        void set_value( Expression *newValue ) { value = newValue; }
     
    7982class ListInit : public Initializer {
    8083  public:
    81         ListInit( std::list<Initializer*> &,
    82                           std::list<Expression *> &designators = *(new std::list<Expression *>()) );
     84        ListInit( const std::list<Initializer*> &initializers,
     85                          const std::list<Expression *> &designators = std::list< Expression * >(), bool maybeConstructed = false );
    8386        virtual ~ListInit();
    8487
     
    100103};
    101104
     105// ConstructorInit represents an initializer that is either a constructor expression or
     106// a C-style initializer.
     107class ConstructorInit : public Initializer {
     108  public:
     109        ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init );
     110        virtual ~ConstructorInit();
     111
     112        void set_ctor( Statement * newValue ) { ctor = newValue; }
     113        Statement * get_ctor() const { return ctor; }
     114        void set_dtor( Statement * newValue ) { dtor = newValue; }
     115        Statement * get_dtor() const { return dtor; }
     116        void set_init( Initializer * newValue ) { init = newValue; }
     117        Initializer * get_init() const { return init; }
     118
     119        virtual ConstructorInit *clone() const;
     120        virtual void accept( Visitor &v ) { v.visit( this ); }
     121        virtual Initializer *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     122        virtual void print( std::ostream &os, int indent = 0 );
     123
     124  private:
     125        Statement * ctor;
     126        Statement * dtor;
     127        // C-style initializer made up of SingleInit and ListInit nodes to use as a fallback
     128        // if an appropriate constructor definition is not found by the resolver
     129        Initializer * init;
     130};
     131
     132std::ostream & operator<<( std::ostream & out, Initializer * init );
     133
    102134#endif // INITIALIZER_H
    103135
  • src/SynTree/Mutator.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Mutator.cc -- 
     7// Mutator.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  1 18:05:16 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 27 17:07:29 2016
    1313// Update Count     : 16
    1414//
     
    337337}
    338338
     339Expression* Mutator::mutate( ImplicitCopyCtorExpr *impCpCtorExpr ) {
     340        impCpCtorExpr->set_callExpr( maybeMutate( impCpCtorExpr->get_callExpr(), *this ) );
     341        mutateAll( impCpCtorExpr->get_tempDecls(), *this );
     342        mutateAll( impCpCtorExpr->get_returnDecls(), *this );
     343        return impCpCtorExpr;
     344}
     345
    339346Expression *Mutator::mutate( UntypedValofExpr *valofExpr ) {
    340347        mutateAll( valofExpr->get_results(), *this );
     
    450457}
    451458
     459Initializer *Mutator::mutate( ConstructorInit *ctorInit ) {
     460        ctorInit->set_ctor( maybeMutate( ctorInit->get_ctor(), *this ) );
     461        ctorInit->set_init( maybeMutate( ctorInit->get_init(), *this ) );
     462        return ctorInit;
     463}
     464
    452465Subrange *Mutator::mutate( Subrange *subrange ) {
    453466        return subrange;
  • src/SynTree/Mutator.h

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Mutator.h -- 
     7// Mutator.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  1 17:26:56 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:32:00 2016
    1313// Update Count     : 10
    1414//
     
    6262        virtual Expression* mutate( MemberExpr *memberExpr );
    6363        virtual Expression* mutate( VariableExpr *variableExpr );
    64         virtual Expression* mutate( ConstantExpr *constantExpr ); 
     64        virtual Expression* mutate( ConstantExpr *constantExpr );
    6565        virtual Expression* mutate( SizeofExpr *sizeofExpr );
    6666        virtual Expression* mutate( AlignofExpr *alignofExpr );
     
    7676        virtual Expression* mutate( TypeExpr *typeExpr );
    7777        virtual Expression* mutate( AsmExpr *asmExpr );
     78        virtual Expression* mutate( ImplicitCopyCtorExpr *impCpCtorExpr );
    7879        virtual Expression* mutate( UntypedValofExpr *valofExpr );
    7980        virtual Expression* mutate( CompoundLiteralExpr *compLitExpr );
     
    9697        virtual Initializer* mutate( SingleInit *singleInit );
    9798        virtual Initializer* mutate( ListInit *listInit );
     99        virtual Initializer* mutate( ConstructorInit *ctorInit );
    98100
    99101        virtual Subrange *mutate( Subrange *subrange );
  • src/SynTree/ObjectDecl.cc

    r9243a501 r7cc6bd6  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed May 04 12:11:56 2016
     12// Last Modified On : Wed May 04 12:18:28 2016
    1313// Update Count     : 30
    1414//
     
    1919#include "Expression.h"
    2020#include "Common/utility.h"
     21#include "Statement.h"
    2122
    2223ObjectDecl::ObjectDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init, bool isInline, bool isNoreturn )
     
    5960                os << " with initializer ";
    6061                init->print( os, indent );
     62                os << std::string(indent, ' ') << "maybeConstructed? " << init->get_maybeConstructed();
    6163        } // if
    6264
  • src/SynTree/SynTree.h

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // SynTree.h -- 
     7// SynTree.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  1 16:47:44 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:31:36 2016
    1313// Update Count     : 5
    1414//
     
    8181class TypeExpr;
    8282class AsmExpr;
     83class ImplicitCopyCtorExpr;
    8384class UntypedValofExpr;
    8485class CompoundLiteralExpr;
     
    104105class SingleInit;
    105106class ListInit;
     107class ConstructorInit;
    106108
    107109class Subrange;
  • src/SynTree/TypeSubstitution.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TypeSubstitution.cc -- 
     7// TypeSubstitution.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:29:15 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Tue Apr 26 11:15:29 2016
    1313// Update Count     : 3
    1414//
     
    9696        BoundVarsType::const_iterator bound = boundVars.find( inst->get_name() );
    9797        if ( bound != boundVars.end() ) return inst;
    98        
     98
    9999        TypeEnvType::const_iterator i = typeEnv.find( inst->get_name() );
    100100        if ( i == typeEnv.end() ) {
     
    217217}
    218218
     219std::ostream & operator<<( std::ostream & out, const TypeSubstitution & sub ) {
     220        sub.print( out );
     221        return out;
     222}
     223
     224
    219225// Local Variables: //
    220226// tab-width: 4 //
  • src/SynTree/TypeSubstitution.h

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // TypeSubstitution.h -- 
     7// TypeSubstitution.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:33:19 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri Apr 29 15:00:20 2016
    1313// Update Count     : 2
    1414//
     
    3333        TypeSubstitution( const TypeSubstitution &other );
    3434        virtual ~TypeSubstitution();
    35        
     35
    3636        TypeSubstitution &operator=( const TypeSubstitution &other );
    37        
     37
    3838        template< typename SynTreeClass > int apply( SynTreeClass *&input );
    3939        template< typename SynTreeClass > int applyFree( SynTreeClass *&input );
    40        
     40
    4141        void add( std::string formalType, Type *actualType );
    4242        void add( const TypeSubstitution &other );
     
    4444        Type *lookup( std::string formalType ) const;
    4545        bool empty() const;
    46        
     46
    4747        template< typename FormalIterator, typename ActualIterator >
    4848        void add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin );
    49        
     49
     50        /// this function is unused...
    5051        template< typename TypeInstListIterator >
    5152        void extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result );
    52        
     53
    5354        void normalize();
    5455
     
    6364        /// Records type variable bindings from forall-statements and instantiations of generic types
    6465        template< typename TypeClass > Type *handleAggregateType( TypeClass *type );
    65        
     66
    6667        virtual Type* mutate(VoidType *basicType);
    6768        virtual Type* mutate(BasicType *basicType);
     
    7576        virtual Type* mutate(TupleType *tupleType);
    7677        virtual Type* mutate(VarArgsType *varArgsType);
    77        
     78
    7879        // TODO: worry about traversing into a forall-qualified function type or type decl with assertions
    79        
     80
    8081        void initialize( const TypeSubstitution &src, TypeSubstitution &dest );
    8182
     
    136137        return subCount;
    137138}
    138        
     139
    139140template< typename SynTreeClass >
    140141int TypeSubstitution::applyFree( SynTreeClass *&input ) {
     
    149150        return subCount;
    150151}
    151        
     152
    152153template< typename TypeInstListIterator >
    153154void TypeSubstitution::extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result ) {
     155        // xxx - this function doesn't extract varEnv - is this intentional?
    154156        while ( begin != end ) {
    155157                TypeEnvType::iterator cur = typeEnv.find( (*begin++)->get_name() );
     
    173175}
    174176
     177std::ostream & operator<<( std::ostream & out, const TypeSubstitution & sub );
     178
    175179#endif // TYPESUBSTITUTION_H
    176180
  • src/SynTree/Visitor.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Visitor.cc -- 
     7// Visitor.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  1 18:05:13 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 27 17:07:40 2016
    1313// Update Count     : 18
    1414//
     
    284284}
    285285
     286void Visitor::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) {
     287        maybeAccept( impCpCtorExpr->get_callExpr(), *this );
     288        acceptAll( impCpCtorExpr->get_tempDecls(), *this );
     289        acceptAll( impCpCtorExpr->get_returnDecls(), *this );
     290}
     291
    286292void Visitor::visit( UntypedValofExpr *valofExpr ) {
    287293        acceptAll( valofExpr->get_results(), *this );
     
    379385}
    380386
     387void Visitor::visit( ConstructorInit *ctorInit ) {
     388        maybeAccept( ctorInit->get_ctor(), *this );
     389        maybeAccept( ctorInit->get_init(), *this );
     390}
     391
    381392void Visitor::visit( Subrange *subrange ) {}
    382393
  • src/SynTree/Visitor.h

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // Visitor.h -- 
     7// Visitor.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Apr  1 17:26:55 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Thu Apr 14 15:30:58 2016
    1313// Update Count     : 7
    1414//
     
    6262        virtual void visit( MemberExpr *memberExpr );
    6363        virtual void visit( VariableExpr *variableExpr );
    64         virtual void visit( ConstantExpr *constantExpr ); 
     64        virtual void visit( ConstantExpr *constantExpr );
    6565        virtual void visit( SizeofExpr *sizeofExpr );
    6666        virtual void visit( AlignofExpr *alignofExpr );
     
    7676        virtual void visit( TypeExpr *typeExpr );
    7777        virtual void visit( AsmExpr *asmExpr );
     78        virtual void visit( ImplicitCopyCtorExpr *impCpCtorExpr );
    7879        virtual void visit( UntypedValofExpr *valofExpr );
    7980        virtual void visit( CompoundLiteralExpr *compLitExpr );
     
    9697        virtual void visit( SingleInit *singleInit );
    9798        virtual void visit( ListInit *listInit );
     99        virtual void visit( ConstructorInit *ctorInit );
    98100
    99101        virtual void visit( Subrange *subrange );
  • src/examples/array.c

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // array.c -- 
     7// array.c --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Wed May 27 17:56:53 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 18:13:52 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 27 17:21:52 2016
    1313// Update Count     : 3
    1414//
     
    2626// The first element is always at index 0.
    2727forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) )
    28 elt_type * begin( array_type array ) {
     28elt_type * begin( array_type * array ) {
    2929        return &array[ 0 ];
    3030}
     
    3232// The end iterator should point one past the last element.
    3333forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) )
    34 elt_type * end( array_type array ) {
     34elt_type * end( array_type * array ) {
    3535        return &array[ last( array ) ] + 1;
    3636}
  • src/examples/array.h

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // array.h -- 
     7// array.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Wed May 27 17:56:53 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 18:13:35 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 27 17:26:04 2016
    1313// Update Count     : 5
    1414//
     
    2626
    2727// A bounded array is an array that carries its maximum index with it.
    28 trait bounded_array( otype array_type, otype elt_type | array( array_type, elt_type ) ) {
    29         int last( array_type );
     28trait bounded_array( otype array_type, otype elt_type | array( array_type *, elt_type ) ) {
     29        int last( array_type * );
    3030};
    3131
     
    4141// return iterators corresponding to the first element and the one-past-the-end element, STL-style.
    4242forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) )
    43 elt_type *begin( array_type );
     43elt_type * begin( array_type * array );
    4444
     45// The end iterator should point one past the last element.
    4546forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) )
    46 elt_type *end( array_type );
     47elt_type * end( array_type * array );
    4748
    4849#endif // ARRAY_H
  • src/examples/io.c

    r9243a501 r7cc6bd6  
    1111// Created On       : Wed Mar  2 16:56:02 2016
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Wed Apr 13 23:03:14 2016
    14 // Update Count     : 22
     13// Last Modified On : Sat Apr 30 08:34:13 2016
     14// Update Count     : 27
    1515//
    1616
     
    5252                 | sepDisable | fc | dc | ldc | sepEnable | endl                // complex without separator
    5353                 | sepOn | s1 | sepOff | s2 | endl                                              // local separator removal
    54                  | s1 | "" | s2 | endl;                                                                 // C string withou separator
     54                 | s1 | "" | s2 | endl;                                                                 // C string without separator
    5555        sout | endl;
    5656
     
    7070                | "£" | 27
    7171                | "¥" | 27
     72                | "¡" | 27
    7273                | "¿" | 27
    7374                | "«" | 27
  • src/examples/vector_int.c

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // vector_int.c -- 
     7// vector_int.c --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Wed May 27 17:56:53 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 27 18:38:05 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 27 17:27:12 2016
    1313// Update Count     : 3
    1414//
     
    2222#define DEFAULT_CAPACITY 20
    2323
    24 vector_int vector_int_allocate() {
    25         return vector_int_allocate( DEFAULT_CAPACITY );
     24void ?{}( vector_int * vec ) {
     25        vec { DEFAULT_CAPACITY };
    2626}
    2727
    28 vector_int vector_int_allocate( int reserve ) {
    29         vector_int new_vector;
    30         new_vector.last = -1;
    31         new_vector.capacity = reserve;
    32         new_vector.data = malloc( sizeof( int ) * reserve );
    33         return new_vector;
     28void ?{}( vector_int * vec, int reserve ) {
     29        vec->last = -1;
     30        vec->capacity = reserve;
     31        vec->data = malloc( sizeof( int ) * reserve );
    3432}
    3533
    36 void vector_int_deallocate( vector_int vec ) {
    37         free( vec.data );
     34void ?{}( vector_int * vec, vector_int other ) {
     35        vec->last = other.last;
     36        vec->capacity = other.capacity;
     37        vec->data = malloc( sizeof( int ) * other.capacity );
     38        for (int i = 0; i < vec->last; i++) {
     39                vec->data[i] = other.data[i];
     40        }
     41}
     42
     43void ^?{}( vector_int * vec ) {
     44        free( vec->data );
    3845}
    3946
     
    5663// implement bounded_array
    5764
    58 lvalue int ?[?]( vector_int vec, int index ) {
    59         return vec.data[ index ];
     65lvalue int ?[?]( vector_int * vec, int index ) {
     66        return vec->data[ index ];
    6067}
    6168
    62 int last( vector_int vec ) {
    63         return vec.last;
     69int last( vector_int * vec ) {
     70        return vec->last;
    6471}
    6572
  • src/examples/vector_int.h

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // vector_int.h -- 
     7// vector_int.h --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Wed May 27 17:56:53 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 27 18:39:05 2015
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 27 17:26:59 2016
    1313// Update Count     : 2
    1414//
     
    2525} vector_int;
    2626
    27 vector_int vector_int_allocate();                                               // allocate vector with default capacity
    28 vector_int vector_int_allocate( int reserve );                  // allocate vector with specified capacity
    29 void vector_int_deallocate( vector_int );                               // deallocate vector's storage
     27void ?{}( vector_int * );                                                               // allocate vector with default capacity
     28void ?{}( vector_int *, int reserve );          // allocate vector with specified capacity
     29void ?{}( vector_int * vec, vector_int other ); // copy constructor
     30void ^?{}( vector_int * );                                                              // deallocate vector's storage
    3031
    3132void reserve( vector_int *vec, int reserve );                   // reserve more capacity
     
    3435// implement bounded_array
    3536
    36 lvalue int ?[?]( vector_int vec, int index );                   // access to arbitrary element (does not resize)
    37 int last( vector_int vec );                                                             // return last element
     37lvalue int ?[?]( vector_int * vec, int index );                 // access to arbitrary element (does not resize)
     38int last( vector_int * vec );                                                           // return last element
    3839
    3940#endif // VECTOR_INT_H
  • src/examples/vector_test.c

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // vector_test.c -- 
     7// vector_test.c --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Wed May 27 17:56:53 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb 17 12:23:55 2016
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Wed Apr 27 17:31:27 2016
    1313// Update Count     : 18
    1414//
     
    2020
    2121int main( void ) {
    22         vector_int vec = vector_int_allocate();
     22        vector_int vec;
    2323
    2424        // read in numbers until EOF or error
     
    3434
    3535        sout | "Array elements:" | endl;
    36         write( begin( vec ), end( vec ), sout );
     36        write( begin( &vec ), end( &vec ), sout );
    3737        sout | endl;
    3838
    3939        sout | "Array elements reversed:" | endl;
    40         write_reverse( begin( vec ), end( vec ), sout );
     40        write_reverse( begin( &vec ), end( &vec ), sout );
    4141        sout | endl;
    4242}
  • src/initialization.txt

    r9243a501 r7cc6bd6  
    3434sure that resolved initializers for all declarations are being
    3535generated.
     36
     37
     38------
     39
     40More recent email: (I am quoted; Richard is the responder)
     41> As far as I'm aware, the only way that I could currently get the correct
     42> results from the unification engine is by feeding it an expression that
     43> looks like "?=?( ((struct Y)x.y).a, 10 )", then picking out the pieces that
     44> I need (namely the correct choice for a). Does this seem like a reasonable
     45> approach to solve this problem?
     46
     47No, unfortunately. Initialization isn't being rewritten as assignment,
     48so you shouldn't allow the particular selection of assignment
     49operators that happen to be in scope (and which may include
     50user-defined operators) to guide the type resolution.
     51
     52I don't think there is any way to rewrite an initializer as a single
     53expression and have the resolver just do the right thing. I see the
     54algorithm as:
     55
     56For each alternative interpretation of the designator:
     57  Construct an expression that casts the initializer to the type of
     58    the designator
     59  Construct an AlternativeFinder and use it to find the lowest cost
     60    interpretation of the expression
     61  Add this interpretation to a list of possibilities
     62Go through the list of possibilities and pick the lowest cost
     63
     64As with many things in the resolver, it's conceptually simple but the
     65implementation may be a bit of a pain. It fits in with functions like
     66findSingleExpression, findIntegralExpression in Resolver.cc, although
     67it will be significantly more complicated than any of the existing
     68ones.
     69
     70
     71
  • src/libcfa/Makefile.am

    r9243a501 r7cc6bd6  
    66## file "LICENCE" distributed with Cforall.
    77##
    8 ## Makefile.am -- 
     8## Makefile.am --
    99##
    1010## Author           : Peter A. Buhr
     
    5151
    5252CFLAGS = -g -Wall -Wno-unused-function -B${abs_top_srcdir}/src/driver -XCFA -t  # TEMPORARY: does not build with -O2
    53 CC = ${abs_top_srcdir}/src/driver/cfa 
     53CC = ${abs_top_srcdir}/src/driver/cfa
    5454
    5555# extension-less header files are overridden by default make rules => explicitly override rule
     
    6767include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders}
    6868
     69CLEANFILES = libcfa-prelude.c
    6970MAINTAINERCLEANFILES += ${includedir}/*
  • src/libcfa/Makefile.in

    r9243a501 r7cc6bd6  
    111111AWK = @AWK@
    112112BACKEND_CC = @BACKEND_CC@
    113 CC = ${abs_top_srcdir}/src/driver/cfa 
     113CC = ${abs_top_srcdir}/src/driver/cfa
    114114CCDEPMODE = @CCDEPMODE@
    115115CFA_BINDIR = @CFA_BINDIR@
     
    219219cfaheaders = # limits
    220220include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders}
     221CLEANFILES = libcfa-prelude.c
    221222all: all-am
    222223
     
    457458
    458459clean-generic:
     460        -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
    459461
    460462distclean-generic:
  • src/libcfa/fstream

    r9243a501 r7cc6bd6  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Apr 19 20:44:10 2016
    13 // Update Count     : 84
     12// Last Modified On : Thu Apr 28 08:08:04 2016
     13// Update Count     : 88
    1414//
    1515
     
    2222struct ofstream {
    2323        void *file;
    24         int sepDefault;
    25         int sepOnOff;
     24        _Bool sepDefault;
     25        int sepOnOff;                                                                           // FIX ME: type should be _Bool
    2626        char separator[separateSize];
    2727}; // ofstream
  • src/libcfa/fstream.c

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // fstream.c -- 
     7// fstream.c --
    88//
    99// Author           : Peter A. Buhr
    1010// Created On       : Wed May 27 17:56:53 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr  6 17:55:27 2016
    13 // Update Count     : 176
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon May 02 15:14:52 2016
     13// Update Count     : 187
    1414//
    1515
     
    7575        if ( fclose( (FILE *)(os->file) ) == EOF ) {
    7676                perror( IO_MSG "close output" );
    77         } // if 
     77        } // if
    7878} // close
    7979
     
    9393int prtfmt( ofstream * os, const char fmt[], ... ) {
    9494    va_list args;
    95 
    9695    va_start( args, fmt );
    9796    int len = vfprintf( (FILE *)(os->file), fmt, args );
     
    103102        } // if
    104103    va_end( args );
     104
     105        sepReset( os );                                                                         // reset separator
    105106        return len;
    106107} // prtfmt
     
    139140        if ( fclose( (FILE *)(is->file) ) == EOF ) {
    140141                perror( IO_MSG "close input" );
    141         } // if 
     142        } // if
    142143} // close
    143144
     
    154155        return is;
    155156} // read
    156  
     157
    157158ifstream *ungetc( ifstream * is, char c ) {
    158159        if ( fail( is ) ) {
  • src/libcfa/iostream.c

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // iostream.c -- 
     7// iostream.c --
    88//
    99// Author           : Peter A. Buhr
    1010// Created On       : Wed May 27 17:56:53 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Apr  6 16:13:29 2016
    13 // Update Count     : 278
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Mon May 02 15:13:55 2016
     13// Update Count     : 302
    1414//
    1515
     
    3434ostype * ?|?( ostype *os, short int si ) {
    3535        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    36         sepReset( os );
    3736        prtfmt( os, "%hd", si );
    3837        return os;
     
    4241ostype * ?|?( ostype *os, unsigned short int usi ) {
    4342        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    44         sepReset( os );
    4543        prtfmt( os, "%hu", usi );
    4644        return os;
     
    5048ostype * ?|?( ostype *os, int i ) {
    5149        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    52         sepReset( os );
    5350        prtfmt( os, "%d", i );
    5451        return os;
     
    5855ostype * ?|?( ostype *os, unsigned int ui ) {
    5956        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    60         sepReset( os );
    6157        prtfmt( os, "%u", ui );
    6258        return os;
     
    6662ostype * ?|?( ostype *os, long int li ) {
    6763        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    68         sepReset( os );
    6964        prtfmt( os, "%ld", li );
    7065        return os;
     
    7469ostype * ?|?( ostype *os, unsigned long int uli ) {
    7570        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    76         sepReset( os );
    7771        prtfmt( os, "%lu", uli );
    7872        return os;
     
    8276ostype * ?|?( ostype *os, long long int lli ) {
    8377        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    84         sepReset( os );
    8578        prtfmt( os, "%lld", lli );
    8679        return os;
     
    9083ostype * ?|?( ostype *os, unsigned long long int ulli ) {
    9184        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    92         sepReset( os );
    9385        prtfmt( os, "%llu", ulli );
    9486        return os;
     
    9890ostype * ?|?( ostype *os, float f ) {
    9991        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    100         sepReset( os );
    10192        prtfmt( os, "%g", f );
    10293        return os;
     
    10697ostype * ?|?( ostype *os, double d ) {
    10798        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    108         sepReset( os );
    10999        prtfmt( os, "%.*lg", DBL_DIG, d );
    110100        return os;
     
    114104ostype * ?|?( ostype *os, long double ld ) {
    115105        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    116         sepReset( os );
    117106        prtfmt( os, "%.*Lg", LDBL_DIG, ld );
    118107        return os;
     
    155144                // opening delimiters
    156145                ['('] : Open, ['['] : Open, ['{'] : Open,
    157                 ['$'] : Open, [(unsigned char)'£'] : Open, [(unsigned char)'¥'] : Open, [(unsigned char)'¿'] : Open, [(unsigned char)'«'] : Open,
     146                ['$'] : Open, [(unsigned char)'£'] : Open, [(unsigned char)'¥'] : Open,
     147                [(unsigned char)'¡'] : Open, [(unsigned char)'¿'] : Open, [(unsigned char)'«'] : Open,
    158148                // closing delimiters
    159149                [','] : Close, ['.'] : Close, [':'] : Close, [';'] : Close, ['!'] : Close, ['?'] : Close,
     
    162152                // opening-closing delimiters
    163153                ['\''] : OpenClose, ['`'] : OpenClose, ['"'] : OpenClose,
    164                 ['\f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace
     154                [' '] : OpenClose, ['\f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace
    165155        }; // mask
    166156
    167         int len = strlen( cp );
    168         // null string => no separator
    169   if ( len == 0 ) { sepOff( os ); return os; }
     157  if ( cp[0] == '\0' ) { sepOff( os ); return os; }             // null string => no separator
     158
    170159        // first character IS NOT spacing or closing punctuation => add left separator
    171160        unsigned char ch = cp[0];                                                       // must make unsigned
     
    173162                prtfmt( os, "%s", sepGet( os ) );
    174163        } // if
     164
     165        // if string starts line, must reset to determine open state because separator is off
     166        sepReset( os );                                                                         // reset separator
     167
    175168        // last character IS spacing or opening punctuation => turn off separator for next item
    176         unsigned int posn = len - 1;
     169        unsigned int len = strlen( cp ), posn = len - 1;
    177170        ch = cp[posn];                                                                          // must make unsigned
    178         if ( mask[ ch ] == Open || mask[ ch ] == OpenClose ) {
     171        if ( sepPrt( os ) && mask[ ch ] != Open && mask[ ch ] != OpenClose ) {
     172                sepOn( os );
     173        } else {
    179174                sepOff( os );
    180         } else {
    181                 sepOn( os );
    182175        } // if
    183176        return write( os, cp, len );
     
    187180ostype * ?|?( ostype *os, const void *p ) {
    188181        if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) );
    189         sepReset( os );
    190182        prtfmt( os, "%p", p );
    191183        return os;
     
    193185
    194186
    195 forall( dtype ostype | ostream( ostype ) ) 
     187forall( dtype ostype | ostream( ostype ) )
    196188ostype * ?|?( ostype *os, ostype * (* manip)( ostype * ) ) {
    197189        return manip( os );
    198190} // ?|?
    199191
    200 forall( dtype ostype | ostream( ostype ) ) 
     192forall( dtype ostype | ostream( ostype ) )
    201193ostype * endl( ostype * os ) {
    202194        os | '\n';
     
    206198} // endl
    207199
    208 forall( dtype ostype | ostream( ostype ) ) 
     200forall( dtype ostype | ostream( ostype ) )
    209201ostype * sepOn( ostype * os ) {
    210202        sepOn( os );
     
    212204} // sepOn
    213205
    214 forall( dtype ostype | ostream( ostype ) ) 
     206forall( dtype ostype | ostream( ostype ) )
    215207ostype * sepOff( ostype * os ) {
    216208        sepOff( os );
     
    218210} // sepOff
    219211
    220 forall( dtype ostype | ostream( ostype ) ) 
     212forall( dtype ostype | ostream( ostype ) )
    221213ostype * sepEnable( ostype * os ) {
    222214        sepEnable( os );
     
    224216} // sepEnable
    225217
    226 forall( dtype ostype | ostream( ostype ) ) 
     218forall( dtype ostype | ostream( ostype ) )
    227219ostype * sepDisable( ostype * os ) {
    228220        sepDisable( os );
     
    344336} // ?|?
    345337
    346 _Istream_cstrUC cstr( char * s ) { _Istream_cstrUC s = { s }; return s; }
     338_Istream_cstrUC cstr( char * str ) { _Istream_cstrUC s = { str }; return s; }
    347339forall( dtype istype | istream( istype ) )
    348340istype * ?|?( istype * is, _Istream_cstrUC cstr ) {
     
    351343} // cstr
    352344
    353 _Istream_cstrC cstr( char * s, int size ) { _Istream_cstrC s = { s, size }; return s; }
     345_Istream_cstrC cstr( char * str, int size ) { _Istream_cstrC s = { str, size }; return s; }
    354346forall( dtype istype | istream( istype ) )
    355347istype * ?|?( istype * is, _Istream_cstrC cstr ) {
  • src/libcfa/prelude.cf

    r9243a501 r7cc6bd6  
    11# 2 "prelude.cf"  // needed for error messages from this file
    2 //                               -*- Mode: C -*- 
    3 // 
     2//                               -*- Mode: C -*-
     3//
    44// Copyright (C) Glen Ditchfield 1994, 1999
    5 // 
     5//
    66// prelude.cf -- Standard Cforall Preample for C99
    7 // 
     7//
    88// Author           : Glen Ditchfield
    99// Created On       : Sat Nov 29 07:23:41 2014
     
    117117forall( ftype FT ) lvalue FT             *?( FT * );
    118118
    119 _Bool                   +?( _Bool ),                    -?( _Bool ),                    ~?( _Bool );         
    120 signed int              +?( signed int ),               -?( signed int ),               ~?( signed int );           
    121 unsigned int            +?( unsigned int ),             -?( unsigned int ),             ~?( unsigned int );         
    122 signed long int         +?( signed long int ),          -?( signed long int ),          ~?( signed long int );       
    123 unsigned long int       +?( unsigned long int ),        -?( unsigned long int ),        ~?( unsigned long int );             
    124 signed long long int    +?( signed long long int ),     -?( signed long long int ),     ~?( signed long long int );   
    125 unsigned long long int  +?( unsigned long long int ),   -?( unsigned long long int ),   ~?( unsigned long long int ); 
     119_Bool                   +?( _Bool ),                    -?( _Bool ),                    ~?( _Bool );
     120signed int              +?( signed int ),               -?( signed int ),               ~?( signed int );
     121unsigned int            +?( unsigned int ),             -?( unsigned int ),             ~?( unsigned int );
     122signed long int         +?( signed long int ),          -?( signed long int ),          ~?( signed long int );
     123unsigned long int       +?( unsigned long int ),        -?( unsigned long int ),        ~?( unsigned long int );
     124signed long long int    +?( signed long long int ),     -?( signed long long int ),     ~?( signed long long int );
     125unsigned long long int  +?( unsigned long long int ),   -?( unsigned long long int ),   ~?( unsigned long long int );
    126126float                   +?( float ),                    -?( float );
    127127double                  +?( double ),                   -?( double );
     
    627627                        ?+=?( long double _Complex *, long double _Complex ), ?+=?( volatile long double _Complex *, long double _Complex ),
    628628                        ?-=?( long double _Complex *, long double _Complex ), ?-=?( volatile long double _Complex *, long double _Complex );
     629
     630
     631
     632
     633
     634// ------------------------------------------------------------
     635//
     636// Section ??? Constructors and Destructors
     637//
     638// ------------------------------------------------------------
     639
     640// default ctor
     641void    ?{}( _Bool * ),                         ?{}( volatile _Bool * );
     642void    ?{}( char * ),  ?{}( volatile char * );
     643void    ?{}( unsigned char * ), ?{}( volatile unsigned char * );
     644void    ?{}( char signed * ),                   ?{}( volatile char signed * );
     645void    ?{}( int short * ),                             ?{}( volatile int short * );
     646void    ?{}( int short unsigned * ),    ?{}( volatile int short unsigned * );
     647void    ?{}( signed int * ),                    ?{}( volatile signed int * );
     648void    ?{}( unsigned int * ),                  ?{}( volatile unsigned int * );
     649void    ?{}( signed long int * ),               ?{}( volatile signed long int * );
     650void    ?{}( unsigned long int * ),             ?{}( volatile unsigned long int * );
     651void    ?{}( signed long long int * ),          ?{}( volatile signed long long int * );
     652void    ?{}( unsigned long long int * ),        ?{}( volatile unsigned long long int * );
     653void    ?{}( float * ),                         ?{}( volatile float * );
     654void    ?{}( double * ),                        ?{}( volatile double * );
     655void    ?{}( long double * ),                   ?{}( volatile long double * );
     656void    ?{}( float _Complex * ),                ?{}( volatile float _Complex * );
     657void    ?{}( double _Complex * ),               ?{}( volatile double _Complex * );
     658void    ?{}( long double _Complex * ),          ?{}( volatile long double _Complex * );
     659
     660// copy ctor
     661void    ?{}( _Bool *, _Bool ),                                  ?{}( volatile _Bool *, _Bool );
     662void    ?{}( char *, char ),    ?{}( volatile char *, char );
     663void    ?{}( unsigned char *, unsigned char ),                  ?{}( volatile unsigned char *, unsigned char );
     664void    ?{}( char signed *, char signed ),                      ?{}( volatile char signed *, char signed );
     665void    ?{}( int short *, int short ),                          ?{}( volatile int short *, int short );
     666void    ?{}( int short unsigned *, int short unsigned ),        ?{}( volatile int short unsigned *, int short unsigned );
     667void    ?{}( signed int *, signed int),                         ?{}( volatile signed int *, signed int );
     668void    ?{}( unsigned int *, unsigned int),                     ?{}( volatile unsigned int *, unsigned int );
     669void    ?{}( signed long int *, signed long int),               ?{}( volatile signed long int *, signed long int );
     670void    ?{}( unsigned long int *, unsigned long int),           ?{}( volatile unsigned long int *, unsigned long int );
     671void    ?{}( signed long long int *, signed long long int),     ?{}( volatile signed long long int *, signed long long int );
     672void    ?{}( unsigned long long int *, unsigned long long int), ?{}( volatile unsigned long long int *, unsigned long long int );
     673void    ?{}( float *, float),                                   ?{}( volatile float *, float );
     674void    ?{}( double *, double),                                 ?{}( volatile double *, double );
     675void    ?{}( long double *, long double),                       ?{}( volatile long double *, long double );
     676void    ?{}( float _Complex *, float _Complex),                 ?{}( volatile float _Complex *, float _Complex );
     677void    ?{}( double _Complex *, double _Complex),               ?{}( volatile double _Complex *, double _Complex );
     678void    ?{}( long double _Complex *, long double _Complex),     ?{}( volatile long double _Complex *, long double _Complex );
     679
     680// dtor
     681void    ^?{}( _Bool * ),                        ^?{}( volatile _Bool * );
     682void    ^?{}( char * ), ^?{}( volatile char * );
     683void    ^?{}( char unsigned * ),                        ^?{}( volatile char unsigned * );
     684void    ^?{}( char signed * ),                  ^?{}( volatile char signed * );
     685void    ^?{}( int short * ),                            ^?{}( volatile int short * );
     686void    ^?{}( int short unsigned * ),   ^?{}( volatile int short unsigned * );
     687void    ^?{}( signed int * ),                   ^?{}( volatile signed int * );
     688void    ^?{}( unsigned int * ),                 ^?{}( volatile unsigned int * );
     689void    ^?{}( signed long int * ),              ^?{}( volatile signed long int * );
     690void    ^?{}( unsigned long int * ),            ^?{}( volatile unsigned long int * );
     691void    ^?{}( signed long long int * ),         ^?{}( volatile signed long long int * );
     692void    ^?{}( unsigned long long int * ),       ^?{}( volatile unsigned long long int * );
     693void    ^?{}( float * ),                        ^?{}( volatile float * );
     694void    ^?{}( double * ),                       ^?{}( volatile double * );
     695void    ^?{}( long double * ),                  ^?{}( volatile long double * );
     696void    ^?{}( float _Complex * ),               ^?{}( volatile float _Complex * );
     697void    ^?{}( double _Complex * ),              ^?{}( volatile double _Complex * );
     698void    ^?{}( long double _Complex * ),         ^?{}( volatile long double _Complex * );
     699
     700// // default ctor
     701// forall( dtype DT ) void       ?{}(                DT ** );
     702// forall( dtype DT ) void       ?{}( const          DT ** );
     703// forall( dtype DT ) void       ?{}(       volatile DT ** );
     704// forall( dtype DT ) void       ?{}( const volatile DT ** );
     705
     706// // copy ctor
     707// forall( dtype DT ) void       ?{}(                DT **, DT* );
     708// forall( dtype DT ) void       ?{}( const          DT **, DT* );
     709// forall( dtype DT ) void       ?{}(       volatile DT **, DT* );
     710// forall( dtype DT ) void       ?{}( const volatile DT **, DT* );
     711
     712// // dtor
     713// forall( dtype DT ) void      ^?{}(                DT ** );
     714// forall( dtype DT ) void      ^?{}( const          DT ** );
     715// forall( dtype DT ) void      ^?{}(       volatile DT ** );
     716// forall( dtype DT ) void      ^?{}( const volatile DT ** );
     717
     718// copied from assignment section
     719// copy constructors
     720forall( ftype FT ) void ?{}( FT **, FT * );
     721forall( ftype FT ) void ?{}( FT * volatile *, FT * );
     722
     723forall( dtype DT ) void ?{}(                 DT *          *,                   DT * );
     724forall( dtype DT ) void ?{}(                 DT * volatile *,                   DT * );
     725forall( dtype DT ) void ?{}( const           DT *          *,                   DT * );
     726forall( dtype DT ) void ?{}( const           DT * volatile *,                   DT * );
     727forall( dtype DT ) void ?{}( const           DT *          *, const             DT * );
     728forall( dtype DT ) void ?{}( const           DT * volatile *, const             DT * );
     729forall( dtype DT ) void ?{}(       volatile  DT *          *,                   DT * );
     730forall( dtype DT ) void ?{}(       volatile  DT * volatile *,                   DT * );
     731forall( dtype DT ) void ?{}(       volatile  DT *          *,       volatile    DT * );
     732forall( dtype DT ) void ?{}(       volatile  DT * volatile *,       volatile    DT * );
     733
     734forall( dtype DT ) void ?{}( const volatile  DT *          *,                   DT * );
     735forall( dtype DT ) void ?{}( const volatile  DT * volatile *,                   DT * );
     736forall( dtype DT ) void ?{}( const volatile  DT *          *, const             DT * );
     737forall( dtype DT ) void ?{}( const volatile  DT * volatile *, const             DT * );
     738forall( dtype DT ) void ?{}( const volatile  DT *          *,       volatile    DT * );
     739forall( dtype DT ) void ?{}( const volatile  DT * volatile *,       volatile    DT * );
     740forall( dtype DT ) void ?{}( const volatile  DT *          *, const volatile    DT * );
     741forall( dtype DT ) void ?{}( const volatile  DT * volatile *, const volatile    DT * );
     742
     743forall( dtype DT ) void ?{}(                 DT *          *,                   void * );
     744forall( dtype DT ) void ?{}(                 DT * volatile *,                   void * );
     745forall( dtype DT ) void ?{}( const           DT *          *,                   void * );
     746forall( dtype DT ) void ?{}( const           DT * volatile *,                   void * );
     747forall( dtype DT ) void ?{}( const           DT *          *, const             void * );
     748forall( dtype DT ) void ?{}( const           DT * volatile *, const             void * );
     749forall( dtype DT ) void ?{}(       volatile  DT *          *,                   void * );
     750forall( dtype DT ) void ?{}(       volatile  DT * volatile *,                   void * );
     751forall( dtype DT ) void ?{}(       volatile  DT *          *,       volatile    void * );
     752forall( dtype DT ) void ?{}(       volatile  DT * volatile *,       volatile    void * );
     753
     754forall( dtype DT ) void ?{}( const volatile  DT *          *,                   void * );
     755forall( dtype DT ) void ?{}( const volatile  DT * volatile *,                   void * );
     756forall( dtype DT ) void ?{}( const volatile  DT *          *, const             void * );
     757forall( dtype DT ) void ?{}( const volatile  DT * volatile *, const             void * );
     758forall( dtype DT ) void ?{}( const volatile  DT *          *,       volatile    void * );
     759forall( dtype DT ) void ?{}( const volatile  DT * volatile *,       volatile    void * );
     760forall( dtype DT ) void ?{}( const volatile  DT *          *, const volatile    void * );
     761forall( dtype DT ) void ?{}( const volatile  DT * volatile *, const volatile    void * );
     762
     763forall( dtype DT ) void ?{}(                 void *          *,                 DT * );
     764forall( dtype DT ) void ?{}(                 void * volatile *,                 DT * );
     765forall( dtype DT ) void ?{}( const           void *          *,                 DT * );
     766forall( dtype DT ) void ?{}( const           void * volatile *,                 DT * );
     767forall( dtype DT ) void ?{}( const           void *          *, const           DT * );
     768forall( dtype DT ) void ?{}( const           void * volatile *, const           DT * );
     769forall( dtype DT ) void ?{}(        volatile void *          *,                 DT * );
     770forall( dtype DT ) void ?{}(        volatile void * volatile *,                 DT * );
     771forall( dtype DT ) void ?{}(        volatile void *          *,       volatile  DT * );
     772forall( dtype DT ) void ?{}(        volatile void * volatile *,       volatile  DT * );
     773forall( dtype DT ) void ?{}( const volatile void *           *,                 DT * );
     774forall( dtype DT ) void ?{}( const volatile void * volatile *,                  DT * );
     775forall( dtype DT ) void ?{}( const volatile void *           *, const           DT * );
     776forall( dtype DT ) void ?{}( const volatile void * volatile *, const            DT * );
     777forall( dtype DT ) void ?{}( const volatile void *           *,       volatile  DT * );
     778forall( dtype DT ) void ?{}( const volatile void * volatile *,        volatile  DT * );
     779forall( dtype DT ) void ?{}( const volatile void *           *, const volatile  DT * );
     780forall( dtype DT ) void ?{}( const volatile void * volatile *, const volatile   DT * );
     781
     782void    ?{}(                void *          *,                void * );
     783void    ?{}(                void * volatile *,                void * );
     784void    ?{}( const          void *          *,                void * );
     785void    ?{}( const          void * volatile *,                void * );
     786void    ?{}( const          void *          *, const          void * );
     787void    ?{}( const          void * volatile *, const          void * );
     788void    ?{}(       volatile void *          *,                void * );
     789void    ?{}(       volatile void * volatile *,                void * );
     790void    ?{}(       volatile void *          *,       volatile void * );
     791void    ?{}(       volatile void * volatile *,       volatile void * );
     792void    ?{}( const volatile void *          *,                void * );
     793void    ?{}( const volatile void * volatile *,                void * );
     794void    ?{}( const volatile void *          *, const          void * );
     795void    ?{}( const volatile void * volatile *, const          void * );
     796void    ?{}( const volatile void *          *,       volatile void * );
     797void    ?{}( const volatile void * volatile *,       volatile void * );
     798void    ?{}( const volatile void *          *, const volatile void * );
     799void    ?{}( const volatile void * volatile *, const volatile void * );
     800
     801//forall( dtype DT ) void ?{}(              DT *          *, forall( dtype DT2 ) const DT2 * );
     802//forall( dtype DT ) void ?{}(              DT * volatile *, forall( dtype DT2 ) const DT2 * );
     803forall( dtype DT ) void ?{}( const          DT *          *, forall( dtype DT2 ) const DT2 * );
     804forall( dtype DT ) void ?{}( const          DT * volatile *, forall( dtype DT2 ) const DT2 * );
     805//forall( dtype DT ) void ?{}( volatile     DT *          *, forall( dtype DT2 ) const DT2 * );
     806//forall( dtype DT ) void ?{}( volatile     DT * volatile *, forall( dtype DT2 ) const DT2 * );
     807forall( dtype DT ) void ?{}( const volatile DT *          *, forall( dtype DT2 ) const DT2 * );
     808forall( dtype DT ) void ?{}( const volatile DT * volatile *, forall( dtype DT2 ) const DT2 * );
     809
     810forall( ftype FT ) void ?{}( FT *          *, forall( ftype FT2 ) FT2 * );
     811forall( ftype FT ) void ?{}( FT * volatile *, forall( ftype FT2 ) FT2 * );
     812
     813// default ctors
     814forall( ftype FT ) void ?{}( FT *          * );
     815forall( ftype FT ) void ?{}( FT * volatile * );
     816
     817forall( dtype DT ) void ?{}(                 DT *          *);
     818forall( dtype DT ) void ?{}(                 DT * volatile *);
     819forall( dtype DT ) void ?{}( const           DT *          *);
     820forall( dtype DT ) void ?{}( const           DT * volatile *);
     821forall( dtype DT ) void ?{}(       volatile  DT *          *);
     822forall( dtype DT ) void ?{}(       volatile  DT * volatile *);
     823forall( dtype DT ) void ?{}( const volatile  DT *          *);
     824forall( dtype DT ) void ?{}( const volatile  DT * volatile *);
     825
     826void    ?{}(                void *          *);
     827void    ?{}(                void * volatile *);
     828void    ?{}( const          void *          *);
     829void    ?{}( const          void * volatile *);
     830void    ?{}(       volatile void *          *);
     831void    ?{}(       volatile void * volatile *);
     832void    ?{}( const volatile void *          *);
     833void    ?{}( const volatile void * volatile *);
     834
     835// dtors
     836forall( ftype FT ) void ^?{}( FT *         * );
     837forall( ftype FT ) void ^?{}( FT * volatile * );
     838
     839forall( dtype DT ) void ^?{}(                DT *          *);
     840forall( dtype DT ) void ^?{}(                DT * volatile *);
     841forall( dtype DT ) void ^?{}( const          DT *          *);
     842forall( dtype DT ) void ^?{}( const          DT * volatile *);
     843forall( dtype DT ) void ^?{}(      volatile  DT *          *);
     844forall( dtype DT ) void ^?{}(      volatile  DT * volatile *);
     845forall( dtype DT ) void ^?{}( const volatile  DT *         *);
     846forall( dtype DT ) void ^?{}( const volatile  DT * volatile *);
     847
     848void    ^?{}(               void *          *);
     849void    ^?{}(               void * volatile *);
     850void    ^?{}( const         void *          *);
     851void    ^?{}( const         void * volatile *);
     852void    ^?{}(      volatile void *          *);
     853void    ^?{}(      volatile void * volatile *);
     854void    ^?{}( const volatile void *         *);
     855void    ^?{}( const volatile void * volatile *);
  • src/libcfa/stdlib

    r9243a501 r7cc6bd6  
    1010// Created On       : Thu Jan 28 17:12:35 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr 21 07:55:21 2016
    13 // Update Count     : 95
     12// Last Modified On : Wed Apr 27 22:03:29 2016
     13// Update Count     : 96
    1414//
    1515
     
    4545
    4646forall( otype T ) T * aligned_alloc( size_t alignment );
    47 forall( otype T ) T * memalign( size_t alignment );
     47forall( otype T ) T * memalign( size_t alignment );             // deprecated
    4848forall( otype T ) int posix_memalign( T ** ptr, size_t alignment );
    4949
  • src/libcfa/stdlib.c

    r9243a501 r7cc6bd6  
    1010// Created On       : Thu Jan 28 17:10:29 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Apr 21 07:58:29 2016
    13 // Update Count     : 165
     12// Last Modified On : Thu Apr 28 07:54:21 2016
     13// Update Count     : 166
    1414//
    1515
     
    213213//---------------------------------------
    214214
    215 forall( otype T | { T ?/?( T, T ); T ?%?( T, T ); } )
    216 [ T, T ] div( T t1, T t2 ) { /* return [ t1 / t2, t1 % t2 ]; */ }
     215// forall( otype T | { T ?/?( T, T ); T ?%?( T, T ); } )
     216// [ T, T ] div( T t1, T t2 ) { return [ t1 / t2, t1 % t2 ]; }
    217217
    218218//---------------------------------------
  • src/main.cc

    r9243a501 r7cc6bd6  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // main.cc -- 
     7// main.cc --
    88//
    99// Author           : Richard C. Bilson
    1010// Created On       : Fri May 15 23:12:02 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jan 27 22:20:20 2016
    13 // Update Count     : 199
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri Apr 29 12:02:21 2016
     13// Update Count     : 200
    1414//
    1515
     
    4040#include "MakeLibCfa.h"
    4141#include "InitTweak/Mutate.h"
    42 #include "InitTweak/RemoveInit.h"
     42#include "InitTweak/GenInit.h"
     43#include "InitTweak/FixInit.h"
    4344//#include "Explain/GenProlog.h"
    4445//#include "Try/Visit.h"
     
    5556
    5657static void parse( FILE * input, LinkageSpec::Type t, bool shouldExit = false );
    57 static void dump( std::list< Declaration * > & translationUnit );
     58static void dump( std::list< Declaration * > & translationUnit, std::ostream & out = std::cout );
    5859
    5960bool
    6061        astp = false,
    6162        bresolvep = false,
     63        bboxp = false,
     64        ctorinitp = false,
    6265        exprp = false,
    6366        expraltp = false,
     
    7477        codegenp = false;
    7578
    76 enum { Ast, Bresolver, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, };
     79enum { Ast, Bbox, Bresolver, CtorInitFix, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, };
    7780
    7881static struct option long_opts[] = {
    7982        { "ast", no_argument, 0, Ast },
     83        { "before-box", no_argument, 0, Bbox },
    8084        { "before-resolver", no_argument, 0, Bresolver },
     85        { "ctorinitfix", no_argument, 0, CtorInitFix },
    8186        { "expr", no_argument, 0, Expr },
    8287        { "expralt", no_argument, 0, ExprAlt },
     
    100105
    101106        opterr = 0;                                                                                     // prevent getopt from printing error messages
    102        
     107
    103108        int c;
    104         while ( (c = getopt_long( argc, argv, "abefglnpqrstvyzD:", long_opts, &long_index )) != -1 ) {
     109        while ( (c = getopt_long( argc, argv, "abBcefFglnpqrstvyzD:", long_opts, &long_index )) != -1 ) {
    105110                switch ( c ) {
    106111                  case Ast:
     
    111116                  case 'b':                                                                             // print before resolver steps
    112117                        bresolvep = true;
     118                        break;
     119                  case 'B':                                                                             // print before resolver steps
     120                        bboxp = true;
     121                        break;
     122                  case CtorInitFix:
     123                  case 'c':
     124                        ctorinitp = true;
    113125                        break;
    114126                  case Expr:
     
    187199                        output = new ofstream( argv[ optind ] );
    188200                } // if
    189        
     201
    190202                Parser::get_parser().set_debug( grammarp );
    191203
     
    208220                                        exit( 1 );
    209221                                } // if
    210                    
     222
    211223                                parse( prelude, LinkageSpec::Intrinsic );
    212224                        } // if
    213225                } // if
    214226
    215                 parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp );     
    216  
     227                parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp );
     228
    217229                if ( parsep ) {
    218230                        Parser::get_parser().get_parseTree()->printList( std::cout );
     
    249261                OPTPRINT( "mutate" )
    250262                ControlStruct::mutate( translationUnit );
    251                 OPTPRINT( "fixNames" ) 
     263                OPTPRINT( "fixNames" )
    252264                CodeGen::fixNames( translationUnit );
    253                 OPTPRINT( "tweak" )
    254                 InitTweak::tweak( translationUnit );
     265                OPTPRINT( "tweakInit" )
     266                InitTweak::genInit( translationUnit );
    255267
    256268                if ( libcfap ) {
     
    268280                if ( exprp ) {
    269281                        dump( translationUnit );
     282                        return 0;
     283                }
     284
     285                OPTPRINT( "fixInit" )
     286                // fix ObjectDecl - replaces ConstructorInit nodes
     287                InitTweak::fix( translationUnit );
     288                if ( ctorinitp ) {
     289                        dump ( translationUnit );
     290                        return 0;
    270291                }
    271292
     
    276297                OPTPRINT( "convertLvalue" )
    277298                GenPoly::convertLvalue( translationUnit );
     299
     300                if ( bboxp ) {
     301                        dump( translationUnit );
     302                        return 0;
     303                }
    278304                OPTPRINT( "box" )
    279305                GenPoly::box( translationUnit );
    280                
     306
    281307                // print tree right before code generation
    282308                if ( codegenp ) {
     
    292318        } catch ( SemanticError &e ) {
    293319                if ( errorp ) {
    294                         dump( translationUnit );
     320                        std::cerr << "---AST at error:---" << std::endl;
     321                        dump( translationUnit, std::cerr );
     322                        std::cerr << std::endl << "---End of AST, begin error message:---\n" << std::endl;
    295323                }
    296324                e.print( std::cerr );
     
    314342        } // try
    315343
     344        deleteAll( translationUnit );
    316345        return 0;
    317346} // main
     
    331360}
    332361
    333 static void dump( std::list< Declaration * > & translationUnit ) {
     362static void dump( std::list< Declaration * > & translationUnit, std::ostream & out ) {
    334363        std::list< Declaration * > decls;
    335364        if ( noprotop ) {
    336                 filter( translationUnit.begin(), translationUnit.end(), 
     365                filter( translationUnit.begin(), translationUnit.end(),
    337366                                std::back_inserter( decls ), notPrelude );
    338367        } else {
     
    340369        }
    341370
    342         printAll( decls, std::cout );
     371        printAll( decls, out );
    343372        deleteAll( translationUnit );
    344373}
Note: See TracChangeset for help on using the changeset viewer.