Changes in / [bb8ea30:d668182]


Ignore:
Files:
8 added
2 deleted
73 edited

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/common.tex

    rbb8ea30 rd668182  
    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 : Wed May  4 08:01:10 2016
     14%% Update Count     : 54
    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}
     
    129132% blocks and titles
    130133\newcommand{\define}[1]{\emph{#1\/}\index{#1}}
    131 \newcommand{\rewrite}{\(\Rightarrow\)}
    132134\newcommand{\rewriterules}{\paragraph{Rewrite Rules}~\par\noindent}
    133135\newcommand{\examples}{\paragraph{Examples}~\par\noindent}
     
    141143\newcommand{\lhs}[1]{\par{\emph{#1:}}\index{#1@{\emph{#1}}|italic}}
    142144\newcommand{\rhs}{\hfil\break\hbox{\hskip1in}}
    143 \newcommand{\oldlhs}[1]{\emph{#1: \ldots}\index{#1@{\emph{#1}}|italic}}
     145\newcommand{\oldlhs}[1]{\emph{#1: \dots}\index{#1@{\emph{#1}}|italic}}
    144146\newcommand{\nonterm}[1]{\emph{#1\/}\index{#1@{\emph{#1}}|italic}}
    145147\newcommand{\opt}{$_{opt}$\ }
     
    179181                fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,__label__,lvalue,_Noreturn,otype,restrict,_Static_assert,
    180182                _Thread_local,throw,throwResume,trait,try,typeof,__typeof,__typeof__,},
    181         moredelim=**[is][\color{red}]{`}{`}, % red highlighting of program text
    182183}%
    183184
     
    186187columns=flexible,
    187188basicstyle=\sf\relsize{-1},
     189stringstyle=\tt,
    188190tabsize=4,
    189191xleftmargin=\parindent,
    190 escapechar=@,
     192extendedchars=true,
     193escapechar=§,
    191194mathescape=true,
    192195keepspaces=true,
    193196showstringspaces=false,
    194197showlines=true,
    195 aboveskip=6pt,
    196 belowskip=4pt,
    197 literate={\\`}{\raisebox{0.3ex}{\ttfamily\upshape \hspace*{-2pt}`}}1, % escape \`, otherwise used for red highlighting
     198aboveskip=4pt,
     199belowskip=2pt,
     200moredelim=**[is][\color{red}]{®}{®}, % red highlighting
     201% moredelim=**[is][\color{blue}]{¢}{¢}, % blue highlighting
     202moredelim=[is][\lstset{keywords={}}]{¶}{¶}, % temporarily turn off keywords
     203% literate={\\`}{\raisebox{0.3ex}{\ttfamily\upshape \hspace*{-2pt}`}}1, % escape \`, otherwise used for red highlighting
     204literate={...}{{$\dots$}}1 {<-}{{$\leftarrow$}}1 {=>}{{$\Rightarrow$}}1,
    198205}%
     206
     207\lstMakeShortInline©    % single-character for \lstinline
    199208
    200209\makeatletter
     
    203212\lst@ProcessOther{"22}{\lst@ttfamily{"}{\raisebox{0.3ex}{\ttfamily\upshape "}}} % replace double quote
    204213\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
     214\lst@ProcessOther{"2D}{\lst@ttfamily{-}{\textbf{\texttt{-}}}} % replace minus
     215\lst@ProcessOther{"3C}{\lst@ttfamily{<}{\textbf{\texttt{<}}}} % replace less than
     216\lst@ProcessOther{"3E}{\lst@ttfamily{>}{\textbf{\texttt{>}}}} % replace greater than
    208217\lst@ProcessOther{"5E}{\raisebox{0.4ex}{$\scriptstyle\land\,$}} % replace circumflex
    209218\lst@ProcessOther{"5F}{\lst@ttfamily{\char95}{{\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}}} % replace underscore
  • doc/refrat/refrat.tex

    rbb8ea30 rd668182  
    1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%%
    2 %%
     1%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%%``%%
    32%% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo
    43%%
     
    1110%% Created On       : Wed Apr  6 14:52:25 2016
    1211%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sat Apr  9 10:19:12 2016
    14 %% Update Count     : 8
     12%% Last Modified On : Tue May  3 18:00:28 2016
     13%% Update Count     : 64
    1514%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1615
    1716% requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended
     17
     18% inline code ©...© (copyright symbol) emacs: C-q M-)
     19% red highlighting ®...® (registered trademark sumbol) emacs: C-q M-.
     20% latex escape §...§ (section symbol) emacs: C-q M-'
     21% keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^
     22% math escape $...$ (dollar symbol)
    1823
    1924\documentclass[openright,twoside]{report}
     
    2126
    2227% Latex packages used in the document.
     28\usepackage[T1]{fontenc}                                % allow Latin1 (extended ASCII) characters
     29\usepackage{textcomp}
     30\usepackage[latin1]{inputenc}
     31\usepackage{upquote}
    2332\usepackage{fullpage,times}
     33\usepackage{epic,eepic}
    2434\usepackage{xspace}
    2535\usepackage{varioref}
     
    4151%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    4252
     53% Names used in the document.
     54
     55\newcommand{\Version}{1.0.0}
     56
     57%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
     58
    4359\setcounter{secnumdepth}{3}                             % number subsubsections
    4460\setcounter{tocdepth}{3}                                % subsubsections in table of contents
     
    123139\subsection{Scopes of identifiers}\index{scopes}
    124140
    125 \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
    126 \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
    129 \Index{visible} when the scope of the inner declaration terminates.
    130 \begin{rationale}
    131 Hence, a \CFA program can declare an \lstinline$int v$ and a \lstinline$float v$ in the same scope;
     141\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 \Index{name space}, instead of hiding them.
     142The 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 ©type©\use{type} or ©typedef©\use{typedef} declaration and the other is not.
     143The outer declaration becomes \Index{visible} when the scope of the inner declaration terminates.
     144\begin{rationale}
     145Hence, a \CFA program can declare an ©int v© and a ©float v© in the same scope;
    132146a {\CC} program can not.
    133147\end{rationale}
     
    138152
    139153\CFA's linkage rules differ from C's in only one respect: instances of a particular identifier with external or internal linkage do not necessarily denote the same object or function.
    140 Instead, in the set of translation units and libraries that constitutes an entire program, any two instances of a particular identifier with \Index{external linkage} denote the same object or function if they have
    141 \Index{compatible type}s, 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.
     154Instead, in the set of translation units and libraries that constitutes an entire program, any two instances of a particular identifier with \Index{external linkage} denote the same object or function if they have \Index{compatible type}s, 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.
    142155Within one translation unit, each instance of an identifier with \Index{internal linkage} denotes the same object or function in the same circumstances.
    143156Identifiers with \Index{no linkage} always denote unique entities.
    144157\begin{rationale}
    145 A \CFA program can declare an \lstinline$extern int v$ and an \lstinline$extern float v$;
     158A \CFA program can declare an ©extern int v© and an ©extern float v©;
    146159a C program cannot.
    147160\end{rationale}
     
    166179\end{lstlisting}
    167180
    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$.
     181The type parameters in an instantiation of a generic type must satisfy any constraints in the forall specifier on the type generator declaration, e.g., ©sumable©.
    169182The instantiation then has the semantics that would result if the type parameters were substituted into the type generator declaration by macro substitution.
    170183
     
    214227\CFA defines situations where values of one type are automatically converted to another type.
    215228These conversions are called \define{implicit conversion}s.
    216 The programmer can request
    217 \define{explicit conversion}s using cast expressions.
     229The programmer can request \define{explicit conversion}s using cast expressions.
    218230
    219231
     
    227239In \CFA, these conversions play a role in overload resolution, and collectively are called the \define{safe arithmetic conversion}s.
    228240
    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.
     241Let ©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$.
     242Let ©unsigned$_{mr}$© be the unsigned integer type with maximal rank.
    231243
    232244The following conversions are \emph{direct} safe arithmetic conversions.
     
    235247The \Index{integer promotion}s.
    236248\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$.
     249For every rank $r$ greater than or equal to the rank of ©int©, conversion from ©int$_r$© to ©unsigned$_r$©.
     250\item
     251For every rank $r$ greater than or equal to the rank of ©int©, where ©int$_{r+1}$© exists and can represent all values of ©unsigned$_r$©, conversion from ©unsigned$_r$© to ©int$_{r+1}$©.
     252\item
     253Conversion from ©unsigned$_{mr}$© to ©float©.
    242254\item
    243255Conversion from an enumerated type to its compatible integer type.
    244256\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$.
     257Conversion from ©float© to ©double©, and from ©double© to ©long double©.
     258\item
     259Conversion from ©float _Complex© to ©double _Complex©, and from ©double _Complex© to ©long double _Complex©.
    248260\begin{sloppypar}
    249261\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.
     262Conversion from ©float _Imaginary© to ©double _Imaginary©, and from ©double _Imaginary© to ©long double _Imaginary©, if the implementation supports imaginary types.
    251263\end{sloppypar}
    252264\end{itemize}
    253265
    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.
     266If type ©T© can be converted to type ©U© by a safe direct arithmetic conversion and type ©U© can be converted to type ©V© by a safe arithmetic conversion, then the conversion from ©T© to type ©V© is an \emph{indirect} safe arithmetic conversion.
    255267
    256268\begin{rationale}
     
    266278\label{anon-conv}
    267279
    268 If an expression's type is a pointer to a structure or union type that has a member that is an
    269 \Index{anonymous structure} or an \Index{anonymous union}, it can be implicitly converted\index{implicit conversion} to a pointer to the anonymous structure's or anonymous union's type.
     280If an expression's type is a pointer to a structure or union type that has a member that is an \Index{anonymous structure} or an \Index{anonymous union}, it can be implicitly converted\index{implicit conversion} to a pointer to the anonymous structure's or anonymous union's type.
    270281The result of the conversion is a pointer to the member.
    271282
     
    275286        int x, y;
    276287};
    277 void move_by( struct point * p1, struct point * p2 ) {@\impl{move_by}@
     288void move_by( struct point * p1, struct point * p2 ) {§\impl{move_by}§
    278289        p1->x += p2.x;
    279290        p1->y += p2.y;
     
    285296move_to( &cp1, &cp2 );
    286297\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.
     298Thanks to implicit conversion, the two arguments that ©move_by()© receives are pointers to ©cp1©'s second member and ©cp2©'s second member.
    289299
    290300
     
    328338a direct safe arithmetic conversion;
    329339\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$;
     340from any object type or incomplete type to ©void©;
     341\item
     342from a pointer to any non-©void© type to a pointer to ©void©;
    333343\item
    334344from a pointer to any type to a pointer to a more qualified version of the type\index{qualified type};
     
    341351Conversions that are not safe conversions are \define{unsafe conversion}s.
    342352\begin{rationale}
    343 As in C, there is an implicit conversion from \lstinline$void *$ to any pointer type.
     353As in C, there is an implicit conversion from ©void *© to any pointer type.
    344354This is clearly dangerous, and {\CC} does not have this implicit conversion.
    345355\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.
     
    367377\begin{itemize}
    368378\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.
     379The cost of an implicit conversion from ©int© to ©long© is 1.
     380The cost of an implicit conversion from ©long© to ©double© is 3, because it is defined in terms of conversions from ©long© to ©unsigned long©, then to ©float©, and then to ©double©.
     381
     382\item
     383If ©int© can represent all the values of ©unsigned short©, then the cost of an implicit conversion from ©unsigned short© to ©unsigned© is 2: ©unsigned short© to ©int© to ©unsigned©.
     384Otherwise, ©unsigned short© is converted directly to ©unsigned©, and the cost is 1.
     385
     386\item
     387If ©long© can represent all the values of ©unsigned©, then the conversion cost of ©unsigned© to ©long© is 1.
    379388Otherwise, the conversion is an unsafe conversion, and its conversion cost is undefined.
    380389\end{itemize}
     
    384393\begin{syntax}
    385394\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$
     395        \rhs ©forall©
     396        \rhs ©lvalue©
     397        \rhs ©trait©
     398        \rhs ©dtype©
     399        \rhs ©ftype©
     400        \rhs ©otype©
    392401\end{syntax}
    393402
     
    396405
    397406\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.
     407Furthermore, the constants ``©0©'' and ``©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.
    399408Programmers can use these identifiers to declare functions and objects that implement operators and constants for their own types.
    400409
     
    405414\begin{syntax}
    406415\oldlhs{identifier}
    407 \rhs \lstinline$0$
    408 \rhs \lstinline$1$
     416\rhs ©0©
     417\rhs ©1©
    409418\end{syntax}
    410419
    411 \index{constant identifiers}\index{identifiers!for constants} The tokens ``\lstinline$0$''\impl{0} and ``\lstinline$1$''\impl{1} are identifiers.
     420\index{constant identifiers}\index{identifiers!for constants} The tokens ``©0©''\impl{0} and ``©1©''\impl{1} are identifiers.
    412421No other tokens defined by the rules for integer constants are considered to be identifiers.
    413422\begin{rationale}
    414 Why ``\lstinline$0$'' and ``\lstinline$1$''? Those integers have special status in C.
     423Why ``©0©'' and ``©1©''? Those integers have special status in C.
    415424All 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.
     425The operations ``©&&©'', ``©||©'', and ``©!©'' can be applied to any scalar arguments, and are defined in terms of comparison against 0.
    417426A \nonterm{constant-expression} that evaluates to 0 is effectively compatible with every pointer type.
    418427
    419428In 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.
    420429However, 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.
     430Defining special constants for a user-defined type is more efficient than defining a conversion to the type from ©_Bool©.
     431
     432Why \emph{just} ``©0©'' and ``©1©''? Why not other integers? No other integers have special status in C.
     433A facility that let programmers declare specific constants---``©const Rational 12©'', for instance---would not be much of an improvement.
    425434Some facility for defining the creation of values of programmer-defined types from arbitrary integer tokens would be needed.
    426435The complexity of such a feature doesn't seem worth the gain.
     
    438447\begin{tabular}[t]{ll}
    439448%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{?/?}\\
     449©?[?]© & subscripting \impl{?[?]}\\
     450©?()© & function call \impl{?()}\\
     451©?++© & postfix increment \impl{?++}\\
     452©?--© & postfix decrement \impl{?--}\\
     453©++?© & prefix increment \impl{++?}\\
     454©--?© & prefix decrement \impl{--?}\\
     455©*?© & dereference \impl{*?}\\
     456©+?© & unary plus \impl{+?}\\
     457©-?© & arithmetic negation \impl{-?}\\
     458©~?© & bitwise negation \impl{~?}\\
     459©!?© & logical complement \impl{"!?}\\
     460©?*?© & multiplication \impl{?*?}\\
     461©?/?© & division \impl{?/?}\\
    453462\end{tabular}\hfil
    454463\begin{tabular}[t]{ll}
    455464%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{?&?}\\
     465©?%?© & remainder \impl{?%?}\\
     466©?+?© & addition \impl{?+?}\\
     467©?-?© & subtraction \impl{?-?}\\
     468©?<<?© & left shift \impl{?<<?}\\
     469©?>>?© & right shift \impl{?>>?}\\
     470©?<?© & less than \impl{?<?}\\
     471©?<=?© & less than or equal \impl{?<=?}\\
     472©?>=?© & greater than or equal \impl{?>=?}\\
     473©?>?© & greater than \impl{?>?}\\
     474©?==?© & equality \impl{?==?}\\
     475©?!=?© & inequality \impl{?"!=?}\\
     476©?&?© & bitwise AND \impl{?&?}\\
    468477\end{tabular}\hfil
    469478\begin{tabular}[t]{ll}
    470479%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{?"|=?}\\
     480©?^?© & exclusive OR \impl{?^?}\\
     481©?|?© & inclusive OR \impl{?"|?}\\
     482©?=?© & simple assignment \impl{?=?}\\
     483©?*=?© & multiplication assignment \impl{?*=?}\\
     484©?/=?© & division assignment \impl{?/=?}\\
     485©?%=?© & remainder assignment \impl{?%=?}\\
     486©?+=?© & addition assignment \impl{?+=?}\\
     487©?-=?© & subtraction assignment \impl{?-=?}\\
     488©?<<=?© & left-shift assignment \impl{?<<=?}\\
     489©?>>=?© & right-shift assignment \impl{?>>=?}\\
     490©?&=?© & bitwise AND assignment \impl{?&=?}\\
     491©?^=?© & exclusive OR assignment \impl{?^=?}\\
     492©?|=?© & inclusive OR assignment \impl{?"|=?}\\
    484493\end{tabular}
    485494\hfil
     
    496505
    497506\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$--$''.
     507The use of ``©?©'' in identifiers means that some C programs are not \CFA programs.  For instance, the sequence of characters ``©(i < 0)?--i:i©'' is legal in a C program, but a
     508\CFA compiler detects a syntax error because it treats ``©?--©'' as an identifier, not as the two tokens ``©?©'' and ``©--©''.
    500509\end{rationale}
    501510
     
    504513\begin{itemize}
    505514\item
    506 The logical operators ``\lstinline$&&$'' and ``\lstinline$||$'', and the conditional operator
    507 ``\lstinline$?:$''.
     515The logical operators ``©&&©'' and ``©||©'', and the conditional operator ``©?:©''.
    508516These 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.
     517Note that the definitions of ``©&&©'' and ``©||©'' say that they work by checking that their arguments are unequal to 0, so defining ``©!=©'' and ``©0©'' for user-defined types is enough to allow them to be used in logical expressions.
    510518
    511519\item
     
    516524\item
    517525The ``address of'' operator.
    518 It would seem useful to define a unary ``\lstinline$&$'' operator that returns values of some programmer-defined pointer-like type.
     526It would seem useful to define a unary ``©&©'' operator that returns values of some programmer-defined pointer-like type.
    519527The 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 )$''
     528Consider the expression ``©p = &x©'', where ©x© is of type ©T© and ©p© has the programmer-defined type ©T_ptr©.
     529The expression might be treated as a call to the unary function ``©&?©''.
     530Now what is the type of the function's parameter? It can not be ©T©, because then ©x© would be passed by value, and there is no way to create a useful pointer-like result from a value.
     531Hence the parameter must have type ©T *©.
     532But then the expression must be rewritten as ``©p = &?( &x )©''
    526533---which doesn't seem like progress!
    527534
    528535The 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.
     536It seems simpler to define a conversion function from ©T *© to ©T_ptr©.
     537
     538\item
     539The ©sizeof© operator.
    533540It is already defined for every object type, and intimately tied into the language's storage allocation model.
    534541Redefining it seems pointless.
    535542
    536543\item
    537 The ``member of'' operators ``\lstinline$.$'' and ``\lstinline$->$''.
     544The ``member of'' operators ``©.©'' and ``©->©''.
    538545These are not really infix operators, since their right ``operand'' is not a value or object.
    539546
     
    572579The ``fewest unsafe conversions'' rule ensures that the usual conversions are done, if possible.
    573580The ``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$.
     581The 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: ©(double)-i© will be preferred to ©-(double)i©.
    575582
    576583The ``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.
    577 It 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}).
     584It also gives preference to monomorphic values (such as the ©int© ©0©) over polymorphic values (such as the \Index{null pointer} ©0©\use{0}).
    580585However, interpretations that call polymorphic functions are preferred to interpretations that perform unsafe conversions, because those conversions potentially lose accuracy or violate strong typing.
    581586
     
    597602\begin{rationale}
    598603Predefined 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)$''.
     604For instance, ``©an_int + an_int©'' is equivalent to ``©?+?(an_int, an_int)©''.
    600605If integer addition has not been redefined in the current scope, a compiler can generate code to perform the addition directly.
    601606If predefined functions had external linkage, this optimization would be difficult.
     
    623628\rhs \nonterm{constant}
    624629\rhs \nonterm{string-literal}
    625 \rhs \lstinline$($ \nonterm{expression} \lstinline$)$
     630\rhs ©(© \nonterm{expression} ©)©
    626631\rhs \nonterm{generic-selection}
    627632\end{syntax}
     
    629634\predefined
    630635\begin{lstlisting}
    631 const int 1;@\use{1}@
    632 const int 0;@\use{0}@
     636const int 1;§\use{1}§
     637const int 0;§\use{0}§
    633638forall( dtype DT ) DT * const 0;
    634639forall( ftype FT ) FT * const 0;
     
    639644
    640645A \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.
     646The predefined integer identifiers ``©1©'' and ``©0©'' have the integer values 1 and 0, respectively.
     647The other two predefined ``©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.
    643648
    644649A parenthesised expression has the same interpretations as the contained \nonterm{expression}.
    645650
    646651\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 *$.
    648 In 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.
     652The expression ©(void *)0©\use{0} specializes the (polymorphic) null pointer to a null pointer to ©void©. ©(const void *)0© does the same, and also uses a safe conversion from ©void *© to ©const void *©.
     653In each case, the null pointer conversion is better\index{best valid interpretations} than the unsafe conversion of the integer ©0© to a pointer.
    650654
    651655\begin{rationale}
     
    653657
    654658\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.
    656 Similarly,
    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
     659The C token ``©0©'' is an expression of type ©int© with the value ``zero'', and it \emph{also} is a null pointer constant.
     660Similarly, ``©(void *)0© is an expression of type ©(void *)© whose value is a null pointer, and it also is a null pointer constant.
     661However, in C, ``©(void *)(void *)0©'' is
    659662\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.
    660663
     
    663666\begin{lstlisting}
    664667forall( 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.
     668\end{lstlisting} means that ©0© is a polymorphic object, and contains a value that can have \emph{any} pointer-to-object type or pointer-to-incomplete type.
    666669The only such value is the null pointer.
    667670Therefore the type \emph{alone} is enough to identify a null pointer.
     
    673676
    674677\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.
     678If a generic selection has no ©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.
    676679
    677680\semantics
     
    684687\lhs{postfix-expression}
    685688\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$}$
     689\rhs \nonterm{postfix-expression} ©[© \nonterm{expression} ©]©
     690\rhs \nonterm{postfix-expression} ©(©
     691         \nonterm{argument-expression-list}\opt ©)©
     692\rhs \nonterm{postfix-expression} ©.© \nonterm{identifier}
     693\rhs \nonterm{postfix-expression} ©->© \nonterm{identifier}
     694\rhs \nonterm{postfix-expression} ©++©
     695\rhs \nonterm{postfix-expression} ©--©
     696\rhs ©(© \nonterm{type-name} ©)© ©{© \nonterm{initializer-list} ©}©
     697\rhs ©(© \nonterm{type-name} ©)© ©{© \nonterm{initializer-list} ©,© ©}©
    695698\lhs{argument-expression-list}
    696699\rhs \nonterm{assignment-expression}
    697 \rhs \nonterm{argument-expression-list} \lstinline$,$
     700\rhs \nonterm{argument-expression-list} ©,©
    698701         \nonterm{assignment-expression}
    699702\end{syntax}
     
    701704\rewriterules
    702705\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{?--}@
     706a[b] => ?[?]( b, a ) // if a has integer type§\use{?[?]}§
     707a[b] => ?[?]( a, b ) // otherwise
     708a( §\emph{arguments}§ ) => ?()( a, §\emph{arguments}§ )§\use{?()}§
     709a++ => ?++(&( a ))§\use{?++}§
     710a-- => ?--(&( a ))§\use{?--}§
    708711\end{lstlisting}
    709712
     
    713716\predefined
    714717\begin{lstlisting}
    715 forall( otype T ) lvalue T ?[?]( T *, ptrdiff_t );@\use{ptrdiff_t}@
     718forall( otype T ) lvalue T ?[?]( T *, ptrdiff_t );§\use{ptrdiff_t}§
    716719forall( otype T ) lvalue _Atomic T ?[?]( _Atomic T *, ptrdiff_t );
    717720forall( otype T ) lvalue const T ?[?]( const T *, ptrdiff_t );
     
    733736The interpretations of subscript expressions are the interpretations of the corresponding function call expressions.
    734737\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$?[?]$.
     738C defines subscripting as pointer arithmetic in a way that makes ©a[i]© and ©i[a]© equivalent. \CFA provides the equivalence through a rewrite rule to reduce the number of overloadings of ©?[?]©.
    737739
    738740Subscript expressions are rewritten as function calls that pass the first parameter by value.
    739741This 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.
     742The alternative is to use the rewrite rule ``©a[b] => ?[?](&(a), b)©''.
     743However, C semantics forbid this approach: the ©a© in ``©a[b]©'' can be an arbitrary pointer value, which does not have an address.
    742744
    743745The repetitive form of the predefined identifiers shows up a deficiency\index{deficiencies!pointers
     
    754756\nonterm{postfix-expression} in a function call may have some interpretations that are function designators and some that are not.
    755757
    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$?()$''.
     758For those interpretations of the \nonterm{postfix-expression} that are not function designators, the expression is rewritten and becomes a call of a function named ``©?()©''.
    757759The valid interpretations of the rewritten expression are determined in the manner described below.
    758760
     
    761763\begin{itemize}
    762764\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
    763 \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.
     765\item if the function designator's type does not include a prototype or if the argument corresponds to ``©...©'' in a prototype, a \Index{default argument promotion} is applied to it.
    765766\end{itemize}
    766767The type of the valid interpretation is the return type of the function designator.
    767768
    768 For those combinations where the interpretation of the \nonterm{postfix-expression} is a
    769 \Index{polymorphic function} designator and the function designator accepts the number of arguments given, there shall be at least one set of \define{implicit argument}s for the implicit parameters such that
     769For those combinations where the interpretation of the \nonterm{postfix-expression} is a \Index{polymorphic function} designator and the function designator accepts the number of arguments given, there shall be at least one set of \define{implicit argument}s for the implicit parameters such that
    770770\begin{itemize}
    771771\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.
     772If the declaration of the implicit parameter uses \Index{type-class} ©type©\use{type}, the implicit argument must be an object type;
     773if it uses ©dtype©, the implicit argument must be an object type or an incomplete type;
     774and if it uses ©ftype©, the implicit argument must be a function type.
    775775
    776776\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.
     
    791791\begin{rationale}
    792792One 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$.
    794 
    795 \CFA\index{deficiencies!generalizability} does not fully possess this property, because
    796 \Index{unsafe conversion} are not done when arguments are passed to polymorphic parameters.
     793For instance, it should be possible to replace a function ``©int f( int );©'' with ``©forall( otype T ) T f( T );©'' without affecting any calls of ©f©.
     794
     795\CFA\index{deficiencies!generalizability} does not fully possess this property, because \Index{unsafe conversion} are not done when arguments are passed to polymorphic parameters.
    797796Consider
    798797\begin{lstlisting}
     
    805804f = g( d, f );          // (3) (unsafe conversion to float)
    806805\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 *);$''.
    811 This 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.
     806If ©g© was replaced by ``©forall( otype T ) T g( T, T );©'', the first and second calls would be unaffected, but the third would change: ©f© would be converted to ©double©, and the result would be a ©double©.
     807
     808Another example is the function ``©void h( int *);©''.
     809This function can be passed a ©void *© argument, but the generalization ``©forall( otype T ) void h( T *);©'' can not.
     810In this case, ©void© is not a valid value for ©T© because it is not an object type.
     811If unsafe conversions were allowed, ©T© could be inferred to be \emph{any} object type, which is undesirable.
    815812\end{rationale}
    816813
    817814\examples
    818 A function called ``\lstinline$?()$'' might be part of a numerical differentiation package.
     815A function called ``©?()©'' might be part of a numerical differentiation package.
    819816\begin{lstlisting}
    820817extern otype Derivative;
     
    827824d = sin_dx( 12.9 );
    828825\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 )$''.
     826Here, the only interpretation of ©sin_dx© is as an object of type ©Derivative©.
     827For that interpretation, the function call is treated as ``©?()( sin_dx, 12.9 )©''.
    831828\begin{lstlisting}
    832829int f( long );          // (1)
     
    835832int i = f( 5 );         // calls (1)
    836833\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.
     834Function (1) provides a valid interpretation of ``©f( 5 )©'', using an implicit ©int© to ©long© conversion.
     835The other functions do not, since the second requires two arguments, and since there is no implicit conversion from ©int© to ©int *© that could be used with the third function.
    839836
    840837\begin{lstlisting}
     
    842839double d = h( 1.5 );
    843840\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$.
     841``©1.5©'' is a ©double© constant, so ©T© is inferred to be ©double©, and the result of the function call is a ©double©.
    846842
    847843\begin{lstlisting}
    848844forall( otype T, otype U ) void g( T, U );      // (4)
    849845forall( otype T ) void g( T, T );                       // (5)
    850 forall( otype T ) void g( T, long );                    // (6)
     846forall( otype T ) void g( T, long );            // (6)
    851847void g( long, long );                                           // (7)
    852848double d;
    853849int i;
    854850int *p;
    855 g( d, d );                      // calls (5)
    856 g( d, i );                      // calls (6)
    857 g( i, i );                      // calls (7)
    858 g( i, p );                      // calls (4)
    859 \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).
     851g( d, d );                                                                      // calls (5)
     852g( d, i );                                                                      // calls (6)
     853g( i, i );                                                                      // calls (7)
     854g( i, p );                                                                      // calls (4)
     855\end{lstlisting}
     856The first call has valid interpretations for all four versions of ©g©. (6) and (7) are discarded because they involve unsafe ©double©-to-©long© conversions. (5) is chosen because it is less polymorphic than (4).
    861857
    862858For 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.
     859Of the remaining interpretations for (4), (5), and (6) (with ©i© converted to ©long©), (6) is chosen because it is the least polymorphic.
    864860
    865861The third call has valid interpretations for all of the functions;
     
    870866forall( otype T ) T min( T, T );
    871867double max( double, double );
    872 trait min_max( T ) {@\impl{min_max}@
     868trait min_max( T ) {§\impl{min_max}§
    873869        T min( T, T );
    874870        T max( T, T );
     
    877873shuffle( 9, 10 );
    878874\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$.
    881 \begin{lstlisting}
    882 extern void q( int );           // (8)
    883 extern void q( void * );        // (9)
     875The only possibility for ©U© is ©double©, because that is the type used in the only visible ©max© function. 9 and 10 must be converted to ©double©, and ©min© must be specialized with ©T© bound to ©double©.
     876\begin{lstlisting}
     877extern void q( int );                                           // (8)
     878extern void q( void * );                                        // (9)
    884879extern void r();
    885880q( 0 );
    886881r( 0 );
    887882\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.
     883The ©int 0© could be passed to (8), or the ©(void *)© \Index{specialization} of the null pointer\index{null pointer} ©0©\use{0} could be passed to (9).
     884The former is chosen because the ©int© ©0© is \Index{less polymorphic}.
     885For the same reason, ©int© ©0© is passed to ©r()©, even though it has \emph{no} declared parameter types.
    891886
    892887
    893888\subsubsection{Structure and union members}
    894889
    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.
     890\semantics In the member selection expression ``©s©.©m©'', there shall be at least one interpretation of ©s© whose type is a structure type or union type containing a member named ©m©.
     891If two or more interpretations of ©s© have members named ©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.
     892If an interpretation of ©s© has a member ©m© whose type is not compatible with any other ©s©'s ©m©, then the expression has an interpretation with the member's type.
    900893The expression has no other interpretations.
    901894
    902 The expression ``\lstinline$p->m$'' has the same interpretations as the expression
    903 ``\lstinline$(*p).m$''.
     895The expression ``©p->m©'' has the same interpretations as the expression ``©(*p).m©''.
    904896
    905897
     
    996988        * ?--( _Atomic const restrict volatile T * _Atomic restrict volatile * );
    997989\end{lstlisting}
    998 For every extended integer type \lstinline$X$ there exist
     990For every extended integer type ©X© there exist
    999991% Don't use predefined: keep this out of prelude.cf.
    1000992\begin{lstlisting}
     
    1002994  ?--( volatile X * ), ?--( _Atomic volatile X * );
    1003995\end{lstlisting}
    1004 For every complete enumerated type \lstinline$E$ there exist
     996For every complete enumerated type ©E© there exist
    1005997% Don't use predefined: keep this out of prelude.cf.
    1006998\begin{lstlisting}
     
    10101002
    10111003\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.
     1004Note that ``©++©'' and ``©--©'' 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.
    10131005This partially enforces the C semantic rule that such operands must be \emph{modifiable} lvalues.
    10141006\end{rationale}
     
    10161008\begin{rationale}
    10171009In 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$.
     1010Hence, ©void *© objects cannot be incremented.
     1011In \CFA, the restriction follows from the use of a ©type© parameter in the predefined function definitions, as opposed to ©dtype©, since only object types can be inferred arguments corresponding to the type parameter ©T©.
    10201012\end{rationale}
    10211013
    10221014\semantics
    10231015First, 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.
     1016For 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.
    10261017
    10271018For the remaining interpretations, the expression is rewritten, and the interpretations of the expression are the interpretations of the corresponding function call.
     
    10361027\end{lstlisting}
    10371028\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.
     1029Since ©&(vs)© has type ©volatile short int *©, the best valid interpretation of ©vs++© calls the ©?++© function with the ©volatile short *© parameter.
     1030©s++© does the same, applying the safe conversion from ©short int *© to ©volatile short int *©.
     1031Note that there is no conversion that adds an ©_Atomic© qualifier, so the ©_Atomic volatile short int© overloading does not provide a valid interpretation.
    10431032\end{sloppypar}
    10441033
    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.
     1034There is no safe conversion from ©const short int *© to ©volatile short int *©, and no ©?++© function that accepts a ©const *© parameter, so ©cs++© has no valid interpretations.
     1035
     1036The best valid interpretation of ©as++© calls the ©short ?++© function with the ©_Atomic volatile short int *© parameter, applying a safe conversion to add the ©volatile© qualifier.
    10481037\begin{lstlisting}
    10491038char * const restrict volatile * restrict volatile pqpc;
     
    10521041ppc++;
    10531042\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$.
     1043Since ©&(pqpc)© has type ©char * const restrict volatile * restrict volatile *©, the best valid interpretation of ©pqpc++© calls the polymorphic ©?++© function with the ©const restrict volatile T * restrict volatile *© parameter, inferring ©T© to be ©char *©.
     1044
     1045©ppc++© calls the same function, again inferring ©T© to be ©char *©, and using the safe conversions from ©T© to ©T const© ©restrict volatile©.
    10571046
    10581047\begin{rationale}
     
    10681057\begin{enumerate}
    10691058\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
     1059``©char * p; p++;©''.
     1060The argument to ©?++© has type ©char * *©, and the result has type ©char *©.
     1061The expression would be valid if ©?++© were declared by
    10731062\begin{lstlisting}
    10741063forall( 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.
     1064\end{lstlisting} with ©T© inferred to be ©char©.
     1065
     1066\item
     1067``©char *restrict volatile qp; qp++©''.
     1068The result again has type ©char *©, but the argument now has type ©char *restrict volatile *©, so it cannot be passed to the hypothetical function declared in point 1.
    10801069Hence the actual predefined function is
    10811070\begin{lstlisting}
    10821071forall( 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++$''.
    1093 Here the result has type
    1094 \lstinline$char const volatile *$, so a new overloading is needed:
     1072\end{lstlisting} which also accepts a ©char * *© argument, because of the safe conversions that add ©volatile© and ©restrict© qualifiers. (The parameter is not const-qualified, so constant pointers cannot be incremented.)
     1073
     1074\item
     1075``©char *_Atomic ap; ap++©''.
     1076The result again has type ©char *©, but no safe conversion adds an ©_Atomic© qualifier, so the function in point 2 is not applicable.
     1077A separate overloading of ©?++© is required.
     1078
     1079\item
     1080``©char const volatile * pq; pq++©''.
     1081Here the result has type ©char const volatile *©, so a new overloading is needed:
    10951082\begin{lstlisting}
    10961083forall( otype T ) T const volatile * ?++( T const volatile *restrict volatile * );
     
    10991086 
    11001087\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:
     1088``©float *restrict * prp; prp++©''.
     1089The ©restrict© qualifier is handled just like ©const© and ©volatile© in the previous case:
    11031090\begin{lstlisting}
    11041091forall( 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.
     1092\end{lstlisting} with ©T© inferred to be ©float *©.
     1093This looks odd, because {\c11} contains a constraint that requires restrict-qualified types to be pointer-to-object types, and ©T© is not syntactically a pointer type. \CFA loosens the constraint.
    11071094\end{enumerate}
    11081095\end{rationale}
     
    11201107\lhs{unary-expression}
    11211108\rhs \nonterm{postfix-expression}
    1122 \rhs \lstinline$++$ \nonterm{unary-expression}
    1123 \rhs \lstinline$--$ \nonterm{unary-expression}
     1109\rhs ©++© \nonterm{unary-expression}
     1110\rhs ©--© \nonterm{unary-expression}
    11241111\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$!$
     1112\rhs ©sizeof© \nonterm{unary-expression}
     1113\rhs ©sizeof© ©(© \nonterm{type-name} ©)©
     1114\lhs{unary-operator} one of \rhs ©&© ©*© ©+© ©-© ©~© ©!©
    11281115\end{syntax}
    11291116
    11301117\rewriterules
    11311118\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{--?}@
     1119*a      => *?( a )§\use{*?}§
     1120+a      => +?( a )§\use{+?}§
     1121-a      => -?( a )§\use{-?}§
     1122~a      => ~?( a )§\use{~?}§
     1123!a      => !?( a )§\use{"!?}§
     1124++a     => ++?(&( a ))§\use{++?}§
     1125--a     => --?(&( a ))§\use{--?}§
    11391126\end{lstlisting}
    11401127
     
    12321219        * --?( _Atomic const restrict volatile T * _Atomic restrict volatile * );
    12331220\end{lstlisting}
    1234 For every extended integer type \lstinline$X$ there exist
     1221For every extended integer type ©X© there exist
    12351222% Don't use predefined: keep this out of prelude.cf.
    12361223\begin{lstlisting}
     
    12401227        --?( _Atomic volatile X * );
    12411228\end{lstlisting}
    1242 For every complete enumerated type \lstinline$E$ there exist
     1229For every complete enumerated type ©E© there exist
    12431230% Don't use predefined: keep this out of prelude.cf.
    12441231\begin{lstlisting}
     
    12771264
    12781265\constraints
    1279 The operand of the unary ``\lstinline$&$'' operator shall have exactly one
    1280 \Index{interpretation}\index{ambiguous interpretation}, which shall be unambiguous.
     1266The operand of the unary ``©&©'' operator shall have exactly one \Index{interpretation}\index{ambiguous interpretation}, which shall be unambiguous.
    12811267
    12821268\semantics
    1283 The ``\lstinline$&$'' expression has one interpretation which is of type \lstinline$T *$, where
    1284 \lstinline$T$ is the type of the operand.
     1269The ``©&©'' expression has one interpretation which is of type ©T *©, where ©T© is the type of the operand.
    12851270
    12861271The interpretations of an indirection expression are the interpretations of the corresponding function call.
     
    13111296forall( ftype FT ) int !?( FT * );
    13121297\end{lstlisting}
    1313 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1298For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist
    13141299% Don't use predefined: keep this out of prelude.cf.
    13151300\begin{lstlisting}
     
    13241309\begin{lstlisting}
    13251310long 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
     1311void eat_double( double );§\use{eat_double}§
     1312eat_double(-li ); // => eat_double( -?( li ) );
     1313\end{lstlisting}
     1314The valid interpretations of ``©-li©'' (assuming no extended integer types exist) are
    13301315\begin{center}
    13311316\begin{tabular}{llc} interpretation & result type & expression conversion cost \\
    13321317\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) \\
     1318©-?( (int)li )©                                         & ©int©                                         & (unsafe) \\
     1319©-?( (unsigned)li)©                                     & ©unsigned int©                        & (unsafe) \\
     1320©-?( (long)li)©                                         & ©long©                                        & 0 \\
     1321©-?( (long unsigned int)li)©            & ©long unsigned int©           & 1 \\
     1322©-?( (long long int)li)©                        & ©long long int©                       & 2 \\
     1323©-?( (long long unsigned int)li)©       & ©long long unsigned int©      & 3 \\
     1324©-?( (float)li)©                                        & ©float©                                       & 4 \\
     1325©-?( (double)li)©                                       & ©double©                                      & 5 \\
     1326©-?( (long double)li)©                          & ©long double©                         & 6 \\
     1327©-?( (_Complex float)li)©                       & ©float©                                       & (unsafe) \\
     1328©-?( (_Complex double)li)©                      & ©double©                                      & (unsafe) \\
     1329©-?( (_Complex long double)li)©         & ©long double©                         & (unsafe) \\
    13451330\end{tabular}
    13461331\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
     1332The valid interpretations of the ©eat_double© call, with the cost of the argument conversion and the cost of the entire expression, are
    13481333\begin{center}
    13491334\begin{tabular}{lcc} interpretation & argument cost & expression cost \\
    13501335\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) \\
     1336©eat_double( (double)-?( (int)li) )©                                    & 7                     & (unsafe) \\
     1337©eat_double( (double)-?( (unsigned)li) )©                               & 6                     & (unsafe) \\
     1338©eat_double( (double)-?(li) )©                                                  & 5                     & \(0+5=5\) \\
     1339©eat_double( (double)-?( (long unsigned int)li) )©              & 4                     & \(1+4=5\) \\
     1340©eat_double( (double)-?( (long long int)li) )©                  & 3                     & \(2+3=5\) \\
     1341©eat_double( (double)-?( (long long unsigned int)li) )© & 2                     & \(3+2=5\) \\
     1342©eat_double( (double)-?( (float)li) )©                                  & 1                     & \(4+1=5\) \\
     1343©eat_double( (double)-?( (double)li) )©                                 & 0                     & \(5+0=5\) \\
     1344©eat_double( (double)-?( (long double)li) )©                    & (unsafe)      & (unsafe) \\
     1345©eat_double( (double)-?( (_Complex float)li) )©                 & (unsafe)      & (unsafe) \\
     1346©eat_double( (double)-?( (_Complex double)li) )©                & (unsafe)      & (unsafe) \\
     1347©eat_double( (double)-?( (_Complex long double)li) )©   & (unsafe)      & (unsafe) \\
    13631348\end{tabular}
    13641349\end{center}
    1365 Each has result type \lstinline$void$, so the best must be selected.
     1350Each has result type ©void©, so the best must be selected.
    13661351The interpretations involving unsafe conversions are discarded.
    1367 The remainder have equal expression conversion costs, so the
    1368 ``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}
     1352The remainder have equal expression conversion costs, so the ``highest argument conversion cost'' rule is invoked, and the chosen interpretation is ©eat_double( (double)-?(li) )©.
     1353
     1354
     1355\subsubsection[The sizeof and \_Alignof operators]{The \lstinline@sizeof@ and \lstinline@_Alignof@ operators}
    13731356
    13741357\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
     1358The operand of ©sizeof© or ©_Alignof© shall not be ©type©, ©dtype©, or ©ftype©.
     1359
     1360When the ©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 ©sizeof© or ©_Alignof© expression has one interpretation, of type ©size_t©.
     1361
     1362When ©sizeof© is applied to an identifier declared by a \nonterm{type-declaration} or a
    13811363\nonterm{type-parameter}, it yields the size in bytes of the type that implements the operand.
    13821364When the operand is an opaque type or an inferred type parameter\index{inferred parameter}, the expression is not a constant expression.
    13831365
    1384 When \lstinline$_Alignof$ is applied to an identifier declared by a \nonterm{type-declaration} or a
     1366When ©_Alignof© is applied to an identifier declared by a \nonterm{type-declaration} or a
    13851367\nonterm{type-parameter}, it yields the alignment requirement of the type that implements the operand.
    13861368When the operand is an opaque type or an inferred type parameter\index{inferred parameter}, the expression is not a constant expression.
     
    13891371otype Pair = struct { int first, second; };
    13901372size_t p_size = sizeof(Pair);           // constant expression
    1391 extern otype Rational;@\use{Rational}@
     1373extern otype Rational;§\use{Rational}§
    13921374size_t c_size = sizeof(Rational);       // non-constant expression
    13931375forall(type T) T f(T p1, T p2) {
     
    13961378}
    13971379\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.
     1380``©sizeof Rational©'', although not statically known, is fixed.
     1381Within ©f()©, ``©sizeof(T)©'' is fixed for each call of ©f()©, but may vary from call to call.
    14011382\end{rationale}
    14021383
     
    14071388\lhs{cast-expression}
    14081389\rhs \nonterm{unary-expression}
    1409 \rhs \lstinline$($ \nonterm{type-name} \lstinline$)$ \nonterm{cast-expression}
     1390\rhs ©(© \nonterm{type-name} ©)© \nonterm{cast-expression}
    14101391\end{syntax}
    14111392
    14121393\constraints
    1413 The \nonterm{type-name} in a \nonterm{cast-expression} shall not be \lstinline$type$,
    1414 \lstinline$dtype$, or \lstinline$ftype$.
     1394The \nonterm{type-name} in a \nonterm{cast-expression} shall not be ©type©, ©dtype©, or ©ftype©.
    14151395
    14161396\semantics
    14171397
    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.
     1398In a \Index{cast expression} ``©(©\nonterm{type-name}©)e©'', if
     1399\nonterm{type-name} is the type of an interpretation of ©e©, then that interpretation is the only interpretation of the cast expression;
     1400otherwise, ©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.
    14211401The 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.
    14221402
     
    14311411\lhs{multiplicative-expression}
    14321412\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}
     1413\rhs \nonterm{multiplicative-expression} ©*© \nonterm{cast-expression}
     1414\rhs \nonterm{multiplicative-expression} ©/© \nonterm{cast-expression}
     1415\rhs \nonterm{multiplicative-expression} ©%© \nonterm{cast-expression}
    14361416\end{syntax}
    14371417
    14381418\rewriterules
    14391419\begin{lstlisting}
    1440 a * b @\rewrite@ ?*?( a, b )@\use{?*?}@
    1441 a / b @\rewrite@ ?/?( a, b )@\use{?/?}@
    1442 a % b @\rewrite@ ?%?( a, b )@\use{?%?}@
     1420a * b => ?*?( a, b )§\use{?*?}§
     1421a / b => ?/?( a, b )§\use{?/?}§
     1422a % b => ?%?( a, b )§\use{?%?}§
    14431423\end{lstlisting}
    14441424
     
    14671447        ?*?( _Complex long double, _Complex long double ), ?/?( _Complex long double, _Complex long double );
    14681448\end{lstlisting}
    1469 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1449For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist
    14701450% Don't use predefined: keep this out of prelude.cf.
    14711451\begin{lstlisting}
     
    14741454
    14751455\begin{rationale}
    1476 {\c11} does not include conversions from the \Index{real type}s to \Index{complex type}s in the
    1477 \Index{usual arithmetic conversion}s.  Instead it specifies conversion of the result of binary operations on arguments from mixed type domains. \CFA's predefined operators match that pattern.
     1456{\c11} does not include conversions from the \Index{real type}s to \Index{complex type}s in the \Index{usual arithmetic conversion}s.  Instead it specifies conversion of the result of binary operations on arguments from mixed type domains. \CFA's predefined operators match that pattern.
    14781457\end{rationale}
    14791458
     
    14851464int i;
    14861465long li;
    1487 void eat_double( double );@\use{eat_double}@
     1466void eat_double( double );§\use{eat_double}§
    14881467eat_double( li % i );
    14891468\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
     1469``©li % i©'' is rewritten as ``©?%?(li, i )©''.
     1470The valid interpretations of ©?%?(li, i )©, the cost\index{conversion cost} of converting their arguments, and the cost of converting the result to ©double© (assuming no extended integer types are present ) are
    14921471\begin{center}
    14931472\begin{tabular}{lcc} interpretation & argument cost & result cost \\
    1494 \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     \\
     1473\hline
     1474© ?%?( (int)li, i )©                                                                            & (unsafe)      & 6     \\
     1475© ?%?( (unsigned)li,(unsigned)i )©                                                      & (unsafe)      & 5     \\
     1476© ?%?( li, (long)i )©                                                                           & 1                     & 4     \\
     1477© ?%?( (long unsigned)li,(long unsigned)i )©                            & 3                     & 3     \\
     1478© ?%?( (long long)li,(long long)i )©                                            & 5                     & 2     \\
     1479© ?%?( (long long unsigned)li, (long long unsigned)i )©         & 7                     & 1     \\
    15011480\end{tabular}
    15021481\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 )$''.
     1482The best interpretation of ©eat_double( li, i )© is ©eat_double( (double)?%?(li, (long)i ))©, which has no unsafe conversions and the lowest total cost.
     1483
     1484\begin{rationale}
     1485{\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 ©int©.
     1486If ©s© is a ©short int©, ``©s *s©'' does not have type ©short int©;
     1487it is treated as ``©( (int)s ) * ( (int)s )©'', and has type ©int©. \CFA matches that pattern;
     1488it does not predefine ``©short ?*?( short, short )©''.
    15111489
    15121490These ``missing'' operators limit polymorphism.
     
    15171495square( s );
    15181496\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$.
     1497Since \CFA does not define a multiplication operator for ©short int©, ©square( s )© is treated as ©square( (int)s )©, and the result has type ©int©.
    15221498This is mildly surprising, but it follows the {\c11} operator pattern.
    15231499
     
    15281504product( sa, 5);
    15291505\end{lstlisting}
    1530 This has no valid interpretations, because \CFA has no conversion from ``array of
    1531 \lstinline$short int$'' to ``array of \lstinline$int$''.
     1506This has no valid interpretations, because \CFA has no conversion from ``array of ©short int©'' to ``array of ©int©''.
    15321507The alternatives in such situations include
    15331508\begin{itemize}
    15341509\item
    1535 Defining monomorphic overloadings of \lstinline$product$ for \lstinline$short$ and the other
    1536 ``small'' types.
    1537 \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.
     1510Defining monomorphic overloadings of ©product© for ©short© and the other ``small'' types.
     1511\item
     1512Defining ``©short ?*?( short, short )©'' within the scope containing the call to ©product©.
     1513\item
     1514Defining ©product© to take as an argument a conversion function from the ``small'' type to the operator's argument type.
    15421515\end{itemize}
    15431516\end{rationale}
     
    15491522\lhs{additive-expression}
    15501523\rhs \nonterm{multiplicative-expression}
    1551 \rhs \nonterm{additive-expression} \lstinline$+$ \nonterm{multiplicative-expression}
    1552 \rhs \nonterm{additive-expression} \lstinline$-$ \nonterm{multiplicative-expression}
     1524\rhs \nonterm{additive-expression} ©+© \nonterm{multiplicative-expression}
     1525\rhs \nonterm{additive-expression} ©-© \nonterm{multiplicative-expression}
    15531526\end{syntax}
    15541527
    15551528\rewriterules
    15561529\begin{lstlisting}
    1557 a + b @\rewrite@ ?+?( a, b )@\use{?+?}@
    1558 a - b @\rewrite@ ?-?( a, b )@\use{?-?}@
     1530a + b => ?+?( a, b )§\use{?+?}§
     1531a - b => ?-?( a, b )§\use{?-?}§
    15591532\end{lstlisting}
    15601533
     
    16091582        * ?-?( _Atomic const restrict volatile T *, _Atomic const restrict volatile T * );
    16101583\end{lstlisting}
    1611 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1584For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist
    16121585% Don't use predefined: keep this out of prelude.cf.
    16131586\begin{lstlisting}
     
    16191592
    16201593\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.
     1594©ptrdiff_t© is an implementation-defined identifier defined in ©<stddef.h>© that is synonymous with a signed integral type that is large enough to hold the difference between two pointers.
    16221595It 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.
     1596The {\c11} standard uses ©size_t© in several cases where a library function takes an argument that is used as a subscript, but ©size_t© is unsuitable here because it is an unsigned type.
    16241597\end{rationale}
    16251598
     
    16301603\lhs{shift-expression}
    16311604\rhs \nonterm{additive-expression}
    1632 \rhs \nonterm{shift-expression} \lstinline$<<$ \nonterm{additive-expression}
    1633 \rhs \nonterm{shift-expression} \lstinline$>>$ \nonterm{additive-expression}
     1605\rhs \nonterm{shift-expression} ©<<© \nonterm{additive-expression}
     1606\rhs \nonterm{shift-expression} ©>>© \nonterm{additive-expression}
    16341607\end{syntax}
    16351608
    1636 \rewriterules \use{?>>?}%use{?<<?}
    1637 \begin{lstlisting}
    1638 a << b @\rewrite@ ?<<?( a, b )
    1639 a >> b @\rewrite@ ?>>?( a, b )
     1609\rewriterules
     1610\begin{lstlisting}
     1611a << b => ?<<?( a, b )§\use{?<<?}§
     1612a >> b => ?>>?( a, b )§\use{?>>?}§
    16401613\end{lstlisting}
    16411614
     
    16491622long long unsigned int ?<<?( long long unsigned int, int ), ?>>?( long long unsigned int, int);
    16501623\end{lstlisting}
    1651 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1624For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist
    16521625% Don't use predefined: keep this out of prelude.cf.
    16531626\begin{lstlisting}
     
    16691642\lhs{relational-expression}
    16701643\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}
     1644\rhs \nonterm{relational-expression} ©< © \nonterm{shift-expression}
     1645\rhs \nonterm{relational-expression} ©> © \nonterm{shift-expression}
     1646\rhs \nonterm{relational-expression} ©<=© \nonterm{shift-expression}
     1647\rhs \nonterm{relational-expression} ©>=© \nonterm{shift-expression}
    16751648\end{syntax}
    16761649
    1677 \rewriterules\use{?>?}\use{?>=?}%use{?<?}%use{?<=?}
    1678 \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 )
     1650\rewriterules
     1651\begin{lstlisting}
     1652a < b => ?<?( a, b )§\use{?<?}§
     1653a > b => ?>?( a, b )§\use{?>?}§
     1654a <= b => ?<=?( a, b )§\use{?<=?}§
     1655a >= b => ?>=?( a, b )§\use{?>=?}§
    16831656\end{lstlisting}
    16841657
     
    17121685        ?>=?( _Atomic const restrict volatile DT *, _Atomic const restrict volatile DT * );
    17131686\end{lstlisting}
    1714 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1687For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist
    17151688% Don't use predefined: keep this out of prelude.cf.
    17161689\begin{lstlisting}
     
    17301703\lhs{equality-expression}
    17311704\rhs \nonterm{relational-expression}
    1732 \rhs \nonterm{equality-expression} \lstinline$==$ \nonterm{relational-expression}
    1733 \rhs \nonterm{equality-expression} \lstinline$!=$ \nonterm{relational-expression}
     1705\rhs \nonterm{equality-expression} ©==© \nonterm{relational-expression}
     1706\rhs \nonterm{equality-expression} ©!=© \nonterm{relational-expression}
    17341707\end{syntax}
    17351708
    17361709\rewriterules
    17371710\begin{lstlisting}
    1738 a == b @\rewrite@ ?==?( a, b )@\use{?==?}@
    1739 a != b @\rewrite@ ?!=?( a, b )@\use{?"!=?}@
     1711a == b => ?==?( a, b )§\use{?==?}§
     1712a != b => ?!=?( a, b )§\use{?"!=?}§
    17401713\end{lstlisting}
    17411714
     
    17901763        ?==?( forall( ftype FT2) FT2*, forall( ftype FT3) FT3 * ), ?!=?( forall( ftype FT2) FT2*, forall( ftype FT3) FT3 * );
    17911764\end{lstlisting}
    1792 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1765For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist
    17931766% Don't use predefined: keep this out of prelude.cf.
    17941767\begin{lstlisting}
     
    17981771
    17991772\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.
     1773The polymorphic equality operations come in three styles: comparisons between pointers of compatible types, between pointers to ©void© and pointers to object types or incomplete types, and between the \Index{null pointer} constant and pointers to any type.
    18011774In the last case, a special constraint rule for null pointer constant operands has been replaced by a consequence of the \CFA type system.
    18021775\end{rationale}
     
    18191792\lhs{AND-expression}
    18201793\rhs \nonterm{equality-expression}
    1821 \rhs \nonterm{AND-expression} \lstinline$&$ \nonterm{equality-expression}
     1794\rhs \nonterm{AND-expression} ©&© \nonterm{equality-expression}
    18221795\end{syntax}
    18231796
    18241797\rewriterules
    18251798\begin{lstlisting}
    1826 a & b @\rewrite@ ?&?( a, b )@\use{?&?}@
     1799a & b => ?&?( a, b )§\use{?&?}§
    18271800\end{lstlisting}
    18281801
     
    18361809long long unsigned int ?&?( long long unsigned int, long long unsigned int );
    18371810\end{lstlisting}
    1838 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1811For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist
    18391812% Don't use predefined: keep this out of prelude.cf.
    18401813\begin{lstlisting}
     
    18511824\lhs{exclusive-OR-expression}
    18521825\rhs \nonterm{AND-expression}
    1853 \rhs \nonterm{exclusive-OR-expression} \lstinline$^$ \nonterm{AND-expression}
     1826\rhs \nonterm{exclusive-OR-expression} ©^© \nonterm{AND-expression}
    18541827\end{syntax}
    18551828
    18561829\rewriterules
    18571830\begin{lstlisting}
    1858 a ^ b @\rewrite@ ?^?( a, b )@\use{?^?}@
     1831a ^ b => ?^?( a, b )§\use{?^?}§
    18591832\end{lstlisting}
    18601833
     
    18681841long long unsigned int ?^?( long long unsigned int, long long unsigned int );
    18691842\end{lstlisting}
    1870 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1843For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist
    18711844% Don't use predefined: keep this out of prelude.cf.
    18721845\begin{lstlisting}
     
    18831856\lhs{inclusive-OR-expression}
    18841857\rhs \nonterm{exclusive-OR-expression}
    1885 \rhs \nonterm{inclusive-OR-expression} \lstinline$|$ \nonterm{exclusive-OR-expression}
     1858\rhs \nonterm{inclusive-OR-expression} ©|© \nonterm{exclusive-OR-expression}
    18861859\end{syntax}
    18871860
    1888 \rewriterules\use{?"|?}
    1889 \begin{lstlisting}
    1890 a | b @\rewrite@ ?|?( a, b )
     1861\rewriterules
     1862\begin{lstlisting}
     1863a | b => ?|?( a, b )§\use{?"|?}§
    18911864\end{lstlisting}
    18921865
     
    19001873long long unsigned int ?|?( long long unsigned int, long long unsigned int );
    19011874\end{lstlisting}
    1902 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$ there exist
     1875For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist
    19031876% Don't use predefined: keep this out of prelude.cf.
    19041877\begin{lstlisting}
     
    19151888\lhs{logical-AND-expression}
    19161889\rhs \nonterm{inclusive-OR-expression}
    1917 \rhs \nonterm{logical-AND-expression} \lstinline$&&$ \nonterm{inclusive-OR-expression}
     1890\rhs \nonterm{logical-AND-expression} ©&&© \nonterm{inclusive-OR-expression}
    19181891\end{syntax}
    19191892
    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}@
     1893\semantics The operands of the expression ``©a && b©'' are treated as ``©(int)((a)!=0)©'' and ``©(int)((b)!=0)©'', which shall both be unambiguous.
     1894The expression has only one interpretation, which is of type ©int©.
     1895\begin{rationale}
     1896When the operands of a logical expression are values of built-in types, and ``©!=©'' has not been redefined for those types, the compiler can optimize away the function calls.
     1897
     1898A common C idiom omits comparisons to ©0© in the controlling expressions of loops and ©if© statements.
     1899For instance, the loop below iterates as long as ©rp© points at a ©Rational© value that is non-zero.
     1900
     1901\begin{lstlisting}
     1902extern otype Rational;§\use{Rational}§
     1903extern const Rational 0;§\use{0}§
    19331904extern int ?!=?( Rational, Rational );
    19341905Rational *rp;
    19351906while ( rp && *rp ) { ... }
    19361907\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.
     1908The logical expression calls the ©Rational© inequality operator, passing it ©*rp© and the ©Rational 0©, and getting a 1 or 0 as a result.
     1909In contrast, {\CC} would apply a programmer-defined ©Rational©-to-©int© conversion to ©*rp© in the equivalent situation.
     1910The conversion to ©int© would produce a general integer value, which is unfortunate, and possibly dangerous if the conversion was not written with this situation in mind.
    19401911\end{rationale}
    19411912
     
    19461917\lhs{logical-OR-expression}
    19471918\rhs \nonterm{logical-AND-expression}
    1948 \rhs \nonterm{logical-OR-expression} \lstinline$||$ \nonterm{logical-AND-expression}
     1919\rhs \nonterm{logical-OR-expression} ©||© \nonterm{logical-AND-expression}
    19491920\end{syntax}
    19501921
    19511922\semantics
    19521923
    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$.
     1924The operands of the expression ``©a || b©'' are treated as ``©(int)((a)!=0)©'' and ``©(int)((b))!=0)©'', which shall both be unambiguous.
     1925The expression has only one interpretation, which is of type ©int©.
    19551926
    19561927
     
    19601931\lhs{conditional-expression}
    19611932\rhs \nonterm{logical-OR-expression}
    1962 \rhs \nonterm{logical-OR-expression} \lstinline$?$ \nonterm{expression}
    1963          \lstinline$:$ \nonterm{conditional-expression}
     1933\rhs \nonterm{logical-OR-expression} ©?© \nonterm{expression}
     1934         ©:© \nonterm{conditional-expression}
    19641935\end{syntax}
    19651936
    19661937\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
     1938In the conditional expression\use{?:} ``©a?b:c©'', if the second and third operands both have an interpretation with ©void© type, then the expression has an interpretation with type ©void©, equivalent to
    19681939\begin{lstlisting}
    19691940( int)(( a)!=0) ? ( void)( b) : ( void)( c)
    19701941\end{lstlisting}
    19711942
    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
     1943If the second and third operands both have interpretations with non-©void© types, the expression is treated as if it were the call ``©cond((a)!=0, b, c)©'', with ©cond© declared as
    19731944\begin{lstlisting}
    19741945forall( otype T ) T cond( int, T, T );
     
    20221993rand() ? i : l;
    20231994\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$.
     1995The best interpretation infers the expression's type to be ©long© and applies the safe ©int©-to-©long© conversion to ©i©.
    20261996
    20271997\begin{lstlisting}
     
    20302000rand() ? cip : vip;
    20312001\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.
     2002The expression has type ©const volatile int *©, with safe conversions applied to the second and third operands to add ©volatile© and ©const© qualifiers, respectively.
    20332003
    20342004\begin{lstlisting}
    20352005rand() ? cip : 0;
    20362006\end{lstlisting}
    2037 The expression has type \lstinline$const int *$, with a specialization conversion applied to
    2038 \lstinline$0$.
     2007The expression has type ©const int *©, with a specialization conversion applied to ©0©.
    20392008
    20402009
     
    20472016         \nonterm{assignment-expression}
    20482017\lhs{assignment-operator} one of
    2049 \rhs \lstinline$=$\ \ \lstinline$*=$\ \ \lstinline$/=$\ \ \lstinline$%=$\ \ \lstinline$+=$\ \ \lstinline$-=$\ \ 
    2050          \lstinline$<<=$\ \ \lstinline$>>=$\ \ \lstinline$&=$\ \ \lstinline$^=$\ \ \lstinline$|=$
     2018\rhs ©=©\ \ ©*=©\ \ ©/=©\ \ ©%=©\ \ ©+=©\ \ ©-=©\ \ ©<<=©\ \ ©>>=©\ \ ©&=©\ \ ©^=©\ \ ©|=©
    20512019\end{syntax}
    20522020
    20532021\rewriterules
    2054 Let ``\(\leftarrow\)'' be any of the assignment operators.
     2022Let ``©<-©'' be any of the assignment operators.
    20552023Then
    2056 \use{?=?}\use{?*=?}\use{?/=?}\use{?%=?}\use{?+=?}\use{?-=?}
    2057 \use{?>>=?}\use{?&=?}\use{?^=?}\use{?"|=?}%use{?<<=?}
    2058 \begin{lstlisting}
    2059 a @$\leftarrow$@ b @\rewrite@ ?@$\leftarrow$@?( &( a ), b )
     2024\use{?=?}\use{?*=?}\use{?/=?}\use{?%=?}\use{?+=?}\use{?-=?}\use{?>>=?}\use{?&=?}\use{?^=?}\use{?"|=?}%use{?<<=?}
     2025\begin{lstlisting}
     2026a <- b => ?<-?( &( a ), b )
    20602027\end{lstlisting}
    20612028
    20622029\semantics
    20632030Each 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.
     2031For each interpretation that is a bit-field or is declared with the ©register© storage class specifier, the expression has one valid interpretation, with the type of the left operand.
    20652032The right operand is cast to that type, and the assignment expression is ambiguous if either operand is.
    20662033For the remaining interpretations, the expression is rewritten, and the interpretations of the assignment expression are the interpretations of the corresponding function call.
     
    22952262\end{lstlisting}
    22962263\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
     2264The pattern of overloadings for simple assignment resembles that of pointer increment and decrement, except that the polymorphic pointer assignment functions declare a ©dtype© parameter, instead of a ©type© parameter, because the left operand may be a pointer to an incomplete type.
     2265\end{rationale}
     2266
     2267For every complete structure or union type ©S© there exist
    23012268% Don't use predefined: keep this out of prelude.cf.
    23022269\begin{lstlisting}
     
    23042271\end{lstlisting}
    23052272
    2306 For every extended integer type \lstinline$X$ there exist
     2273For every extended integer type ©X© there exist
    23072274% Don't use predefined: keep this out of prelude.cf.
    23082275\begin{lstlisting}
     
    23102277\end{lstlisting}
    23112278
    2312 For every complete enumerated type \lstinline$E$ there exist
     2279For every complete enumerated type ©E© there exist
    23132280% Don't use predefined: keep this out of prelude.cf.
    23142281\begin{lstlisting}
     
    23162283\end{lstlisting}
    23172284\begin{rationale}
    2318 The right-hand argument is \lstinline$int$ because enumeration constants have type \lstinline$int$.
     2285The right-hand argument is ©int© because enumeration constants have type ©int©.
    23192286\end{rationale}
    23202287
     
    25772544\end{lstlisting}
    25782545
    2579 For every extended integer type \lstinline$X$ there exist
     2546For every extended integer type ©X© there exist
    25802547% Don't use predefined: keep this out of prelude.cf.
    25812548\begin{lstlisting}
     
    25922559\end{lstlisting}
    25932560
    2594 For every complete enumerated type \lstinline$E$ there exist
     2561For every complete enumerated type ©E© there exist
    25952562% Don't use predefined: keep this out of prelude.cf.
    25962563\begin{lstlisting}
     
    26132580\lhs{expression}
    26142581\rhs \nonterm{assignment-expression}
    2615 \rhs \nonterm{expression} \lstinline$,$ \nonterm{assignment-expression}
     2582\rhs \nonterm{expression} ©,© \nonterm{assignment-expression}
    26162583\end{syntax}
    26172584
    26182585\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}.
     2586In the comma expression ``©a, b©'', the first operand is interpreted as ``©( void )(a)©'', which shall be unambiguous\index{ambiguous interpretation}.
    26212587The interpretations of the expression are the interpretations of the second operand.
    26222588
     
    26532619{ ... }
    26542620\end{lstlisting}
    2655 Without the rule, \lstinline$Complex$ would be a type in the first case, and a parameter name in the second.
     2621Without the rule, ©Complex© would be a type in the first case, and a parameter name in the second.
    26562622\end{rationale}
    26572623
     
    26792645\examples
    26802646\begin{lstlisting}
    2681 struct point {@\impl{point}@
     2647struct point {§\impl{point}§
    26822648        int x, y;
    26832649};
    2684 struct color_point {@\impl{color_point}@
     2650struct color_point {§\impl{color_point}§
    26852651        enum { RED, BLUE, GREEN } color;
    26862652        struct point;
     
    26892655cp.x = 0;
    26902656cp.color = RED;
    2691 struct literal {@\impl{literal}@
     2657struct literal {§\impl{literal}§
    26922658        enum { NUMBER, STRING } tag;
    26932659        union {
     
    27102676\begin{syntax}
    27112677\lhs{forall-specifier}
    2712 \rhs \lstinline$forall$ \lstinline$($ \nonterm{type-parameter-list} \lstinline$)$
     2678\rhs ©forall© ©(© \nonterm{type-parameter-list} ©)©
    27132679\end{syntax}
    27142680
     
    27222688} mkPair( T, T ); // illegal
    27232689\end{lstlisting}
    2724 If an instance of \lstinline$struct Pair$ was declared later in the current scope, what would the members' type be?
     2690If an instance of ©struct Pair© was declared later in the current scope, what would the members' type be?
    27252691\end{rationale}
    27262692\end{comment}
     
    27292695The \nonterm{type-parameter-list}s and assertions of the \nonterm{forall-specifier}s declare type identifiers, function and object identifiers with \Index{no linkage}.
    27302696
    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
    2736 \nonterm{type-parameter-list} or it and an inferred parameter are used as arguments of a
    2737 \Index{specification} in one of the \nonterm{forall-specifier}s.
     2697If, in the declaration ``©T D©'', ©T© contains \nonterm{forall-specifier}s and ©D© has the form
     2698\begin{lstlisting}
     2699D( §\normalsize\nonterm{parameter-type-list}§ )
     2700\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 ©D©, and it is used in the type of a parameter in the following
     2701\nonterm{type-parameter-list} or it and an inferred parameter are used as arguments of a \Index{specification} in one of the \nonterm{forall-specifier}s.
    27382702The identifiers declared by assertions that use an inferred parameter of a function declarator are \Index{assertion parameter}s of that function declarator.
    27392703
     
    27442708If this restriction were lifted, it would be possible to write
    27452709\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}@
     2710forall( otype T ) T * alloc( void );§\use{alloc}§ int *p = alloc();
     2711\end{lstlisting}
     2712Here ©alloc()© would receive ©int© as an inferred argument, and return an ©int *©.
     2713In general, if a call to ©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 ©T© to be bound.
     2714
     2715With the current restriction, ©alloc()© must be given an argument that determines ©T©:
     2716\begin{lstlisting}
     2717forall( otype T ) T * alloc( T initial_value );§\use{alloc}§
    27562718\end{lstlisting}
    27572719\end{rationale}
     
    27592721
    27602722If a function declarator is part of a function definition, its inferred parameters and assertion parameters have \Index{block scope};
    2761 otherwise, identifiers declared by assertions have a
    2762 \define{declaration scope}, which terminates at the end of the \nonterm{declaration}.
     2723otherwise, identifiers declared by assertions have a \define{declaration scope}, which terminates at the end of the \nonterm{declaration}.
    27632724
    27642725A function type that has at least one inferred parameter is a \define{polymorphic function} type.
     
    27692730Let $f$ and $g$ be two polymorphic function types with the same number of inferred parameters, and let $f_i$ and $g_i$ be the inferred parameters of $f$ and $g$ in their order of occurance in the function types' \nonterm{parameter-type-list}s.
    27702731Let $f'$ be $f$ with every occurrence of $f_i$ replaced by $g_i$, for all $i$.
    2771 Then $f$ and $g$ are
    2772 \Index{compatible type}s if $f'$'s and $g$'s return types and parameter lists are compatible, and if for every assertion parameter of $f'$ there is an assertion parameter in $g$ with the same identifier and compatible type, and vice versa.
     2732Then $f$ and $g$ are \Index{compatible type}s if $f'$'s and $g$'s return types and parameter lists are compatible, and if for every assertion parameter of $f'$ there is an assertion parameter in $g$ with the same identifier and compatible type, and vice versa.
    27732733
    27742734\examples
     
    27782738forall( otype T ) T fT( T );
    27792739\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$.
     2740©fi()© takes an ©int© and returns an ©int©. ©fT()© takes a ©T© and returns a ©T©, for any type ©T©.
    27822741\begin{lstlisting}
    27832742int (*pfi )( int ) = fi;
    27842743forall( otype T ) T (*pfT )( T ) = fT;
    27852744\end{lstlisting}
    2786 \lstinline$pfi$ and \lstinline$pfT$ are pointers to functions. \lstinline$pfT$ is not polymorphic, but the function it points at is.
     2745©pfi© and ©pfT© are pointers to functions. ©pfT© is not polymorphic, but the function it points at is.
    27872746\begin{lstlisting}
    27882747int (*fvpfi( void ))( int ) {
     
    27932752}
    27942753\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.
     2754©fvpfi()© and ©fvpfT()© are functions taking no arguments and returning pointers to functions. ©fvpfT()© is monomorphic, but the function that its return value points at is polymorphic.
    27962755\begin{lstlisting}
    27972756forall( otype T ) int ( *fTpfi( T ) )( int );
     
    27992758forall( otype T, otype U ) U ( *fTpfU( T ) )( U );
    28002759\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 *$.
     2760©fTpfi()© is a polymorphic function that returns a pointer to a monomorphic function taking an integer and returning an integer.
     2761It could return ©pfi©. ©fTpfT()© is subtle: it is a polymorphic function returning a \emph{monomorphic} function taking and returning
     2762©T©, where ©T© is an inferred parameter of ©fTpfT()©.
     2763For instance, in the expression ``©fTpfT(17)©'', ©T© is inferred to be ©int©, and the returned value would have type ©int ( * )( int )©. ``©fTpfT(17)(13)©'' and ``©fTpfT("yes")("no")©'' are legal, but ``©fTpfT(17)("no")©'' is illegal.
     2764©fTpfU()© is polymorphic ( in type ©T©), and returns a pointer to a function that is polymorphic ( in type ©U©). ``©f5(17)("no")©'' is a legal expression of type ©char *©.
    28082765\begin{lstlisting}
    28092766forall( otype T, otype U, otype V ) U * f( T *, U, V * const );
    28102767forall( otype U, otype V, otype W ) U * g( V *, U, W * const );
    28112768\end{lstlisting}
    2812 The functions \lstinline$f()$ and \lstinline$g()$ have compatible types.
     2769The functions ©f()© and ©g()© have compatible types.
    28132770Let \(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$.
     2771then \(f_1\) = ©T©, \(f_2\) = ©U©, \(f_3\) = ©V©, \(g_1\)
     2772= ©V©, \(g_2\) = ©U©, and \(g_3\) = ©W©.
    28162773Replacing every \(f_i\) by \(g_i\) in \(f\) gives
    28172774\begin{lstlisting}
     
    28192776\end{lstlisting} which has a return type and parameter list that is compatible with \(g\).
    28202777\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.
     2778The word ``©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.
    28222779
    28232780Even without parameterized types, I might try to allow
     
    28452802\subsection{Type qualifiers}
    28462803
    2847 \CFA defines a new type qualifier \lstinline$lvalue$\impl{lvalue}\index{lvalue}.
     2804\CFA defines a new type qualifier ©lvalue©\impl{lvalue}\index{lvalue}.
    28482805\begin{syntax}
    28492806\oldlhs{type-qualifier}
    2850 \rhs \lstinline$lvalue$
     2807\rhs ©lvalue©
    28512808\end{syntax}
    28522809
    28532810\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.
     2811\Indexc{restrict} Types other than type parameters and pointer types whose referenced type is an object type shall not be restrict-qualified.
    28552812
    28562813\semantics
    2857 An object's type may be a restrict-qualified type parameter. \lstinline$restrict$ does not establish any special semantics in that case.
     2814An object's type may be a restrict-qualified type parameter.
     2815©restrict© does not establish any special semantics in that case.
    28582816
    28592817\begin{rationale}
     
    28612819\end{rationale}
    28622820
    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;
    2865 then 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.
     2821©lvalue© may be used to qualify the return type of a function type.
     2822Let ©T© be an unqualified version of a type;
     2823then the result of calling a function with return type ©lvalue T© is a \Index{modifiable lvalue} of type ©T©.
     2824©const©\use{const} and ©volatile©\use{volatile} qualifiers may also be added to indicate that the function result is a constant or volatile lvalue.
     2825\begin{rationale}
     2826The ©const© and ©volatile© qualifiers can only be sensibly used to qualify the return type of a function if the ©lvalue© qualifier is also used.
    28702827\end{rationale}
    28712828
     
    28742831
    28752832\begin{rationale}
    2876 \lstinline$lvalue$ provides some of the functionality of {\CC}'s ``\lstinline$T&$'' ( reference to object of type \lstinline$T$) type.
     2833©lvalue© provides some of the functionality of {\CC}'s ``©T&©'' ( reference to object of type ©T©) type.
    28772834Reference types have four uses in {\CC}.
    28782835\begin{itemize}
    28792836\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.
     2837They are necessary for user-defined operators that return lvalues, such as ``subscript'' and ``dereference''.
     2838
     2839\item
     2840A 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 ©with© statement.
    28852841The following {\CC} code gives an example.
    28862842\begin{lstlisting}
     
    28952851A reference parameter can be used to allow a function to modify an argument without forcing the caller to pass the address of the argument.
    28962852This 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
     2853In {\CC}, plain assignment is done by a function called ``©operator=©'', and the two expressions
    28982854\begin{lstlisting}
    28992855a = b;
    29002856operator=( a, b );
    29012857\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&$''.
    2903 It 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$&$''.
     2858If ©a© and ©b© are of type ©T©, then the first parameter of ©operator=© must have type ``©T&©''.
     2859It cannot have type ©T©, because then assignment couldn't alter the variable, and it can't have type ``©T *©'', because the assignment would have to be written ``©&a = b;©''.
     2860
     2861In 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 ``©a = b;©'' is equivalent to ``©operator=(&( a), b )©''.
     2862Reference 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 ``©&©''.
    29102863
    29112864\item
    29122865References 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
     2866{\CC} function call ``©fiddle( a_thing )©'', where the type of ©a_thing© is
     2867©Thing©, the type of ©fiddle© could be either of
    29152868\begin{lstlisting}
    29162869void fiddle( Thing );
    29172870void fiddle( const Thing & );
    29182871\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.
     2872If 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 ©fiddle© the parameter is subject to the usual problems caused by aliases.
     2873The reference form might be chosen for efficiency's sake if ©Thing©s are too large or their constructors or destructors are too expensive.
    29212874An implementation may switch between them without causing trouble for well-behaved clients.
    29222875This leaves the implementor to define ``too large'' and ``too expensive''.
     
    29262879void fiddle( const volatile Thing );
    29272880\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''.
     2881Since it knows all about the size of ©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''.
    29292882\end{itemize}
    29302883
     
    29462899\begin{syntax}
    29472900\lhs{spec-definition}
    2948 \rhs \lstinline$spec$ \nonterm{identifier}
    2949         \lstinline$($ \nonterm{type-parameter-list} \lstinline$)$
    2950         \lstinline${$ \nonterm{spec-declaration-list}\opt \lstinline$}$
     2901\rhs ©spec© \nonterm{identifier}
     2902        ©(© \nonterm{type-parameter-list} ©)©
     2903        ©{© \nonterm{spec-declaration-list}\opt ©}©
    29512904\lhs{spec-declaration-list}
    2952 \rhs \nonterm{spec-declaration} \lstinline$;$
    2953 \rhs \nonterm{spec-declaration-list} \nonterm{spec-declaration} \lstinline$;$
     2905\rhs \nonterm{spec-declaration} ©;©
     2906\rhs \nonterm{spec-declaration-list} \nonterm{spec-declaration} ©;©
    29542907\lhs{spec-declaration}
    29552908\rhs \nonterm{specifier-qualifier-list} \nonterm{declarator-list}
    29562909\lhs{declarator-list}
    29572910\rhs \nonterm{declarator}
    2958 \rhs \nonterm{declarator-list} \lstinline$,$ \nonterm{declarator}
     2911\rhs \nonterm{declarator-list} ©,© \nonterm{declarator}
    29592912\end{syntax}
    29602913\begin{rationale}
     
    29782931\rhs \nonterm{assertion-list} \nonterm{assertion}
    29792932\lhs{assertion}
    2980 \rhs \lstinline$|$ \nonterm{identifier} \lstinline$($ \nonterm{type-name-list} \lstinline$)$
    2981 \rhs \lstinline$|$ \nonterm{spec-declaration}
     2933\rhs ©|© \nonterm{identifier} ©(© \nonterm{type-name-list} ©)©
     2934\rhs ©|© \nonterm{spec-declaration}
    29822935\lhs{type-name-list}
    29832936\rhs \nonterm{type-name}
    2984 \rhs \nonterm{type-name-list} \lstinline$,$ \nonterm{type-name}
     2937\rhs \nonterm{type-name-list} ©,© \nonterm{type-name}
    29852938\end{syntax}
    29862939
     
    29892942The \nonterm{type-name-list} shall contain one \nonterm{type-name} argument for each \nonterm{type-parameter} in that specification's \nonterm{spec-parameter-list}.
    29902943If 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}.
     2944\nonterm{type-parameter} uses type-class ©type©\use{type}, the argument shall be the type name of an \Index{object type};
     2945if it uses ©dtype©, the argument shall be the type name of an object type or an \Index{incomplete type};
     2946and if it uses ©ftype©, the argument shall be the type name of a \Index{function type}.
    29942947
    29952948\semantics
    2996 An \define{assertion} is a declaration of a collection of objects and functions, called
    2997 \define{assertion parameters}.
     2949An \define{assertion} is a declaration of a collection of objects and functions, called \define{assertion parameters}.
    29982950
    29992951The assertion parameters produced by an assertion that applies the name of a specification to type arguments are found by taking the declarations specified in the specification and treating each of the specification's parameters as a synonym for the corresponding \nonterm{type-name} argument.
     
    30042956\examples
    30052957\begin{lstlisting}
    3006 forall( otype T | T ?*?( T, T ))@\use{?*?}@
    3007 T square( T val ) {@\impl{square}@
     2958forall( otype T | T ?*?( T, T ))§\use{?*?}§
     2959T square( T val ) {§\impl{square}§
    30082960        return val + val;
    30092961}
    3010 trait summable( otype T ) {@\impl{summable}@
    3011         T ?+=?( T *, T );@\use{?+=?}@
    3012         const T 0;@\use{0}@
     2962trait summable( otype T ) {§\impl{summable}§
     2963        T ?+=?( T *, T );§\use{?+=?}§
     2964        const T 0;§\use{0}§
    30132965};
    3014 trait list_of( otype List, otype Element ) {@\impl{list_of}@
     2966trait list_of( otype List, otype Element ) {§\impl{list_of}§
    30152967        Element car( List );
    30162968        List cdr( List );
     
    30212973trait sum_list( otype List, otype Element | summable( Element ) | list_of( List, Element ) ) {};
    30222974\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
     2975©sum_list© contains seven declarations, which describe a list whose elements can be added up.
     2976The assertion ``©|sum_list( i_list, int )©''\use{sum_list} produces the assertion parameters
    30252977\begin{lstlisting}
    30262978int ?+=?( int *, int );
     
    30392991\lhs{type-parameter-list}
    30402992\rhs \nonterm{type-parameter}
    3041 \rhs \nonterm{type-parameter-list} \lstinline$,$ \nonterm{type-parameter}
     2993\rhs \nonterm{type-parameter-list} ©,© \nonterm{type-parameter}
    30422994\lhs{type-parameter}
    30432995\rhs \nonterm{type-class} \nonterm{identifier} \nonterm{assertion-list}\opt
    30442996\lhs{type-class}
    3045 \rhs \lstinline$type$
    3046 \rhs \lstinline$dtype$
    3047 \rhs \lstinline$ftype$
     2997\rhs ©type©
     2998\rhs ©dtype©
     2999\rhs ©ftype©
    30483000\lhs{type-declaration}
    3049 \rhs \nonterm{storage-class-specifier}\opt \lstinline$type$ \nonterm{type-declarator-list} \verb|;|
     3001\rhs \nonterm{storage-class-specifier}\opt ©type© \nonterm{type-declarator-list} \verb|;|
    30503002\lhs{type-declarator-list}
    30513003\rhs \nonterm{type-declarator}
    3052 \rhs \nonterm{type-declarator-list} \lstinline$,$ \nonterm{type-declarator}
     3004\rhs \nonterm{type-declarator-list} ©,© \nonterm{type-declarator}
    30533005\lhs{type-declarator}
    3054 \rhs \nonterm{identifier} \nonterm{assertion-list}\opt \lstinline$=$ \nonterm{type-name}
     3006\rhs \nonterm{identifier} \nonterm{assertion-list}\opt ©=© \nonterm{type-name}
    30553007\rhs \nonterm{identifier} \nonterm{assertion-list}\opt
    30563008\end{syntax}
     
    30633015
    30643016An 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;
    3066 those declared with type-class
    3067 \lstinline$dtype$\use{dtype} are \Index{incomplete type}s;
    3068 and those declared with type-class
    3069 \lstinline$ftype$\use{ftype} are \Index{function type}s.
     3017Identifiers declared with type-class ©type©\use{type} are \Index{object type}s;
     3018those declared with type-class ©dtype©\use{dtype} are \Index{incomplete type}s;
     3019and those declared with type-class ©ftype©\use{ftype} are \Index{function type}s.
    30703020The 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}.
    30713021
     
    30753025Within 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.
    30763026
    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}.
    3078 If a
    3079 \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).
     3027A type declaration without an \Index{initializer} and without a \Index{storage-class specifier} or with storage-class specifier ©static©\use{static} defines an \Index{incomplete type}.
     3028If a \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).
    30803029\begin{rationale}
    30813030Incomplete type declarations allow compact mutually-recursive types.
     
    30943043\end{rationale}
    30953044
    3096 A type declaration without an initializer and with \Index{storage-class specifier}
    3097 \lstinline$extern$\use{extern} is an \define{opaque type declaration}.
    3098 Opaque types are
    3099 \Index{object type}s.
     3045A type declaration without an initializer and with \Index{storage-class specifier} ©extern©\use{extern} is an \define{opaque type declaration}.
     3046Opaque types are \Index{object type}s.
    31003047An opaque type is not a \nonterm{constant-expression};
    3101 neither is a structure or union that has a member whose type is not a \nonterm{constant-expression}.  Every other
    3102 \Index{object type} is a \nonterm{constant-expression}.
     3048neither is a structure or union that has a member whose type is not a \nonterm{constant-expression}.
     3049Every other \Index{object type} is a \nonterm{constant-expression}.
    31033050Objects with static storage duration shall be declared with a type that is a \nonterm{constant-expression}.
    31043051\begin{rationale}
     
    31103057\end{rationale}
    31113058
    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$.
    3114 A
    3115 \Index{function type} is a value of type-class \lstinline$ftype$.
     3059An \Index{incomplete type} which is not a qualified version\index{qualified type} of a type is a value of \Index{type-class} ©dtype©.
     3060An object type\index{object types} which is not a qualified version of a type is a value of type-classes ©type© and ©dtype©.
     3061A \Index{function type} is a value of type-class ©ftype©.
    31163062\begin{rationale}
    31173063Syntactically, a type value is a \nonterm{type-name}, which is a declaration for an object which omits the identifier being declared.
     
    31223068
    31233069Type qualifiers are a weak point of C's type system.
    3124 Consider 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}@
     3070Consider the standard library function ©strchr()© which, given a string and a character, returns a pointer to the first occurrence of the character in the string.
     3071\begin{lstlisting}
     3072char *strchr( const char *s, int c ) {§\impl{strchr}§
    31283073        char real_c = c; // done because c was declared as int.
    31293074        for ( ; *s != real_c; s++ )
     
    31323077}
    31333078\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.
    3135 Hence 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.
     3079The parameter ©s© must be ©const char *©, because ©strchr()© might be used to search a constant string, but the return type must be ©char *©, because the result might be used to modify a non-constant string.
     3080Hence the body must perform a cast, and ( even worse) ©strchr()© provides a type-safe way to attempt to modify constant strings.
     3081What is needed is some way to say that ©s©'s type might contain qualifiers, and the result type has exactly the same qualifiers.
    31383082Polymorphic 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.
     3083Instead, overloading can be used to define ©strchr()© for each combination of qualifiers.
    31403084\end{rationale}
    31413085
     
    31613105};
    31623106\end{lstlisting}
    3163 Without 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$.
     3107Without this restriction, \CFA might require ``module initialization'' code ( since ©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 ©Huge© and the translation that declares ©Rational©.
    31653108
    31663109A 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.
     
    31683111//  File a.c:
    31693112        extern type t1;
    3170         type t2 = struct { t1 f1; ... } // illegal
     3113        type t2 = struct { t1 f1; ... } // illegal
    31713114//  File b.c:
    31723115        extern type t2;
    3173         type t1 = struct { t2 f2; ... } // illegal
     3116        type t1 = struct { t2 f2; ... } // illegal
    31743117\end{lstlisting}
    31753118\end{rationale}
     
    31793122\nonterm{struct-declaration}, type declarations can not be structure members.
    31803123The form of
    3181 \nonterm{type-declaration} forbids arrays of, pointers to, and functions returning \lstinline$type$.
     3124\nonterm{type-declaration} forbids arrays of, pointers to, and functions returning ©type©.
    31823125Hence the syntax of \nonterm{type-specifier} does not have to be extended to allow type-valued expressions.
    31833126It also side-steps the problem of type-valued expressions producing different values in different declarations.
     
    31943137#include <stdlib.h>
    31953138T * 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$;
     3139... int * ip = new( int );
     3140\end{lstlisting}
     3141This looks sensible, but \CFA's declaration-before-use rules mean that ``©T©'' in the function body refers to the parameter, but the ``©T©'' in the return type refers to the meaning of ©T© in the scope that contains ©new©;
    31993142it could be undefined, or a type name, or a function or variable name.
    32003143Nothing good can result from such a situation.
     
    32133156f2( v2 );
    32143157\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]$.
     3158©V1© is passed by value, so ©f1()©'s assignment to ©a[0]© does not modify v1.  ©V2© is converted to a pointer, so ©f2()© modifies ©v2[0]©.
    32163159
    32173160A translation unit containing the declarations
    32183161\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$.
     3162extern type Complex;§\use{Complex}§ // opaque type declaration
     3163extern float abs( Complex );§\use{abs}§
     3164\end{lstlisting} can contain declarations of complex numbers, which can be passed to ©abs©.
     3165Some other translation unit must implement ©Complex© and ©abs©.
    32233166That unit might contain the declarations
    32243167\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 )}@
     3168otype Complex = struct { float re, im; };§\impl{Complex}§
     3169Complex cplx_i = { 0.0, 1.0 };§\impl{cplx_i}§
     3170float abs( Complex c ) {§\impl{abs( Complex )}§
    32283171        return sqrt( c.re * c.re + c.im * c.im );
    32293172}
    32303173\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{?+?}@
     3174Note that ©c© is implicitly converted to a ©struct© so that its components can be retrieved.
     3175
     3176\begin{lstlisting}
     3177otype Time_of_day = int;§\impl{Time_of_day}§ // seconds since midnight.
     3178Time_of_day ?+?( Time_of_day t1, int seconds ) {§\impl{?+?}§
    32363179        return (( int)t1 + seconds ) % 86400;
    32373180}
    32383181\end{lstlisting}
    3239 \lstinline$t1$ must be cast to its implementation type to prevent infinite recursion.
     3182©t1© must be cast to its implementation type to prevent infinite recursion.
    32403183
    32413184\begin{rationale}
    32423185Within 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.
     3186In the ©Time_of_day© example, the difference is important.
    32443187Different languages have treated the distinction between the abstraction and the implementation in different ways.
    32453188\begin{itemize}
    32463189\item
    32473190Inside 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.
     3191Two primitives called ©up© and ©down© can be used to convert between the views.
    32493192\item
    32503193The Simula class \cite{SIMULA87} is essentially a record type.
    32513194Since 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.
    32523195In {\CC}
    3253 \cite{C++}, operations on class instances include assignment and ``\lstinline$&$'', which can be overloaded.
     3196\cite{C++}, operations on class instances include assignment and ``©&©'', which can be overloaded.
    32543197A ``scope resolution'' operator can be used inside the class to specify whether the abstract or implementation version of the operation should be used.
    32553198\item
     
    32643207In this case, explicit conversions between the derived type and the old type can be used.
    32653208\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$.
     3209\CFA's rules are like Clu's, except that implicit conversions and conversion costs allow it to do away with most uses of ©up© and ©down©.
    32673210\end{rationale}
    32683211
     
    32703213\subsubsection{Default functions and objects}
    32713214
    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$.
     3215A declaration\index{type declaration} of a type identifier ©T© with type-class ©type© implicitly declares a \define{default assignment} function ©T ?=?( T *, T )©\use{?=?}, with the same \Index{scope} and \Index{linkage} as the identifier ©T©.
    32753216\begin{rationale}
    32763217Assignment 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).
    32773218Without this rule, nearly every inferred type parameter would need an accompanying assignment assertion parameter.
    3278 If a type parameter should not have an assignment operation,
    3279 \lstinline$dtype$ should be used.
     3219If a type parameter should not have an assignment operation, ©dtype© should be used.
    32803220If 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.
    32813221\end{rationale}
    32823222
    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
    3285 \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$.
     3223A definition\index{type definition} of a type identifier ©T© with \Index{implementation type} ©I© and type-class ©type© implicitly defines a default assignment function.
     3224A definition\index{type definition} of a type identifier ©T© with implementation type ©I© and an assertion list implicitly defines \define{default function}s and \define{default object}s as declared by the assertion declarations.
     3225The default objects and functions have the same \Index{scope} and \Index{linkage} as the identifier ©T©.
    32873226Their values are determined as follows:
    32883227\begin{itemize}
    32893228\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.
     3229If at the definition of ©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 ©I© replaced by ©T© is compatible with the type of the default object, then the default object is initialized with that object.
     3230Otherwise the scope of the declaration of ©T© must contain a definition of the default object.
    32923231
    32933232\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.
     3233If at the definition of ©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 ©I© replaced by ©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.
     3234
     3235Otherwise, if ©I© contains exactly one anonymous member\index{anonymous member} such that at the definition of ©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 ©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.
     3236
     3237Otherwise the scope of the declaration of ©T© must contain a definition of the default function.
    32993238\end{itemize}
    33003239\begin{rationale}
     
    33023241\end{rationale}
    33033242
    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.
     3243A 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 ©T© replaces the default function or object.
    33053244
    33063245\examples
     
    33123251Pair b = { 1, 1 };
    33133252\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$.
    3316 The definition of
    3317 \lstinline$Pair b$ is compulsory because there is no \lstinline$struct impl b$ to construct a value from.
     3253The definition of ©Pair© implicitly defines two objects ©a© and ©b©.
     3254©Pair a© inherits its value from the ©struct impl a©.
     3255The definition of ©Pair b© is compulsory because there is no ©struct impl b© to construct a value from.
    33183256\begin{lstlisting}
    33193257trait ss( otype T ) {
     
    33213259        void munge( T * );
    33223260}
    3323 otype Whatsit | ss( Whatsit );@\use{Whatsit}@
    3324 otype Doodad | ss( Doodad ) = struct doodad {@\use{Doodad}@
     3261otype Whatsit | ss( Whatsit );§\use{Whatsit}§
     3262otype Doodad | ss( Doodad ) = struct doodad {§\use{Doodad}§
    33253263        Whatsit; // anonymous member
    33263264        int extra;
     
    33283266Doodad clone( Doodad ) { ... }
    33293267\end{lstlisting}
    3330 The definition of \lstinline$Doodad$ implicitly defines three functions:
     3268The definition of ©Doodad© implicitly defines three functions:
    33313269\begin{lstlisting}
    33323270Doodad ?=?( Doodad *, Doodad );
     
    33343272void munge( Doodad * );
    33353273\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.
    3340 Hence the definition of
    3341 ``\lstinline$Doodad clone( Doodad )$'' is necessary.
     3274The assignment function inherits ©struct doodad©'s assignment function because the types match when ©struct doodad©  is replaced by ©Doodad© throughout.
     3275©munge()© inherits ©Whatsit©'s ©munge()© because the types match when ©Whatsit© is replaced by ©Doodad© in the parameter list. ©clone()© does \emph{not} inherit ©Whatsit©'s ©clone()©: replacement in the parameter list yields ``©Whatsit clone( Doodad )©'', which is not compatible with ©Doodad©'s ©clone()©'s type.
     3276Hence the definition of ``©Doodad clone( Doodad )©'' is necessary.
    33423277
    33433278Default functions and objects are subject to the normal scope rules.
    33443279\begin{lstlisting}
    3345 otype T = @\ldots@;
    3346 T a_T = @\ldots@;               // Default assignment used.
     3280otype T = ...;
     3281T a_T = ...;            // Default assignment used.
    33473282T ?=?( T *, T );
    3348 T a_T = @\ldots@;               // Programmer-defined assignment called.
     3283T a_T = ...;            // Programmer-defined assignment called.
    33493284\end{lstlisting}
    33503285\begin{rationale}
     
    33793314\begin{syntax}
    33803315\oldlhs{labeled-statement}
    3381 \rhs \lstinline$case$ \nonterm{case-value-list} : \nonterm{statement}
     3316\rhs ©case© \nonterm{case-value-list} : \nonterm{statement}
    33823317\lhs{case-value-list}
    33833318\rhs \nonterm{case-value}
    3384 \rhs \nonterm{case-value-list} \lstinline$,$ \nonterm{case-value}
     3319\rhs \nonterm{case-value-list} ©,© \nonterm{case-value}
    33853320\lhs{case-value}
    33863321\rhs \nonterm{constant-expression}
    33873322\rhs \nonterm{subrange}
    33883323\lhs{subrange}
    3389 \rhs \nonterm{constant-expression} \lstinline$~$ \nonterm{constant-expression}
     3324\rhs \nonterm{constant-expression} ©~© \nonterm{constant-expression}
    33903325\end{syntax}
    33913326
     
    34003335case 1~4, 9~14, 27~32:
    34013336\end{lstlisting}
    3402 The \lstinline$case$ and \lstinline$default$ clauses are restricted within the \lstinline$switch$ and \lstinline$choose$ statements, precluding Duff's device.
     3337The ©case© and ©default© clauses are restricted within the ©switch© and ©choose© statements, precluding Duff's device.
    34033338
    34043339
    34053340\subsection{Expression and null statements}
    34063341
    3407 The expression in an expression statement is treated as being cast to \lstinline$void$.
     3342The expression in an expression statement is treated as being cast to ©void©.
    34083343
    34093344
     
    34123347\begin{syntax}
    34133348\oldlhs{selection-statement}
    3414 \rhs \lstinline$choose$ \lstinline$($ \nonterm{expression} \lstinline$)$ \nonterm{statement}
     3349\rhs ©choose© ©(© \nonterm{expression} ©)© \nonterm{statement}
    34153350\end{syntax}
    34163351
    3417 The controlling expression \lstinline$E$ in the \lstinline$switch$ and \lstinline$choose$ statement:
     3352The controlling expression ©E© in the ©switch© and ©choose© statement:
    34183353\begin{lstlisting}
    34193354switch ( E ) ...
     
    34213356\end{lstlisting} may have more than one interpretation, but it shall have only one interpretation with an integral type.
    34223357An \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.
     3358The constant expressions in ©case© statements with the switch are converted to the promoted type.
    34243359
    34253360
    34263361\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.
     3362\subsubsection[The choose statement]{The \lstinline@choose@ statement}
     3363
     3364The ©choose© statement is the same as the ©switch© statement except control transfers to the end of the ©choose© statement at a ©case© or ©default© labeled statement.
     3365The ©fallthru© statement is used to fall through to the next ©case© or ©default© labeled statement.
    34313366The following have identical meaning:
    34323367\begin{flushleft}
     
    34533388\end{tabular}
    34543389\end{flushleft}
    3455 The \lstinline$choose$ statement addresses the problem of accidental fall-through associated with the \lstinline$switch$ statement.
     3390The ©choose© statement addresses the problem of accidental fall-through associated with the ©switch© statement.
    34563391
    34573392
    34583393\subsection{Iteration statements}
    34593394
    3460 The controlling expression \lstinline$E$ in the loops
     3395The controlling expression ©E© in the loops
    34613396\begin{lstlisting}
    34623397if ( E ) ...
    34633398while ( E ) ...
    34643399do ... while ( E );
    3465 \end{lstlisting} is treated as ``\lstinline$( int )((E)!=0)$''.
     3400\end{lstlisting}
     3401is treated as ``©( int )((E)!=0)©''.
    34663402
    34673403The statement
    34683404\begin{lstlisting}
    3469 for ( a; b; c ) @\ldots@
     3405for ( a; b; c ) ...
    34703406\end{lstlisting} is treated as
    34713407\begin{lstlisting}
     
    34783414\begin{syntax}
    34793415\oldlhs{jump-statement}
    3480 \rhs \lstinline$continue$ \nonterm{identifier}\opt
    3481 \rhs \lstinline$break$ \nonterm{identifier}\opt
     3416\rhs ©continue© \nonterm{identifier}\opt
     3417\rhs ©break© \nonterm{identifier}\opt
    34823418\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}
     3419\rhs ©throw© \nonterm{assignment-expression}\opt
     3420\rhs ©throwResume© \nonterm{assignment-expression}\opt \nonterm{at-expression}\opt
     3421\lhs{at-expression} ©_At© \nonterm{assignment-expression}
    34863422\end{syntax}
    34873423
    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.
     3424Labeled ©continue© and ©break© allow useful but restricted control-flow that reduces the need for the ©goto© statement for exiting multiple nested control-structures.
    34893425\begin{lstlisting}
    34903426L1: {                                                   // compound
     
    35133449
    35143450\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}
     3451\subsubsection[The continue statement]{The \lstinline@continue@ statement}
     3452
     3453The identifier in a ©continue© statement shall name a label located on an enclosing iteration statement.
     3454
     3455
     3456\subsubsection[The break statement]{The \lstinline@break@ statement}
     3457
     3458The identifier in a ©break© statement shall name a label located on an enclosing compound, selection or iteration statement.
     3459
     3460
     3461\subsubsection[The return statement]{The \lstinline@return@ statement}
     3462
     3463An expression in a ©return© statement is treated as being cast to the result type of the function.
     3464
     3465
     3466\subsubsection[The throw statement]{The \lstinline@throw@ statement}
    35313467
    35323468When an exception is raised, \Index{propagation} directs control from a raise in the source execution to a handler in the faulting execution.
    35333469
    35343470
    3535 \subsubsection{The \lstinline$throwResume$ statement}
     3471\subsubsection[The throwResume statement]{The \lstinline@throwResume@ statement}
    35363472
    35373473
     
    35403476\begin{syntax}
    35413477\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}
     3478\rhs ©try© \nonterm{compound-statement} \nonterm{handler-list}
     3479\rhs ©try© \nonterm{compound-statement} \nonterm{finally-clause}
     3480\rhs ©try© \nonterm{compound-statement} \nonterm{handler-list} \nonterm{finally-clause}
    35453481\lhs{handler-list}
    35463482\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}
     3483\rhs ©catch© ©(© \ldots ©)© \nonterm{compound-statement}
     3484\rhs \nonterm{handler-clause} ©catch© ©(© \ldots ©)© \nonterm{compound-statement}
     3485\rhs ©catchResume© ©(© \ldots ©)© \nonterm{compound-statement}
     3486\rhs \nonterm{handler-clause} ©catchResume© ©(© \ldots ©)© \nonterm{compound-statement}
    35513487\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}
     3488\rhs ©catch© ©(© \nonterm{exception-declaration} ©)© \nonterm{compound-statement}
     3489\rhs \nonterm{handler-clause} ©catch© ©(© \nonterm{exception-declaration} ©)© \nonterm{compound-statement}
     3490\rhs ©catchResume© ©(© \nonterm{exception-declaration} ©)© \nonterm{compound-statement}
     3491\rhs \nonterm{handler-clause} ©catchResume© ©(© \nonterm{exception-declaration} ©)© \nonterm{compound-statement}
    35563492\lhs{finally-clause}
    3557 \rhs \lstinline$finally$ \nonterm{compound-statement}
     3493\rhs ©finally© \nonterm{compound-statement}
    35583494\lhs{exception-declaration}
    35593495\rhs \nonterm{type-specifier}
     
    35633499\rhs \nonterm{new-abstract-declarator-tuple}
    35643500\lhs{asynchronous-statement}
    3565 \rhs \lstinline$enable$ \nonterm{identifier-list} \nonterm{compound-statement}
    3566 \rhs \lstinline$disable$ \nonterm{identifier-list} \nonterm{compound-statement}
     3501\rhs ©enable© \nonterm{identifier-list} \nonterm{compound-statement}
     3502\rhs ©disable© \nonterm{identifier-list} \nonterm{compound-statement}
    35673503\end{syntax}
    35683504
     
    35703506
    35713507
    3572 \subsubsection{The \lstinline$try$ statement}
    3573 
    3574 The \lstinline$try$ statement is a block with associated handlers, called a \Index{guarded block};
     3508\subsubsection[The try statement]{The \lstinline@try@ statement}
     3509
     3510The ©try© statement is a block with associated handlers, called a \Index{guarded block};
    35753511all 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.
     3512A ©goto©, ©break©, ©return©, or ©continue© statement can be used to transfer control out of a try block or handler, but not into one.
     3513
     3514
     3515\subsubsection[The enable/disable statements]{The \lstinline@enable@/\lstinline@disable@ statements}
     3516
     3517The ©enable©/©disable© statements toggle delivery of \Index{asynchronous exception}s.
    35823518
    35833519
     
    35893525\subsection{Predefined macro names}
    35903526
    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.
     3527The implementation shall define the macro names ©__LINE__©, ©__FILE__©, ©__DATE__©, and ©__TIME__©, as in the {\c11} standard.
     3528It shall not define the macro name ©__STDC__©.
     3529
     3530In addition, the implementation shall define the macro name ©__CFORALL__© to be the decimal constant 1.
    35963531
    35973532
     
    36103545The pointer, integral, and floating-point types are all \define{scalar types}.
    36113546All 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}@
     3547The assertion ``©scalar( Complex )©'' should be read as ``type ©Complex© is scalar''.
     3548\begin{lstlisting}
     3549trait scalar( otype T ) {§\impl{scalar}§
    36153550        int !?( T );
    36163551        int ?<?( T, T ), ?<=?( T, T ), ?==?( T, T ), ?>=?( T, T ), ?>?( T, T ), ?!=?( T, T );
     
    36223557This is equivalent to inheritance of specifications.
    36233558\begin{lstlisting}
    3624 trait arithmetic( otype T | scalar( T ) ) {@\impl{arithmetic}@@\use{scalar}@
     3559trait arithmetic( otype T | scalar( T ) ) {§\impl{arithmetic}§§\use{scalar}§
    36253560        T +?( T ), -?( T );
    36263561        T ?*?( T, T ), ?/?( T, T ), ?+?( T, T ), ?-?( T, T );
     
    36283563\end{lstlisting}
    36293564
    3630 The various flavors of \lstinline$char$ and \lstinline$int$ and the enumerated types make up the
    3631 \define{integral types}.
    3632 \begin{lstlisting}
    3633 trait integral( otype T | arithmetic( T ) ) {@\impl{integral}@@\use{arithmetic}@
     3565The various flavors of ©char© and ©int© and the enumerated types make up the \define{integral types}.
     3566\begin{lstlisting}
     3567trait integral( otype T | arithmetic( T ) ) {§\impl{integral}§§\use{arithmetic}§
    36343568        T ~?( T );
    36353569        T ?&?( T, T ), ?|?( T, T ), ?^?( T, T );
     
    36453579The only operation that can be applied to all modifiable lvalues is simple assignment.
    36463580\begin{lstlisting}
    3647 trait m_lvalue( otype T ) {@\impl{m_lvalue}@
     3581trait m_lvalue( otype T ) {§\impl{m_lvalue}§
    36483582        T ?=?( T *, T );
    36493583};
     
    36553589Scalars can also be incremented and decremented.
    36563590\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}@
     3591trait m_l_scalar( otype T | scalar( T ) | m_lvalue( T ) ) {§\impl{m_l_scalar}§
     3592        T ?++( T * ), ?--( T * );§\use{scalar}§§\use{m_lvalue}§
    36593593        T ++?( T * ), --?( T * );
    36603594};
     
    36623596
    36633597Modifiable 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}@
     3598Note that this results in the ``inheritance'' of ©scalar© along both paths.
     3599\begin{lstlisting}
     3600trait m_l_arithmetic( otype T | m_l_scalar( T ) | arithmetic( T ) ) {§\impl{m_l_arithmetic}§
     3601        T ?/=?( T *, T ), ?*=?( T *, T );§\use{m_l_scalar}§§\use{arithmetic}§
    36683602        T ?+=?( T *, T ), ?-=?( T *, T );
    36693603};
    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}@
     3604trait m_l_integral( otype T | m_l_arithmetic( T ) | integral( T ) ) {§\impl{m_l_integral}§
     3605        T ?&=?( T *, T ), ?|=?( T *, T ), ?^=?( T *, T );§\use{m_l_arithmetic}§
     3606        T ?%=?( T *, T ), ?<<=?( T *, T ), ?>>=?( T *, T );§\use{integral}§
    36733607};
    36743608\end{lstlisting}
     
    36773611\subsection{Pointer and array types}
    36783612
    3679 Array 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.
     3613Array 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 ``©a[i]©'' is equivalent to the dereferencing expression ``©(*( a+( i )))©''.
     3614Technically, pointer arithmetic and pointer comparisons other than ``©==©'' and ``©!=©'' are only defined for pointers to array elements, but the type system does not enforce those restrictions.
    36833615Consequently, there is no need for a separate ``array type'' specification.
    36843616
    36853617Pointer 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}@
     3618Like other scalar types, they have ``©+©'' and ``©-©'' operators, but the types do not match the types of the operations in ©arithmetic©, so these operators cannot be consolidated in ©scalar©.
     3619\begin{lstlisting}
     3620trait pointer( type P | scalar( P ) ) {§\impl{pointer}§§\use{scalar}§
    36913621        P ?+?( P, long int ), ?+?( long int, P ), ?-?( P, long int );
    36923622        ptrdiff_t ?-?( P, P );
    36933623};
    3694 trait m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {@\impl{m_l_pointer}@
     3624trait m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {§\impl{m_l_pointer}§
    36953625        P ?+=?( P *, long int ), ?-=?( P *, long int );
    36963626        P ?=?( P *, void * );
     
    37013631Specifications 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.
    37023632Different 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}@
     3633The assertion ``©|ptr_to( Safe_pointer, int )©'' should be read as ``©Safe_pointer© acts like a pointer to ©int©''.
     3634\begin{lstlisting}
     3635trait ptr_to( otype P | pointer( P ), otype T ) {§\impl{ptr_to}§§\use{pointer}§
    37073636        lvalue T *?( P );
    37083637        lvalue T ?[?]( P, long int );
    37093638};
    3710 trait ptr_to_const( otype P | pointer( P ), otype T ) {@\impl{ptr_to_const}@
     3639trait ptr_to_const( otype P | pointer( P ), otype T ) {§\impl{ptr_to_const}§
    37113640        const lvalue T *?( P );
    3712         const lvalue T ?[?]( P, long int );@\use{pointer}@
     3641        const lvalue T ?[?]( P, long int );§\use{pointer}§
    37133642};
    3714 trait ptr_to_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@
     3643trait ptr_to_volatile( otype P | pointer( P ), otype T ) }§\impl{ptr_to_volatile}§
    37153644        volatile lvalue T *?( P );
    3716         volatile lvalue T ?[?]( P, long int );@\use{pointer}@
     3645        volatile lvalue T ?[?]( P, long int );§\use{pointer}§
    37173646};
    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}@
     3647trait ptr_to_const_volatile( otype P | pointer( P ), otype T ) }§\impl{ptr_to_const_volatile}§
     3648        const volatile lvalue T *?( P );§\use{pointer}§
    37203649        const volatile lvalue T ?[?]( P, long int );
    37213650};
    37223651\end{lstlisting}
    37233652
    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 *$''.
    3725 Again, 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}@ {
     3653Assignment 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 ``©T *©'' can be assigned to a ``©const T *©'', a ``©volatile T *©'', and a ``©const volatile T *©''.
     3654Again, the pointed-at type is passed in, so that assertions can connect these specifications to the ``©ptr_to©'' specifications.
     3655\begin{lstlisting}
     3656trait 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}§ {
    37293657        P ?=?( P *, T * );
    37303658        T * ?=?( T **, P );
    37313659};
    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}@) {
     3660trait 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}§) {
    37333661        P ?=?( P *, const T * );
    37343662        const T * ?=?( const T **, P );
    37353663};
    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}@
     3664trait 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}§
    37373665        P ?=?( P *, volatile T * );
    37383666        volatile T * ?=?( volatile T **, P );
    37393667};
    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}@
     3668trait 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}§
     3669                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}§
    37423670        P ?=?( P *, const volatile T * );
    37433671        const volatile T * ?=?( const volatile T **, P );
     
    37483676An 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.
    37493677\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 ) ) {
     3678trait 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 ) ) {
    37513679        MyP ?=?( MyP *, CP );
    37523680        CP ?=?( CP *, MyP );
    37533681};
    37543682\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 *$''.
    3757 This 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.
     3683The assertion ``©| m_l_ptr_like( Safe_ptr, const int * )©'' should be read as ``©Safe_ptr© is a pointer type like ©const int *©''.
     3684This specification has two defects, compared to the original four: there is no automatic assertion that dereferencing a ©MyP© produces an lvalue of the type that ©CP© points at, and the ``©|m_l_pointer( CP )©'' assertion provides only a weak assurance that the argument passed to ©CP© really is a pointer type.
    37603685
    37613686
     
    37633688
    37643689Different operators often have related meanings;
    3765 for instance, in C, ``\lstinline$+$'',
    3766 ``\lstinline$+=$'', and the two versions of ``\lstinline$++$'' perform variations of addition.
     3690for instance, in C, ``©+©'', ``©+=©'', and the two versions of ``©++©'' perform variations of addition.
    37673691Languages 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.
    37683692Completeness and consistency is left to the good taste and discretion of the programmer.
     
    37773701The different comparison operators have obvious relationships, but there is no obvious subset of the operations to use in the implementation of the others.
    37783702However, 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.
     3703the library function ©strcmp© is an example.
     3704
     3705C and \CFA have an extra, non-obvious comparison operator: ``©!©'', logical negation, returns 1 if its operand compares equal to 0, and 0 otherwise.
    37823706\begin{lstlisting}
    37833707trait comparable( otype T ) {
     
    38273751\end{lstlisting}
    38283752
    3829 Note 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$.
     3753Note 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 ©int_base©, ©arith_base© and ©comparable©.
    38313754Note 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!
     3755A truly minimal implementation of an arithmetic type might only provide ©0©, ©1©, and ©?-=?©, which would be used by polymorphic ©?+=?©, ©?*=?©, and ©?/=?© functions.
     3756
     3757Note also that ©short© is an integer type in C11 terms, but has no operations!
    38373758
    38383759
     
    38413762
    38423763Restrict 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.
     3764This gets into ©noalias© territory.
     3765Qualifying anything (``©short restrict rs©'') means pointer parameters of ©?++©, etc, would need restrict qualifiers.
    38453766
    38463767Enumerated types.
     
    38523773Color, enum Color ) really make sense? ?++ does, but it adds (int)1.
    38533774
    3854 Operators on {,signed,unsigned} char and other small types. ?<? harmless;
     3775Operators on {,signed,unsigned} char and other small types. ©?<?© harmless;
    38553776?*? questionable for chars.
    38563777Generic selections make these choices visible.
    3857 Safe conversion operators? Predefined
    3858 ``promotion'' function?
    3859 
    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.
     3778Safe conversion operators? Predefined ``promotion'' function?
     3779
     3780©register© assignment might be handled as assignment to a temporary with copying back and forth, but copying must not be done by assignment.
     3781
     3782Don't use ©ptrdiff_t© by name in the predefineds.
    38633783
    38643784Polymorphic objects.
  • doc/user/user.tex

    rbb8ea30 rd668182  
    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 : Tue May  3 08:05:33 2016
     14%% Update Count     : 246
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
    1717% requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended
     18
     19% inline code ©...© (copyright symbol) emacs: C-q M-)
     20% red highlighting ®...® (registered trademark sumbol) emacs: C-q M-.
     21% latex escape §...§ (section symbol) emacs: C-q M-'
     22% keyword escape ¶...¶ (pilcrow symbol) emacs: C-q M-^
     23% math escape $...$ (dollar symbol)
    1824
    1925\documentclass[openright,twoside]{article}
     
    174180\CC~\cite{c++,ANSI14:C++} is an example of a similar project;
    175181however, it largely extended the language, and did not address existing problems.\footnote{%
    176 Two important existing problems addressed were changing the type of character literals from \lstinline@int@ to \lstinline@char@ and enumerator from \lstinline@int@ to the type of its enumerators.}
     182Two important existing problems addressed were changing the type of character literals from ©int© to ©char© and enumerator from ©int© to the type of its enumerators.}
    177183Fortran~\cite{Fortran08}, Ada~\cite{Ada12}, and Cobol~\cite{Cobol14} are examples of programming languages that took an evolutionary approach, where modern language features are added and problems fixed within the framework of the existing language.
    178184Java~\cite{Java8}, Go~\cite{Go}, Rust~\cite{Rust} and D~\cite{D} are examples of the revolutionary approach for modernizing C/\CC, resulting in a new language rather than an extension of the descendent.
     
    199205
    200206However, it is necessary to differentiate between C and \CFA code because of name overloading, as for \CC.
    201 For example, the C math-library provides the following routines for computing the absolute value of the basic type: \lstinline@abs@, \lstinline@labs@, \lstinline@llabs@, \lstinline@fabs@, \lstinline@fabsf@, \lstinline@fabsl@, \lstinline@cabsf@, \lstinline@cabs@, and \lstinline@cabsl@.
    202 Whereas, \CFA wraps each of these routines into one with the common name \lstinline@abs@.
     207For example, the C math-library provides the following routines for computing the absolute value of the basic type: ©abs©, ©labs©, ©llabs©, ©fabs©, ©fabsf©, ©fabsl©, ©cabsf©, ©cabs©, and ©cabsl©.
     208Whereas, \CFA wraps each of these routines into one with the common name ©abs©.
    203209\begin{lstlisting}
    204210char abs( char );
     
    215221long double _Complex abs( long double _Complex );
    216222\end{lstlisting}
    217 The problem is the name clash between the library routine \lstinline@abs@ and the \CFA names \lstinline@abs@.
    218 Hence, names appearing in an \lstinline@extern "C"@ block have \newterm{C linkage}.
     223The problem is the name clash between the library routine ©abs© and the \CFA names ©abs©.
     224Hence, names appearing in an ©extern "C"© block have \newterm{C linkage}.
    219225Then overloading polymorphism uses a mechanism called \newterm{name mangling} to create unique names that are different from C names, which are not mangled.
    220226Hence, there is the same need as in \CC, to know if a name is a C or \CFA name, so it can be correctly formed.
    221227There is no way around this problem, other than C's approach of creating unique names for each pairing of operation and type.
    222228This example strongly illustrates a core idea in \CFA: \emph{the power of a name}.
    223 The name ``\lstinline@abs@'' evokes the notion of absolute value, and many mathematical types provide the notion of absolute value.
    224 Hence, knowing the name \lstinline@abs@ should be sufficient to apply it to any type where it is applicable.
     229The name ``©abs©'' evokes the notion of absolute value, and many mathematical types provide the notion of absolute value.
     230Hence, knowing the name ©abs© should be sufficient to apply it to any type where it is applicable.
    225231The time savings and safety of using one name uniformly versus $N$ unique names should not be underestimated.
    226232
    227233
    228 \section{Compiling \CFA Program}
    229 
    230 The command \lstinline@cfa@ is used to compile \CFA program(s).
    231 This command works like the GNU \lstinline@gcc@\index{gcc} command, e.g.:
    232 \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$}
    236 By default, \CFA programs having the following \lstinline@gcc@ flags turned on:
     234\section[Compiling CFA Program]{Compiling \CFA Program}
     235
     236The command ©cfa© is used to compile \CFA program(s).
     237This command works like the GNU ©gcc©\index{gcc} command, e.g.:
     238\begin{lstlisting}
     239cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA§-files [ assembler/loader-files ]
     240\end{lstlisting}
     241By default, \CFA programs having the following ©gcc© flags turned on:
    237242\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$}}
     243\item\hspace*{-4pt}\Indexc{-std=gnu99}\index{compilation option!-std=gnu99@{©-std=gnu99©}}
    241244The 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$}}
     245\item\hspace*{-4pt}\Indexc{-fgnu89-¶inline¶}\index{compilation option!-fgnu89-inline@{©-fgnu89-¶inline¶©}}
    245246Use the traditional GNU semantics for inline routines in C99 mode.
    246247\end{description}
    247248The following new \CFA option is available:
    248249\begin{description}
    249 \item
    250 \hspace*{-4pt}\lstinline@-CFA@
    251 \index{-CFA@{\lstinline$-CFA$}}\index{compilation option!-CFA@{\lstinline$-CFA$}}
     250\item\hspace*{-4pt}\Indexc{-CFA}\index{compilation option!-CFA@{©-CFA©}}
    252251Only 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.
    253252\end{description}
     
    255254The following preprocessor variables are available:
    256255\begin{description}
    257 \item
    258 \hspace*{-4pt}\lstinline$__CFA__$
    259 \index{__CFA__@{\lstinline$__CFA__$}}\index{preprocessor variables!__CFA__@{\lstinline$__CFA__$}}
     256\item\hspace*{-4pt}\Indexc{__CFA__}\index{preprocessor variables!__CFA__@{©__CFA__©}}
    260257is always available during preprocessing and its value is the current major \Index{version number} of \CFA.\footnote{
    261258The C preprocessor allows only integer values in a preprocessor variable so a value like ``\Version'' is not allowed.
    262259Hence, the need to have three variables for the major, minor and patch version number.}
    263260
    264 \item
    265 \hspace*{-4pt}\lstinline$__CFA_MINOR__$
    266 \index{__CFA_MINOR__@{\lstinline$__CFA_MINOR__$}}\index{preprocessor variables!__CFA_MINOR__@{\lstinline$__CFA_MINOR__$}}
     261\item\hspace*{-4pt}\Indexc{__CFA_MINOR__}\index{preprocessor variables!__CFA_MINOR__@{©__CFA_MINOR__©}}
    267262is always available during preprocessing and its value is the current minor \Index{version number} of \CFA.
    268263
    269 \item
    270 \hspace*{-4pt}\lstinline$__CFA_PATCH__$
    271 \index{__CFA_PATCH__@%(__CFA_PATCH__%)}\index{preprocessor variables!__CFA_PATCH__@%(__CFA_PATCH__%)}
     264\item\hspace*{-4pt}\Indexc{__CFA_PATCH__}\index{preprocessor variables!__CFA_PATCH__@©__CFA_PATCH__©}
    272265is always available during preprocessing and its value is the current patch \Index{version number} of \CFA.
    273266
    274 \item
    275 \hspace*{-4pt}\lstinline$__CFORALL__$
    276 \index{__CFORALL__@%(__CFORALL__%)}\index{preprocessor variables!__CFORALL__@%(__CFORALL__%)}
     267\item\hspace*{-4pt}\Indexc{__CFORALL__}\index{preprocessor variables!__CFORALL__@©__CFORALL__©}
    277268is always available during preprocessing and it has no value.
    278269\end{description}
     
    282273\begin{lstlisting}
    283274#ifndef __CFORALL__
    284 #include <stdio.h>              // C header file
     275#include <stdio.h>                      // C header file
    285276#else
    286 #include <fstream>              // @\CFA{}@ header file
     277#include <fstream>                      // §\CFA{}§ header file
    287278#endif
    288279\end{lstlisting}
    289 which conditionally includes the correct header file, if the program is compiled using \lstinline@gcc@ or \lstinline@cfa@.
     280which conditionally includes the correct header file, if the program is compiled using ©gcc© or ©cfa©.
    290281
    291282
     
    294285Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, e.g.:
    295286\begin{lstlisting}
    296 2`_`147`_`483`_`648;                            // decimal constant
     2872®_®147®_®483®_®648;                            // decimal constant
    29728856_ul;                                          // decimal unsigned long constant
    2982890_377;                                          // octal constant
     
    308299\begin{enumerate}
    309300\item
    310 A sequence of underscores is disallowed, e.g., \lstinline@12__34@ is invalid.
     301A sequence of underscores is disallowed, e.g., ©12__34© is invalid.
    311302\item
    312303Underscores may only appear within a sequence of digits (regardless of the digit radix).
    313 In other words, an underscore cannot start or end a sequence of digits, e.g., \lstinline@_1@, \lstinline@1_@ and \lstinline@_1_@ are invalid (actually, the 1st and 3rd examples are identifier names).
     304In other words, an underscore cannot start or end a sequence of digits, e.g., ©_1©, ©1_© and ©_1_© are invalid (actually, the 1st and 3rd examples are identifier names).
    314305\item
    315306A numeric prefix may end with an underscore;
    316307a numeric infix may begin and/or end with an underscore;
    317308a numeric suffix may begin with an underscore.
    318 For example, the octal \lstinline@0@ or hexadecimal \lstinline@0x@ prefix may end with an underscore \lstinline@0_377@ or \lstinline@0x_ff@;
    319 the exponent infix \lstinline@E@ may start or end with an underscore \lstinline@1.0_E10@, \lstinline@1.0E_10@ or \lstinline@1.0_E_10@;
    320 the type suffixes \lstinline@U@, \lstinline@L@, etc. may start with an underscore \lstinline@1_U@, \lstinline@1_ll@ or \lstinline@1.0E10_f@.
     309For example, the octal ©0© or hexadecimal ©0x© prefix may end with an underscore ©0_377© or ©0x_ff©;
     310the exponent infix ©E© may start or end with an underscore ©1.0_E10©, ©1.0E_10© or ©1.0_E_10©;
     311the type suffixes ©U©, ©L©, etc. may start with an underscore ©1_U©, ©1_ll© or ©1.0E10_f©.
    321312\end{enumerate}
    322313It is significantly easier to read and enter long constants when they are broken up into smaller groupings (most cultures use comma or period among digits for the same purpose).
     
    353344C and the new \CFA declarations may appear together in the same program block, but cannot be mixed within a specific declaration.
    354345
    355 In \CFA declarations, the same tokens are used as in C: the character \lstinline@*@ is used to indicate a pointer, square brackets \lstinline@[@\,\lstinline@]@ are used to represent an array, and parentheses \lstinline@()@ are used to indicate a routine parameter.
     346In \CFA declarations, the same tokens are used as in C: the character ©*© is used to indicate a pointer, square brackets ©[©\,©]© are used to represent an array, and parentheses ©()© are used to indicate a routine parameter.
    356347However, unlike C, \CFA type declaration tokens are specified from left to right and the entire type specification is distributed across all variables in the declaration list.
    357 For instance, variables \lstinline@x@ and \lstinline@y@ of type pointer to integer are defined in \CFA as follows:
     348For instance, variables ©x© and ©y© of type pointer to integer are defined in \CFA as follows:
    358349\begin{quote2}
    359350\begin{tabular}{@{}l@{\hspace{30pt}}l@{}}
    360351\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{C}}        \\
    361352\begin{lstlisting}
    362 `* int x, y;`
     353®* int x, y;®
    363354\end{lstlisting}
    364355&
     
    407398\end{quote2}
    408399
    409 All type qualifiers, i.e., \lstinline@const@ and \lstinline@volatile@, are used in the normal way with the new declarations but appear left to right, e.g.:
     400All type qualifiers, i.e., ©const© and ©volatile©, are used in the normal way with the new declarations but appear left to right, e.g.:
    410401\begin{quote2}
    411402\begin{tabular}{@{}l@{\hspace{30pt}}l@{\hspace{20pt}}l@{}}
     
    427418\end{tabular}
    428419\end{quote2}
    429 All declaration qualifiers, i.e., \lstinline@extern@, \lstinline@static@, etc., are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier}
     420All declaration qualifiers, i.e., ©extern©, ©static©, etc., are used in the normal way with the new declarations but can only appear at the start of a \CFA routine declaration,\footnote{\label{StorageClassSpecifier}
    430421The placement of a storage-class specifier other than at the beginning of the declaration specifiers in a declaration is an obsolescent feature.~\cite[\S~6.11.5(1)]{C11}} e.g.:
    431422\begin{quote2}
     
    449440\end{quote2}
    450441
    451 Unsupported are K\&R C declarations where the base type defaults to \lstinline@int@, if no type is specified\footnote{
     442Unsupported are K\&R C declarations where the base type defaults to ©int©, if no type is specified\footnote{
    452443At least one type specifier shall be given in the declaration specifiers in each declaration, and in the specifier-qualifier list in each structure declaration and type name~\cite[\S~6.7.2(2)]{C11}},
    453444e.g.:
     
    466457\section{Type Operators}
    467458
    468 The new declaration syntax can be used in other contexts where types are required, e.g., casts and the pseudo-routine \lstinline@sizeof@:
     459The new declaration syntax can be used in other contexts where types are required, e.g., casts and the pseudo-routine ©sizeof©:
    469460\begin{quote2}
    470461\begin{tabular}{@{}l@{\hspace{30pt}}l@{}}
     
    488479The point of the new syntax is to allow returning multiple values from a routine~\cite{CLU,Galletly96}, e.g.:
    489480\begin{lstlisting}
    490 `[ int o1, int o2, char o3 ]` f( int i1, char i2, char i3 ) {
    491         @\emph{routine body}@
    492 }
    493 \end{lstlisting}
    494 where routine \lstinline@f@ has three output (return values) and three input parameters.
     481®[ int o1, int o2, char o3 ]® f( int i1, char i2, char i3 ) {
     482        §\emph{routine body}§
     483}
     484\end{lstlisting}
     485where routine ©f© has three output (return values) and three input parameters.
    495486Existing C syntax cannot be extended with multiple return types because it is impossible to embed a single routine name within multiple return type specifications.
    496487
    497 In detail, the brackets, \lstinline@[]@, enclose the result type, where each return value is named and that name is a local variable of the particular return type.\footnote{
     488In detail, the brackets, ©[]©, enclose the result type, where each return value is named and that name is a local variable of the particular return type.\footnote{
    498489Michael Tiemann, with help from Doug Lea, provided named return values in g++, circa 1989.}
    499490The value of each local return variable is automatically returned at routine termination.
    500491Declaration qualifiers can only appear at the start of a routine definition, e.g.:
    501492\begin{lstlisting}
    502 extern [ int x ] g( int y ) {@\,@}
     493extern [ int x ] g( int y ) {§\,§}
    503494\end{lstlisting}
    504495Lastly, if there are no output parameters or input parameters, the brackets and/or parentheses must still be specified;
    505496in 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:
    506497\begin{lstlisting}
    507 [@\,@] g(@\,@);                         // no input or output parameters
     498[§\,§] g();                                             // no input or output parameters
    508499[ void ] g( void );                     // no input or output parameters
    509500\end{lstlisting}
     
    519510int (*f(x))[ 5 ] int x; {}
    520511\end{lstlisting}
    521 The string ``\lstinline@int (*f(x))[ 5 ]@'' declares a K\&R style routine of type returning a pointer to an array of 5 integers, while the string ``\lstinline@[ 5 ] int x@'' declares a \CFA style parameter x of type array of 5 integers.
    522 Since the strings overlap starting with the open bracket, \lstinline@[@, there is an ambiguous interpretation for the string.
     512The string ``©int (*f(x))[ 5 ]©'' declares a K\&R style routine of type returning a pointer to an array of 5 integers, while the string ``©[ 5 ] int x©'' declares a \CFA style parameter x of type array of 5 integers.
     513Since the strings overlap starting with the open bracket, ©[©, there is an ambiguous interpretation for the string.
    523514As well, \CFA-style declarations cannot be used to declare parameters for C-style routine-definitions because of the following ambiguity:
    524515\begin{lstlisting}
     
    526517int f( int (* foo) );           // foo is redefined as a parameter name
    527518\end{lstlisting}
    528 The string ``\lstinline@int (* foo)@'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo.
    529 The redefinition of a type name in a parameter list is the only context in C where the character \lstinline@*@ can appear to the left of a type name, and \CFA relies on all type modifier characters appearing to the right of the type name.
     519The string ``©int (* foo)©'' declares a C-style named-parameter of type pointer to an integer (the parenthesis are superfluous), while the same string declares a \CFA style unnamed parameter of type routine returning integer with unnamed parameter of type pointer to foo.
     520The redefinition of a type name in a parameter list is the only context in C where the character ©*© can appear to the left of a type name, and \CFA relies on all type modifier characters appearing to the right of the type name.
    530521The inability to use \CFA declarations in these two contexts is probably a blessing because it precludes programmers from arbitrarily switching between declarations forms within a declaration contexts.
    531522
     
    546537\subsection{Returning Values}
    547538
    548 Named return values handle the case where it is necessary to define a local variable whose value is then returned in a \lstinline@return@ statement, as in:
     539Named return values handle the case where it is necessary to define a local variable whose value is then returned in a ©return© statement, as in:
    549540\begin{lstlisting}
    550541int f() {
     
    554545}
    555546\end{lstlisting}
    556 Because 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:
    557 \begin{lstlisting}
    558 `[ int x ]` f() {
     547Because the value in the return variable is automatically returned when a \CFA routine terminates, the ©return© statement \emph{does not} contain an expression, as in:
     548\begin{lstlisting}
     549®[ int x ]® f() {
    559550        ... x = 0; ... x = y; ...
    560         `return;` // implicitly return x
    561 }
    562 \end{lstlisting}
    563 When the return is encountered, the current value of \lstinline@x@ is returned to the calling routine.
    564 As well, ``falling off the end'' of a routine without a \lstinline@return@ statement is permitted, as in:
     551        ®return;® // implicitly return x
     552}
     553\end{lstlisting}
     554When the return is encountered, the current value of ©x© is returned to the calling routine.
     555As well, ``falling off the end'' of a routine without a ©return© statement is permitted, as in:
    565556\begin{lstlisting}
    566557[ int x ] f() {
     
    568559} // implicitly return x
    569560\end{lstlisting}
    570 In this case, the current value of \lstinline@x@ is returned to the calling routine just as if a \lstinline@return@ had been encountered.
     561In this case, the current value of ©x© is returned to the calling routine just as if a ©return© had been encountered.
    571562
    572563
     
    781772\subsection{Type Nesting}
    782773
    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.
     774\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.
    784775\begin{quote2}
    785776\begin{tabular}{@{}l@{\hspace{30pt}}l|l@{}}
     
    836827
    837828int 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;
     829        s.t.c = ®S.®R;  // type qualification
     830        struct ®S.®T t = { ®S.®R, 1, 2 };
     831        enum ®S.®C c;
     832        union ®S.T.®U u;
    842833}
    843834\end{lstlisting}
    844835\end{tabular}
    845836\end{quote2}
    846 In the left example in C, types \lstinline@C@, \lstinline@U@ and \lstinline@T@ are implicitly hoisted outside of type \lstinline@S@ into the containing block scope.
    847 In the right example in \CFA, the types are not hoisted and accessed using the field-selection operator ``\lstinline@.@'' for type qualification, as does Java, rather than the \CC type-selection operator ``\lstinline@::@''.
     837In the left example in C, types ©C©, ©U© and ©T© are implicitly hoisted outside of type ©S© into the containing block scope.
     838In the right example in \CFA, the types are not hoisted and accessed using the field-selection operator ``©.©'' for type qualification, as does Java, rather than the \CC type-selection operator ``©::©''.
    848839
    849840
     
    863854qsort( ia, size );              // sort ascending order using builtin ?<?
    864855{
    865         `int ?<?( int x, int y ) { return x > y; }` // nested routine
     856        ®int ?<?( int x, int y ) { return x > y; }® // nested routine
    866857        qsort( ia, size );      // sort descending order by local redefinition
    867858}
     
    870861Nested routines are not first-class, meaning a nested routine cannot be returned if it has references to variables in its enclosing blocks;
    871862the only exception is references to the external block of the translation unit, as these variables persist for the duration of the program.
    872 The following program in undefined in \CFA (and \lstinline@gcc@\index{gcc})
     863The following program in undefined in \CFA (and ©gcc©\index{gcc})
    873864\begin{lstlisting}
    874865[* [int]( int )] foo() {                // int (*foo())( int )
    875         int `i` = 7;
     866        int ®i® = 7;
    876867        int bar( int p ) {
    877                 `i` += 1;                                       // dependent on local variable
    878                 sout | `i` | endl;
     868                ®i® += 1;                                       // dependent on local variable
     869                sout | ®i® | endl;
    879870        }
    880871        return bar;                                     // undefined because of local dependence
     
    897888The general syntax of a tuple is:
    898889\begin{lstlisting}
    899 [ $\emph{exprlist}$ ]
    900 \end{lstlisting}
    901 where \lstinline@$\emph{exprlist}$@ is a list of one or more expressions separated by commas.
    902 The brackets, \lstinline$[]$, allow differentiating between tuples and expressions containing the C comma operator.
     890[ §\emph{exprlist}§ ]
     891\end{lstlisting}
     892where ©$\emph{exprlist}$© is a list of one or more expressions separated by commas.
     893The brackets, ©[]©, allow differentiating between tuples and expressions containing the C comma operator.
    903894The following are examples of tuples:
    904895\begin{lstlisting}
     
    907898[ v+w, x*y, 3.14159, f() ]
    908899\end{lstlisting}
    909 Tuples are permitted to contain sub-tuples (i.e., nesting), such as \lstinline@[ [ 14, 21 ], 9 ]@, which is a 2-element tuple whose first element is itself a tuple.
     900Tuples are permitted to contain sub-tuples (i.e., nesting), such as ©[ [ 14, 21 ], 9 ]©, which is a 2-element tuple whose first element is itself a tuple.
    910901Note, a tuple is not a record (structure);
    911902a record denotes a single value with substructure, whereas a tuple is multiple values with no substructure (see flattening coercion in Section 12.1).
     
    917908The general syntax of a tuple type is:
    918909\begin{lstlisting}
    919 [ @\emph{typelist}@ ]
    920 \end{lstlisting}
    921 where \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.
     910[ §\emph{typelist}§ ]
     911\end{lstlisting}
     912where ©$\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.
    922913Examples of tuple types include:
    923914\begin{lstlisting}
     
    927918[ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ]
    928919\end{lstlisting}
    929 Like tuples, tuple types may be nested, such as \lstinline@[ [ int, int ], int ]@, which is a 2-element tuple type whose first element is itself a tuple type.
     920Like tuples, tuple types may be nested, such as ©[ [ int, int ], int ]©, which is a 2-element tuple type whose first element is itself a tuple type.
    930921
    931922Examples of declarations using tuple types are:
     
    963954tuple does not have structure like a record; a tuple is simply converted into a list of components.
    964955\begin{rationale}
    965 The present implementation of \CFA does not support nested routine calls when the inner routine returns multiple values; i.e., a statement such as \lstinline@g( f() )@ is not supported.
     956The present implementation of \CFA does not support nested routine calls when the inner routine returns multiple values; i.e., a statement such as ©g( f() )© is not supported.
    966957Using a temporary variable to store the  results of the inner routine and then passing this variable to the outer routine works, however.
    967958\end{rationale}
     
    992983\begin{rationale}
    993984Unfortunately, C's syntax for subscripts precluded treating them as tuples.
    994 The C subscript list has the form \lstinline@[i][j]...@ and not \lstinline@i, j, ...]@.
    995 Therefore, there is no syntactic way for a routine returning multiple values to specify the different subscript values, e.g., \lstinline@f[g()]@ always means a single subscript value because there is only one set of brackets.
    996 Fixing this requires a major change to C because the syntactic form \lstinline@M[i, j, k]@ already has a particular meaning: \lstinline@i, j, k@ is a comma expression.
     985The C subscript list has the form ©[i][j]...© and not ©[i, j, ...]©.
     986Therefore, there is no syntactic way for a routine returning multiple values to specify the different subscript values, e.g., ©f[g()]© always means a single subscript value because there is only one set of brackets.
     987Fixing this requires a major change to C because the syntactic form ©M[i, j, k]© already has a particular meaning: ©i, j, k© is a comma expression.
    997988\end{rationale}
    998989
     
    10131004[ a, b, c, d ] = w
    10141005\end{lstlisting}
    1015 \lstinline@w@ is implicitly opened to yield a tuple of four values, which are then assigned individually.
     1006©w© is implicitly opened to yield a tuple of four values, which are then assigned individually.
    10161007
    10171008A \newterm{flattening coercion} coerces a nested tuple, i.e., a tuple with one or more components, which are themselves tuples, into a flattened tuple, which is a tuple whose components are not tuples, as in:
     
    10211012First the right-hand tuple is flattened and then the values are assigned individually.
    10221013Flattening is also performed on tuple types.
    1023 For example, the type \lstinline@[ int, [ int, int ], int ]@ can be coerced, using flattening, into the type \lstinline@[ int, int, int, int ]@.
     1014For example, the type ©[ int, [ int, int ], int ]© can be coerced, using flattening, into the type ©[ int, int, int, int ]©.
    10241015
    10251016A \newterm{structuring coercion} is the opposite of flattening;
    10261017a tuple is structured into a more complex nested tuple.
    1027 For example, structuring the tuple \lstinline@[ 1, 2, 3, 4 ]@ into the tuple \lstinline@[ 1, [ 2, 3 ], 4 ]@ or the tuple type \lstinline@[ int, int, int, int ]@ into the tuple type \lstinline@[ int, [ int, int ], int ]@.
     1018For example, structuring the tuple ©[ 1, 2, 3, 4 ]© into the tuple ©[ 1, [ 2, 3 ], 4 ]© or the tuple type ©[ int, int, int, int ]© into the tuple type ©[ int, [ int, int ], int ]©.
    10281019In the following example, the last assignment illustrates all the tuple coercions:
    10291020\begin{lstlisting}
     
    10331024\end{lstlisting}
    10341025Starting on the right-hand tuple in the last assignment statement, w is opened, producing a tuple of four values;
    1035 therefore, the right-hand tuple is now the tuple \lstinline@[ [ 1, 2, 3, 4 ], 5 ]@.
    1036 This tuple is then flattened, yielding \lstinline@[ 1, 2, 3, 4, 5 ]@, which is structured into \lstinline@[ 1, [ 2, 3, 4, 5 ] ]@ to match the tuple type of the left-hand side.
    1037 The tuple \lstinline@[ 2, 3, 4, 5 ]@ is then closed to create a tuple value.
    1038 Finally, \lstinline@x@ is assigned \lstinline@1@ and \lstinline@w@ is assigned the tuple value using multiple assignment (see Section 14).
     1026therefore, the right-hand tuple is now the tuple ©[ [ 1, 2, 3, 4 ], 5 ]©.
     1027This tuple is then flattened, yielding ©[ 1, 2, 3, 4, 5 ]©, which is structured into ©[ 1, [ 2, 3, 4, 5 ] ]© to match the tuple type of the left-hand side.
     1028The tuple ©[ 2, 3, 4, 5 ]© is then closed to create a tuple value.
     1029Finally, ©x© is assigned ©1© and ©w© is assigned the tuple value using multiple assignment (see Section 14).
    10391030\begin{rationale}
    10401031A possible additional language extension is to use the structuring coercion for tuples to initialize a complex record with a tuple.
     
    10471038Mass assignment has the following form:
    10481039\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.
    1052 \lstinline@$\emph{expr}$@ is any standard arithmetic expression.
     1040[ §\emph{lvalue}§, ..., §\emph{lvalue}§ ] = §\emph{expr}§;
     1041\end{lstlisting}
     1042The 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.
     1043©$\emph{expr}$© is any standard arithmetic expression.
    10531044Clearly, the types of the entities being assigned must be type compatible with the value of the expression.
    10541045
     
    10761067*a1 = t; *a2 = t; *a3 = t;
    10771068\end{lstlisting}
    1078 The temporary \lstinline@t@ is necessary to store the value of the expression to eliminate conversion issues.
     1069The temporary ©t© is necessary to store the value of the expression to eliminate conversion issues.
    10791070The temporaries for the addresses are needed so that locations on the left-hand side do not change as the values are assigned.
    1080 In this case, \lstinline@y[i]@ uses the previous value of \lstinline@i@ and not the new value set at the beginning of the mass assignment.
     1071In this case, ©y[i]© uses the previous value of ©i© and not the new value set at the beginning of the mass assignment.
    10811072
    10821073
     
    10861077Multiple assignment has the following form:
    10871078\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.
     1079[ §\emph{lvalue}§, . . ., §\emph{lvalue}§ ] = [ §\emph{expr}§, . . ., §\emph{expr}§ ];
     1080\end{lstlisting}
     1081The left-hand side is a tuple of \emph{lvalues}, and the right-hand side is a tuple of \emph{expr}s.
     1082Each \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.
    10921083An example of multiple assignment is:
    10931084\begin{lstlisting}
    10941085[ x, y, z ] = [ 1, 2, 3 ];
    10951086\end{lstlisting}
    1096 Here, the values \lstinline@1@, \lstinline@2@ and \lstinline@3@ are assigned, respectively, to the variables \lstinline@x@, \lstinline@y@ and \lstinline@z@.
     1087Here, the values ©1©, ©2© and ©3© are assigned, respectively, to the variables ©x©, ©y© and ©z©.
    10971088 A more complex example is:
    10981089\begin{lstlisting}
    10991090[ i, y[ i ], z ] = [ 1, i, a + b ];
    11001091\end{lstlisting}
    1101 Here, the values \lstinline@1@, \lstinline@i@ and \lstinline@a + b@ are assigned to the variables \lstinline@i@, \lstinline@y[i]@ and \lstinline@z@, respectively.
     1092Here, the values ©1©, ©i© and ©a + b© are assigned to the variables ©i©, ©y[i]© and ©z©, respectively.
    11021093 Note, the parallel semantics of
    11031094multiple assignment ensures:
     
    11051096[ x, y ] = [ y, x ];
    11061097\end{lstlisting}
    1107 correctly interchanges (swaps) the values stored in \lstinline@x@ and \lstinline@y@.
     1098correctly interchanges (swaps) the values stored in ©x© and ©y©.
    11081099The following cases are errors:
    11091100\begin{lstlisting}
     
    11261117Cascade assignment has the following form:
    11271118\begin{lstlisting}
    1128 @\emph{tuple}@ = @\emph{tuple}@ = ... = @\emph{tuple}@;
     1119§\emph{tuple}§ = §\emph{tuple}§ = ... = §\emph{tuple}§;
    11291120\end{lstlisting}
    11301121and it has the same parallel semantics as for mass and multiple assignment.
     
    11441135Its general form is:
    11451136\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}$@.
     1137§\emph{expr}§ . [ §\emph{fieldlist}§ ]
     1138§\emph{expr}§ -> [ §\emph{fieldlist}§ ]
     1139\end{lstlisting}
     1140\emph{expr} is any expression yielding a value of type record, e.g., ©struct©, ©union©.
     1141Each element of \emph{ fieldlist} is an element of the record specified by \emph{expr}.
    11511142A record-field tuple may be used anywhere a tuple can be used. An example of the use of a record-field tuple is
    11521143the following:
     
    11631154also, it is unnecessary to specify all the fields of a struct in a multiple record-field tuple.
    11641155
    1165 If a field of a \lstinline@struct@ is itself another \lstinline@struct@, multiple fields of this subrecord can be specified using a nested record-field tuple, as in the following example:
     1156If a field of a ©struct© is itself another ©struct©, multiple fields of this subrecord can be specified using a nested record-field tuple, as in the following example:
    11661157\begin{lstlisting}
    11671158struct inner {
     
    11801171\section{Labelled Break/Continue}
    11811172
    1182 While C provides \lstinline@break@ and \lstinline@continue@ statements for altering control flow, both are restricted to one level of nesting for a particular control structure.
    1183 Unfortunately, this restriction forces programmers to use \lstinline@goto@ to achieve the equivalent for more than one level of nesting.
    1184 To prevent having to make this switch, the \lstinline@break@ and \lstinline@continue@ are extended with a target label to support static multi-level exit~\cite{Buhr85,Java}.
    1185 For the labelled \lstinline@break@, it is possible to specify which control structure is the target for exit, as in:
     1173While C provides ©break© and ©continue© statements for altering control flow, both are restricted to one level of nesting for a particular control structure.
     1174Unfortunately, this restriction forces programmers to use ©goto© to achieve the equivalent for more than one level of nesting.
     1175To prevent having to make this switch, the ©break© and ©continue© are extended with a target label to support static multi-level exit~\cite{Buhr85,Java}.
     1176For the labelled ©break©, it is possible to specify which control structure is the target for exit, as in:
    11861177\begin{quote2}
    11871178\begin{tabular}{@{}l@{\hspace{30pt}}l@{}}
    11881179\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{C}}        \\
    11891180\begin{lstlisting}
    1190 `L1:` for ( ... ) {
    1191         `L2:` for ( ... ) {
    1192                 `L3:` for ( ... ) {
    1193                         ... break `L1`; ...
    1194                         ... break `L2`; ...
    1195                         ... break `L3`; // or break
     1181®L1:® for ( ... ) {
     1182        ®L2:® for ( ... ) {
     1183                ®L3:® for ( ... ) {
     1184                        ... break ®L1®; ...
     1185                        ... break ®L2®; ...
     1186                        ... break ®L3®; // or break
    11961187                }
    11971188        }
     
    12131204\end{quote2}
    12141205The inner most loop has three exit points, which cause termination of one or more of the three nested loops, respectively.
    1215 For the labelled \lstinline@continue@, it is possible to specify which control structure is the target for the next loop iteration, as in:
     1206For the labelled ©continue©, it is possible to specify which control structure is the target for the next loop iteration, as in:
    12161207\begin{quote2}
    12171208\begin{tabular}{@{}l@{\hspace{30pt}}l@{}}
    12181209\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}}       & \multicolumn{1}{c}{\textbf{C}}        \\
    12191210\begin{lstlisting}
    1220 `L1`: for ( ... ) {
    1221         `L2`: for ( ... ) {
    1222                 `L3`: for ( ... ) {
    1223                         ... continue `L1`; ...
    1224                         ... continue `L2`; ...
    1225                         ... continue `L3`; ...
     1211®L1®: for ( ... ) {
     1212        ®L2®: for ( ... ) {
     1213                ®L3®: for ( ... ) {
     1214                        ... continue ®L1®; ...
     1215                        ... continue ®L2®; ...
     1216                        ... continue ®L3®; ...
    12261217
    12271218                }
     
    12491240\end{quote2}
    12501241The inner most loop has three restart points, which cause the next loop iteration to begin, respectively.
    1251 For both \lstinline@break@ and \lstinline@continue@, the target label must be directly associated with a \lstinline@for@, \lstinline@while@ or \lstinline@do@ statement;
    1252 for \lstinline@break@, the target label can also be associated with a \lstinline@switch@ statement.
    1253 Both \lstinline@break@ and \lstinline@continue@ with target labels are simply a \lstinline@goto@ restricted in the following ways:
     1242For both ©break© and ©continue©, the target label must be directly associated with a ©for©, ©while© or ©do© statement;
     1243for ©break©, the target label can also be associated with a ©switch© statement.
     1244Both ©break© and ©continue© with target labels are simply a ©goto© restricted in the following ways:
    12541245\begin{itemize}
    12551246\item
     
    12601251Since they always transfers out of containing control structures, they cannot be used to branch into a control structure.
    12611252\end{itemize}
    1262 The advantage of the labelled \lstinline@break@/\lstinline@continue@ is that it allows static multi-level exits without having to use the \lstinline@goto@ statement and ties control flow to the target control structure rather than an arbitrary point in a program.
     1253The advantage of the labelled ©break©/©continue© is that it allows static multi-level exits without having to use the ©goto© statement and ties control flow to the target control structure rather than an arbitrary point in a program.
    12631254Furthermore, the location of the label at the beginning of the target control structure informs the reader that complex control-flow is occurring in the body of the control structure.
    1264 With \lstinline@goto@, the label at the end of the control structure fails to convey this important clue early enough to the reader.
     1255With ©goto©, the label at the end of the control structure fails to convey this important clue early enough to the reader.
    12651256Finally, using an explicit target for the transfer instead of an implicit target allows new nested loop or switch constructs to be added or removed without affecting other constructs.
    1266 The implicit targets of the current \lstinline@break@ and \lstinline@continue@, i.e., the closest enclosing loop or \lstinline@switch@, change as certain constructs are added or removed.
     1257The implicit targets of the current ©break© and ©continue©, i.e., the closest enclosing loop or ©switch©, change as certain constructs are added or removed.
    12671258
    12681259
    12691260\section{Switch Statement}
    12701261
    1271 C allows a number of questionable forms for the \lstinline@switch@ statement:
     1262C allows a number of questionable forms for the ©switch© statement:
    12721263\begin{enumerate}
    12731264\item
    1274 By default, the end of a \lstinline@case@ clause\footnote{
    1275 In this section, the term \emph{case clause} refers to either a \lstinline@case@ or \lstinline@default@ clause.}
    1276 \emph{falls through} to the next \lstinline@case@ clause in the \lstinline@switch@ statement;
    1277 to exit a \lstinline@switch@ statement from a \lstinline@case@ clause requires explicitly terminating the clause with a transfer statement, most commonly \lstinline@break@, as in:
     1265By default, the end of a ©case© clause\footnote{
     1266In this section, the term \emph{case clause} refers to either a ©case© or ©default© clause.}
     1267\emph{falls through} to the next ©case© clause in the ©switch© statement;
     1268to exit a ©switch© statement from a ©case© clause requires explicitly terminating the clause with a transfer statement, most commonly ©break©, as in:
    12781269\begin{lstlisting}
    12791270switch ( i ) {
     
    13001291\end{lstlisting}
    13011292In this example, case 2 is always done if case 3 is done.
    1302 This control flow is difficult to simulate with if statements or a \lstinline@switch@ statement without fall-through as code must be duplicated or placed in a separate routine.
     1293This control flow is difficult to simulate with if statements or a ©switch© statement without fall-through as code must be duplicated or placed in a separate routine.
    13031294C also uses fall-through to handle multiple case-values resulting in the same action, as in:
    13041295\begin{lstlisting}
     
    13131304\end{lstlisting}
    13141305However, this situation is handled in other languages without fall-through by allowing a list of case values.
    1315 While fall-through itself is not a problem, the problem occurs when fall-through is the \lstinline@default@, as this semantics is not intuitive to most programmers and is different from virtually all other programming languages with a \lstinline@switch@ statement.
    1316 Hence, \lstinline@default@ fall-through semantics results in a large number of programming errors as programmers often forget the \lstinline@break@ statement at the end of a \lstinline@case@ clause, resulting in inadvertent fall-through.
    1317 
    1318 \item
    1319 It is possible to place \lstinline@case@ clauses on statements nested \emph{within} the body of the \lstinline@switch@ statement, as in:
     1306While fall-through itself is not a problem, the problem occurs when fall-through is the ©default©, as this semantics is not intuitive to most programmers and is different from virtually all other programming languages with a ©switch© statement.
     1307Hence, ©default© fall-through semantics results in a large number of programming errors as programmers often forget the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through.
     1308
     1309\item
     1310It is possible to place ©case© clauses on statements nested \emph{within} the body of the ©switch© statement, as in:
    13201311\begin{lstlisting}
    13211312switch ( i ) {
     
    13581349}
    13591350\end{lstlisting}
    1360 which unrolls a loop N times (N = 8 above) and uses the \lstinline@switch@ statement to deal with any iterations not a multiple of N.
     1351which unrolls a loop N times (N = 8 above) and uses the ©switch© statement to deal with any iterations not a multiple of N.
    13611352While efficient, this sort of special purpose usage is questionable:
    13621353\begin{quote}
     
    13651356\end{quote}
    13661357\item
    1367 It is possible to place the \lstinline@default@ clause anywhere in the list of labelled clauses for a \lstinline@switch@ statement, rather than only at the end.
    1368 Virtually all programming languages with a \lstinline@switch@ statement require the \lstinline@default@ clause to appear last in the case-clause list.
    1369 The logic for this semantics is that after checking all the \lstinline@case@ clauses without success, the \lstinline@default@ clause is selected;
    1370 hence, physically placing the \lstinline@default@ clause at the end of the \lstinline@case@ clause list matches with this semantics.
    1371 This physical placement can be compared to the physical placement of an \lstinline@else@ clause at the end of a series of connected \lstinline@if@/\lstinline@else@ statements.
    1372 
    1373 \item
    1374 It is possible to place unreachable code at the start of a \lstinline@switch@ statement, as in:
     1358It is possible to place the ©default© clause anywhere in the list of labelled clauses for a ©switch© statement, rather than only at the end.
     1359Virtually all programming languages with a ©switch© statement require the ©default© clause to appear last in the case-clause list.
     1360The logic for this semantics is that after checking all the ©case© clauses without success, the ©default© clause is selected;
     1361hence, physically placing the ©default© clause at the end of the ©case© clause list matches with this semantics.
     1362This physical placement can be compared to the physical placement of an ©else© clause at the end of a series of connected ©if©/©else© statements.
     1363
     1364\item
     1365It is possible to place unreachable code at the start of a ©switch© statement, as in:
    13751366\begin{lstlisting}
    13761367switch ( x ) {
     
    13821373}
    13831374\end{lstlisting}
    1384 While the declaration of the local variable \lstinline@y@ is useful and its scope is across all \lstinline@case@ clauses, the initialization for such a variable is defined to never be executed because control always transfers over it.
    1385 Furthermore, any statements before the first \lstinline@case@ clause can only be executed if labelled and transfered to using a \lstinline@goto@, either from outside or inside of the \lstinline@switch@.
     1375While the declaration of the local variable ©y© is useful and its scope is across all ©case© clauses, the initialization for such a variable is defined to never be executed because control always transfers over it.
     1376Furthermore, any statements before the first ©case© clause can only be executed if labelled and transfered to using a ©goto©, either from outside or inside of the ©switch©.
    13861377As mentioned, transfer into control structures should be forbidden.
    1387 Transfers from within the \lstinline@switch@ body using a \lstinline@goto@ are equally unpalatable.
     1378Transfers from within the ©switch© body using a ©goto© are equally unpalatable.
    13881379\end{enumerate}
    13891380Before discussing potential language changes to deal with these problems, it is worth observing that in a typical C program:
    13901381\begin{itemize}
    13911382\item
    1392 the number of \lstinline@switch@ statements is small,
    1393 \item
    1394 most \lstinline@switch@ statements are well formed (i.e., no Duff's device),
    1395 \item
    1396 the \lstinline@default@ clause is usually written as the last case-clause,
    1397 \item
    1398 and there is only a medium amount of fall-through from one \lstinline@case@ clause to the next, and most of these result from a list of case values executing common code, rather than a sequence of case actions that compound.
     1383the number of ©switch© statements is small,
     1384\item
     1385most ©switch© statements are well formed (i.e., no Duff's device),
     1386\item
     1387the ©default© clause is usually written as the last case-clause,
     1388\item
     1389and there is only a medium amount of fall-through from one ©case© clause to the next, and most of these result from a list of case values executing common code, rather than a sequence of case actions that compound.
    13991390\end{itemize}
    14001391These observations should help to put the effects of suggested changes into perspective.
     
    14021393\begin{enumerate}
    14031394\item
    1404 Eliminating the \lstinline@default@ fall-through problem has the greatest potential for affecting existing code.
    1405 However, even if fall-through is removed, most \lstinline@switch@ statements would continue to work because of the explicit transfers already present at the end of each \lstinline@case@ clause, and the common placement of the \lstinline@default@ clause at the end of the case list.
    1406 In addition, the above grammar provides for the most common use of fall-through, i.e., a list of \lstinline@case@ clauses executing common code, e.g.:
     1395Eliminating the ©default© fall-through problem has the greatest potential for affecting existing code.
     1396However, even if fall-through is removed, most ©switch© statements would continue to work because of the explicit transfers already present at the end of each ©case© clause, and the common placement of the ©default© clause at the end of the case list.
     1397In addition, the above grammar provides for the most common use of fall-through, i.e., a list of ©case© clauses executing common code, e.g.:
    14071398\begin{lstlisting}
    14081399case 1:  case 2:  case 3: ...
    14091400\end{lstlisting}
    14101401Nevertheless, reversing the default action would have a non-trivial effect on case actions that compound, such as the above example of processing shell arguments.
    1411 Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of \lstinline@switch@ statement, called \lstinline@choose@, with no fall-through semantics.
    1412 The \lstinline@choose@ statement is identical to the new \lstinline@switch@ statement, except there is no implicit fall-through between case-clauses and the \lstinline@break@ statement applies to the enclosing loop construct (as for the continue statement in a \lstinline@switch@ statement).
     1402Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called ©choose©, with no fall-through semantics.
     1403The ©choose© statement is identical to the new ©switch© statement, except there is no implicit fall-through between case-clauses and the ©break© statement applies to the enclosing loop construct (as for the continue statement in a ©switch© statement).
    14131404It is still possible to fall-through if a case-clause ends with the new keyword fallthru, e.g.:
    14141405\begin{lstlisting}
     
    14261417\item
    14271418Eliminating Duff's device is straightforward and only invalidates a small amount of very questionable code.
    1428 The solution is to allow \lstinline@case@ clauses to only appear at the same nesting level as the \lstinline@switch@ body, as is done in most other programming languages with \lstinline@switch@ statements.
    1429 \item
    1430 The issue of \lstinline@default@ at locations other than at the end of the cause clause can be solved by using good programming style, and there are a few reasonable situations involving fall-through where the \lstinline@default@ clause may appear is locations other than at the end.
     1419The solution is to allow ©case© clauses to only appear at the same nesting level as the ©switch© body, as is done in most other programming languages with ©switch© statements.
     1420\item
     1421The issue of ©default© at locations other than at the end of the cause clause can be solved by using good programming style, and there are a few reasonable situations involving fall-through where the ©default© clause may appear is locations other than at the end.
    14311422Therefore, no language change is made for this issue.
    14321423\item
    1433 Dealing with unreachable code at the start of a \lstinline@switch@ statement is solved by defining the declaration-list, including any associated initialization, at the start of a \lstinline@switch@ statement body to be executed before the transfer to the appropriate \lstinline@case@ clause.
     1424Dealing with unreachable code at the start of a ©switch© statement is solved by defining the declaration-list, including any associated initialization, at the start of a ©switch© statement body to be executed before the transfer to the appropriate ©case© clause.
    14341425This semantics is the same as for declarations at the start of a loop body, which are executed before each iteration of the loop body.
    1435 As well, this grammar does not allow statements to appear before the first \lstinline@case@ clause.
     1426As well, this grammar does not allow statements to appear before the first ©case© clause.
    14361427The change is compatible for declarations with initialization in this context because existing code cannot assume the initialization has occurred.
    14371428The change is incompatible for statements, but any existing code using it is highly questionable, as in:
     
    14431434}
    14441435\end{lstlisting}
    1445 The statement after the \lstinline@switch@ can never be executed unless it is labelled.
    1446 If it is labelled, it must be transfered to from outside or inside the \lstinline@switch@ statement, neither of which is acceptable control flow.
     1436The statement after the ©switch© can never be executed unless it is labelled.
     1437If it is labelled, it must be transfered to from outside or inside the ©switch© statement, neither of which is acceptable control flow.
    14471438\end{enumerate}
    14481439
     
    14501441\section{Case Clause}
    14511442
    1452 C restricts the \lstinline@case@ clause of a \lstinline@switch@ statement to a single value.
    1453 For multiple \lstinline@case@ clauses associated with the same statement, it is necessary to have multiple \lstinline@case@ clauses rather than multiple values.
    1454 Requiring a \lstinline@case@ clause for each value does not seem to be in the spirit of brevity normally associated with C.
    1455 Therefore, the \lstinline@case@ clause is extended with a list of values, as in:
     1443C restricts the ©case© clause of a ©switch© statement to a single value.
     1444For multiple ©case© clauses associated with the same statement, it is necessary to have multiple ©case© clauses rather than multiple values.
     1445Requiring a ©case© clause for each value does not seem to be in the spirit of brevity normally associated with C.
     1446Therefore, the ©case© clause is extended with a list of values, as in:
    14561447\begin{quote2}
    14571448\begin{tabular}{@{}l@{\hspace{30pt}}l@{\hspace{20pt}}l@{}}
     
    14591450\begin{lstlisting}
    14601451switch ( i ) {
    1461   `case 1, 3, 5`:
     1452  ®case 1, 3, 5®:
    14621453        ...
    1463   `case 2, 4, 6`:
     1454  ®case 2, 4, 6®:
    14641455        ...
    14651456}
     
    14911482\begin{lstlisting}
    14921483switch ( i ) {
    1493   `case 1~5:`
     1484  ®case 1~5:®
    14941485        ...
    1495   `case 10~15:`
     1486  ®case 10~15:®
    14961487        ...
    14971488}
     
    17481739
    17491740The syntax for using references in \CFA is the same as \CC with the exception of reference initialization.
    1750 Use \lstinline@&@ to specify a reference, and access references just like regular objects, not like pointers (use dot notation to access fields).
     1741Use ©&© to specify a reference, and access references just like regular objects, not like pointers (use dot notation to access fields).
    17511742When initializing a reference, \CFA uses a different syntax which differentiates reference initialization from assignment to a reference.
    1752 The \lstinline@&@ is used on both sides of the expression to clarify that the address of the reference is being set to the address of the variable to which it refers.
     1743The ©&© is used on both sides of the expression to clarify that the address of the reference is being set to the address of the variable to which it refers.
    17531744
    17541745\begin{figure}
     
    18231814In \CFA, as in C, all scalar types can be incremented and
    18241815decremented, which is defined in terms of adding or subtracting 1.
    1825 The operations \lstinline@&&@, \lstinline@||@, and \lstinline@!@ can be applied to any scalar arguments and are defined in terms of comparison against 0 (ex. \lstinline@(a && b)@ becomes \lstinline@(a != 0 && b != 0)@).
     1816The operations ©&&©, ©||©, and ©!© can be applied to any scalar arguments and are defined in terms of comparison against 0 (ex. ©(a && b)© becomes ©(a != 0 && b != 0)©).
    18261817
    18271818In C, the integer constants 0 and 1 suffice because the integer promotion rules can convert them to any
     
    18321823polymorphic parameters, and user-defined pointer-like types may need a null value.
    18331824Defining special
    1834 constants for a user-defined type is more efficient than defining a conversion to the type from \lstinline@_Bool@.
     1825constants for a user-defined type is more efficient than defining a conversion to the type from ©_Bool©.
    18351826
    18361827Why just 0 and 1? Why not other integers? No other integers have special status in C.
     
    19151906\begin{tabular}[t]{ll}
    19161907%identifier & operation \\ \hline
    1917 \lstinline@?[?]@ & subscripting \impl{?[?]}\\
    1918 \lstinline@?()@ & function call \impl{?()}\\
    1919 \lstinline@?++@ & postfix increment \impl{?++}\\
    1920 \lstinline@?--@ & postfix decrement \impl{?--}\\
    1921 \lstinline@++?@ & prefix increment \impl{++?}\\
    1922 \lstinline@--?@ & prefix decrement \impl{--?}\\
    1923 \lstinline@*?@ & dereference \impl{*?}\\
    1924 \lstinline@+?@ & unary plus \impl{+?}\\
    1925 \lstinline@-?@ & arithmetic negation \impl{-?}\\
    1926 \lstinline@~?@ & bitwise negation \impl{~?}\\
    1927 \lstinline@!?@ & logical complement \impl{"!?}\\
    1928 \lstinline@?*?@ & multiplication \impl{?*?}\\
    1929 \lstinline@?/?@ & division \impl{?/?}\\
     1908©?[?]© & subscripting \impl{?[?]}\\
     1909©?()© & function call \impl{?()}\\
     1910©?++© & postfix increment \impl{?++}\\
     1911©?--© & postfix decrement \impl{?--}\\
     1912©++?© & prefix increment \impl{++?}\\
     1913©--?© & prefix decrement \impl{--?}\\
     1914©*?© & dereference \impl{*?}\\
     1915©+?© & unary plus \impl{+?}\\
     1916©-?© & arithmetic negation \impl{-?}\\
     1917©~?© & bitwise negation \impl{~?}\\
     1918©!?© & logical complement \impl{"!?}\\
     1919©?*?© & multiplication \impl{?*?}\\
     1920©?/?© & division \impl{?/?}\\
    19301921\end{tabular}\hfil
    19311922\begin{tabular}[t]{ll}
    19321923%identifier & operation \\ \hline
    1933 \lstinline@?%?@ & remainder \impl{?%?}\\
    1934 \lstinline@?+?@ & addition \impl{?+?}\\
    1935 \lstinline@?-?@ & subtraction \impl{?-?}\\
    1936 \lstinline@?<<?@ & left shift \impl{?<<?}\\
    1937 \lstinline@?>>?@ & right shift \impl{?>>?}\\
    1938 \lstinline@?<?@ & less than \impl{?<?}\\
    1939 \lstinline@?<=?@ & less than or equal \impl{?<=?}\\
    1940 \lstinline@?>=?@ & greater than or equal \impl{?>=?}\\
    1941 \lstinline@?>?@ & greater than \impl{?>?}\\
    1942 \lstinline@?==?@ & equality \impl{?==?}\\
    1943 \lstinline@?!=?@ & inequality \impl{?"!=?}\\
    1944 \lstinline@?&?@ & bitwise AND \impl{?&?}\\
     1924©?%?© & remainder \impl{?%?}\\
     1925©?+?© & addition \impl{?+?}\\
     1926©?-?© & subtraction \impl{?-?}\\
     1927©?<<?© & left shift \impl{?<<?}\\
     1928©?>>?© & right shift \impl{?>>?}\\
     1929©?<?© & less than \impl{?<?}\\
     1930©?<=?© & less than or equal \impl{?<=?}\\
     1931©?>=?© & greater than or equal \impl{?>=?}\\
     1932©?>?© & greater than \impl{?>?}\\
     1933©?==?© & equality \impl{?==?}\\
     1934©?!=?© & inequality \impl{?"!=?}\\
     1935©?&?© & bitwise AND \impl{?&?}\\
    19451936\end{tabular}\hfil
    19461937\begin{tabular}[t]{ll}
    19471938%identifier & operation \\ \hline
    1948 \lstinline@?^?@ & exclusive OR \impl{?^?}\\
    1949 \lstinline@?|?@ & inclusive OR \impl{?"|?}\\
    1950 \lstinline@?=?@ & simple assignment \impl{?=?}\\
    1951 \lstinline@?*=?@ & multiplication assignment \impl{?*=?}\\
    1952 \lstinline@?/=?@ & division assignment \impl{?/=?}\\
    1953 \lstinline@?%=?@ & remainder assignment \impl{?%=?}\\
    1954 \lstinline@?+=?@ & addition assignment \impl{?+=?}\\
    1955 \lstinline@?-=?@ & subtraction assignment \impl{?-=?}\\
    1956 \lstinline@?<<=?@ & left-shift assignment \impl{?<<=?}\\
    1957 \lstinline@?>>=?@ & right-shift assignment \impl{?>>=?}\\
    1958 \lstinline@?&=?@ & bitwise AND assignment \impl{?&=?}\\
    1959 \lstinline@?^=?@ & exclusive OR assignment \impl{?^=?}\\
    1960 \lstinline@?|=?@ & inclusive OR assignment \impl{?"|=?}\\
     1939©?^?© & exclusive OR \impl{?^?}\\
     1940©?|?© & inclusive OR \impl{?"|?}\\
     1941©?=?© & simple assignment \impl{?=?}\\
     1942©?*=?© & multiplication assignment \impl{?*=?}\\
     1943©?/=?© & division assignment \impl{?/=?}\\
     1944©?%=?© & remainder assignment \impl{?%=?}\\
     1945©?+=?© & addition assignment \impl{?+=?}\\
     1946©?-=?© & subtraction assignment \impl{?-=?}\\
     1947©?<<=?© & left-shift assignment \impl{?<<=?}\\
     1948©?>>=?© & right-shift assignment \impl{?>>=?}\\
     1949©?&=?© & bitwise AND assignment \impl{?&=?}\\
     1950©?^=?© & exclusive OR assignment \impl{?^=?}\\
     1951©?|=?© & inclusive OR assignment \impl{?"|=?}\\
    19611952\end{tabular}
    19621953\hfil
     
    19671958These identifiers are defined such that the question marks in the name identify the location of the operands.
    19681959These operands represent the parameters to the functions, and define how the operands are mapped to the function call.
    1969 For example, \lstinline@a + b@ becomes \lstinline@?+?(a, b)@.
     1960For example, ©a + b© becomes ©?+?(a, b)©.
    19701961
    19711962In the example below, a new type, myComplex, is defined with an overloaded constructor, + operator, and string operator.
     
    20102001\begin{quote2}
    20112002\begin{tabular}{@{}l@{\hspace{30pt}}ll@{}}
    2012 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CC}}        & \multicolumn{1}{c}{\lstinline@gcc@}\index{gcc} \\
     2003\multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CC}}        & \multicolumn{1}{c}{©gcc©}\index{gcc} \\
    20132004\begin{lstlisting}
    20142005
     
    20412032\end{itemize}
    20422033
    2043 In \CFA, \lstinline@typedef@ provides a mechanism to alias long type names with short ones, both globally and locally, but not eliminate the use of the short name.
    2044 \lstinline@gcc@ provides \lstinline@typeof@ to declare a secondary variable from a primary variable.
     2034In \CFA, ©typedef© provides a mechanism to alias long type names with short ones, both globally and locally, but not eliminate the use of the short name.
     2035©gcc© provides ©typeof© to declare a secondary variable from a primary variable.
    20452036\CFA also relies heavily on the specification of the left-hand side of assignment for type inferencing, so in many cases it is crucial to specify the type of the left-hand side to select the correct type of the right-hand expression.
    20462037Only for overloaded routines with the same return type is variable type-inferencing possible.
    2047 Finally, \lstinline@auto@ presents the programming problem of tracking down a type when the type is actually needed.
     2038Finally, ©auto© presents the programming problem of tracking down a type when the type is actually needed.
    20482039For example, given
    20492040\begin{lstlisting}
    2050 auto j = `...`
    2051 \end{lstlisting}
    2052 and the need to write a routine to compute using \lstinline@j@
    2053 \begin{lstlisting}
    2054 void rtn( `...` parm );
     2041auto j = ®...®
     2042\end{lstlisting}
     2043and the need to write a routine to compute using ©j©
     2044\begin{lstlisting}
     2045void rtn( ®...® parm );
    20552046rtn( j );
    20562047\end{lstlisting}
    2057 A programmer must work backwards to determine the type of \lstinline@j@'s initialization expression, reconstructing the possibly long generic type-name.
     2048A programmer must work backwards to determine the type of ©j©'s initialization expression, reconstructing the possibly long generic type-name.
    20582049In this situation, having the type name or a short alias is very useful.
    20592050
     
    20632054At some point, a programmer wants the type of the variable to remain constant and the expression to be in error when it changes.
    20642055
    2065 Given \lstinline@typedef@ and \lstinline@typeof@ in \CFA, and the strong need to use the type of left-hand side in inferencing, auto type-inferencing is not supported at this time.
     2056Given ©typedef© and ©typeof© in \CFA, and the strong need to use the type of left-hand side in inferencing, auto type-inferencing is not supported at this time.
    20662057Should a significant need arise, this feature can be revisited.
    20672058
     
    23652356} s;
    23662357\end{lstlisting}
    2367 The problem occurs in accesing these fields using the selection operation ``\lstinline@.@'':
     2358The problem occurs in accesing these fields using the selection operation ``©.©'':
    23682359\begin{lstlisting}
    23692360s.0 = 0;        // ambiguity with floating constant .0
     
    23722363To make this work, a space is required after the field selection:
    23732364\begin{lstlisting}
    2374 `s.@\textvisiblespace@0` = 0;
    2375 `s.@\textvisiblespace@1` = 1;
     2365®s.§\textvisiblespace§0® = 0;
     2366®s.§\textvisiblespace§1® = 1;
    23762367\end{lstlisting}
    23772368While 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.
    2379 
    2380 There are several ambiguous cases with operator identifiers, e.g., \lstinline@int *?*?()@, where the string \lstinline@*?*?@ can be lexed as \lstinline@*@/\lstinline@?*?@ or \lstinline@*?@/\lstinline@*?@.
    2381 Since it is common practise to put a unary operator juxtaposed to an identifier, e.g., \lstinline@*i@, users will be annoyed if they cannot do this with respect to operator identifiers.
     2369Like the \CC lexical problem with closing template-syntax, e.g, ©Foo<Bar<int®>>®©, this issue can be solved with a more powerful lexer/parser.
     2370
     2371There are several ambiguous cases with operator identifiers, e.g., ©int *?*?()©, where the string ©*?*?© can be lexed as ©*©/©?*?© or ©*?©/©*?©.
     2372Since it is common practise to put a unary operator juxtaposed to an identifier, e.g., ©*i©, users will be annoyed if they cannot do this with respect to operator identifiers.
    23822373Even with this special hack, there are 5 general cases that cannot be handled.
    2383 The first case is for the function-call identifier \lstinline@?()@:
    2384 \begin{lstlisting}
    2385 int *@\textvisiblespace@?()();  // declaration: space required after '*'
    2386 *@\textvisiblespace@?()();              // expression: space required after '*'
    2387 \end{lstlisting}
    2388 Without the space, the string \lstinline@*?()@ is ambiguous without N character look ahead;
    2389 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument/parameter list.
     2374The first case is for the function-call identifier ©?()©:
     2375\begin{lstlisting}
     2376int *§\textvisiblespace§?()();  // declaration: space required after '*'
     2377*§\textvisiblespace§?()();              // expression: space required after '*'
     2378\end{lstlisting}
     2379Without the space, the string ©*?()© is ambiguous without N character look ahead;
     2380it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument/parameter list.
    23902381
    23912382The 4 remaining cases occur in expressions:
    23922383\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 '?'
    2397 \end{lstlisting}
    2398 In the first two cases, the string \lstinline@i++?@ is ambiguous, where this string can be lexed as \lstinline@i@ / \lstinline@++?@ or \lstinline@i++@ / \lstinline@?@;
    2399 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument list.
    2400 In the second two cases, the string \lstinline@?++x@ is ambiguous, where this string can be lexed as \lstinline@?++@ / \lstinline@x@ or \lstinline@?@ / y\lstinline@++x@;
    2401 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument list.
     2384i++§\textvisiblespace§?i:0;             // space required before '?'
     2385i--§\textvisiblespace§?i:0;             // space required before '?'
     2386i§\textvisiblespace§?++i:0;             // space required after '?'
     2387i§\textvisiblespace§?--i:0;             // space required after '?'
     2388\end{lstlisting}
     2389In the first two cases, the string ©i++?© is ambiguous, where this string can be lexed as ©i© / ©++?© or ©i++© / ©?©;
     2390it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument list.
     2391In the second two cases, the string ©?++x© is ambiguous, where this string can be lexed as ©?++© / ©x© or ©?© / y©++x©;
     2392it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument list.
    24022393
    24032394
     
    33253316
    33263317
    3327 \subsection{Comparing Key Features of \CFA}
     3318\subsection[Comparing Key Features of CFA]{Comparing Key Features of \CFA}
    33283319
    33293320
     
    36993690
    37003691\begin{comment}
    3701 \subsubsection{Modules/Packages}
     3692\subsubsection{Modules / Packages}
    37023693
    37033694\begin{lstlisting}
     
    39413932
    39423933
    3943 \subsubsection{\CC}
     3934\subsubsection[C++]{\CC}
    39443935
    39453936\CC is a general-purpose programming language.
     
    40154006\begin{enumerate}
    40164007\item
    4017 Change type of character literal \lstinline@int@ to \lstinline@char@.
     4008Change type of character literal ©int© to ©char©.
    40184009This change allows overloading differentiation argument type matching, e.g.:
    40194010\begin{lstlisting}
     
    40324023
    40334024\item
    4034 Change: String literals made \lstinline@const@ \\
    4035 The type of a string literal is changed from \lstinline@array of char@ to \lstinline@array of const char@.
    4036 The type of a wide string literal is changed from \lstinline@array of wchar_t@ to \lstinline@array of const wchar_t@. \\
     4025Change: String literals made ©const© \\
     4026The type of a string literal is changed from ©array of char© to ©array of const char©.
     4027The type of a wide string literal is changed from ©array of wchar_t© to ©array of const wchar_t©. \\
    40374028Rationale: This avoids calling an inappropriate overloaded function, which might expect to be able to modify its argument.
    40384029Effect on original feature: Change to semantics of well-defined feature. \\
    4039 Difficulty of converting: Simple syntactic transformation, because string literals can be converted to \lstinline@char*;@ (4.2).
     4030Difficulty of converting: Simple syntactic transformation, because string literals can be converted to ©char*;© (4.2).
    40404031The most common cases are handled by a new but deprecated standard conversion:
    40414032\begin{lstlisting}
     
    40764067
    40774068\CFA is C \emph{incompatible} on this issue, and provides semantics similar to \CC.
    4078 Nested types are not hoisted and can be referenced using the field selection operator ``\lstinline@.@'', unlike the \CC scope-resolution operator ``\lstinline@::@''.
     4069Nested types are not hoisted and can be referenced using the field selection operator ``©.©'', unlike the \CC scope-resolution operator ``©::©''.
    40794070Given 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.
    4080 
    40814071
    40824072\item
     
    40904080struct Y yy; // valid C, invalid C++
    40914081\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:
     4082Rationale: C++ classes have member functions which require that classes establish scopes.
     4083The 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.
     4084Effect on original feature: Change of semantics of welldefined feature.
     4085Difficulty 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:
    41024086\begin{lstlisting}
    41034087struct Y; // struct Y and struct X are at the same scope
     
    41064090};
    41074091\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.
     4092All 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.
     4093Note: this is a consequence of the difference in scope rules, which is documented in 3.3.
    41114094How widely used: Seldom.
    41124095\end{enumerate}
     
    41244107\begin{lstlisting}
    41254108int x = 0, y = 1, z = 2;
    4126 `sout` `|` x `|` y `|` z `| endl`;
     4109®sout® ®|® x ®|® y ®|® z ®| endl®;
    41274110\end{lstlisting}
    41284111&
     
    41334116\end{tabular}
    41344117\end{quote2}
    4135 The \CFA form is half as many characters, and is similar to Python I/O with respect to implicit separators.
     4118The \CFA form is half as many characters, and is similar to \Index{Python} I/O with respect to implicit separators.
    41364119
    41374120The logical-or operator is used because it is the lowest-priority overloadable operator, other than assignment.
     
    41604143A seperator does not appear at the start or end of a line.
    41614144\begin{lstlisting}[belowskip=0pt]
    4162 sout 1 | 2 | 3 | endl;
     4145sout | 1 | 2 | 3 | endl;
    41634146\end{lstlisting}
    41644147\begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    41794162which is a local mechanism to disable insertion of the separator character.
    41804163\item
    4181 A seperator does not appear before a C string starting with the \Index{extended ASCII}\index{ASCII} characters: \lstinline[mathescape=off]@([{$£¥¿«@
     4164A seperator does not appear before a C string starting with the (extended) \Index{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off]@([{$£¥¡¿«@
    41824165%$
    41834166\begin{lstlisting}[mathescape=off]
    4184 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x $" | 4 | "x £" | 5 | "x ¥" | 6 | "x ¿" | 7 | "x «" | 8 | endl;
     4167sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x $" | 4 | "x £" | 5 | "x ¥" | 6 | "x ¡" | 7 | "x ¿" | 8 | "x «" | 9 | endl;
    41854168\end{lstlisting}
    41864169%$
    41874170\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
     4171x (1 x [2 x {3 x $4 x £5 x ¥6 x ¡7 x ¿8 x «9
    41894172\end{lstlisting}
    41904173%$
    41914174\item
    4192 A seperator does not appear after a C string ending with the extended ASCII characters: \lstinline@,.:;!?)]}%¢»@
     4175A seperator does not appear after a C string ending with the (extended) \Index{ASCII}\index{ASCII!extended} characters: ©,.:;!?)]}%¢»©
    41934176\begin{lstlisting}[belowskip=0pt]
    41944177sout | 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;
     4178         | 10 | "% x" | 11 | "¢ x" | 12 | "» x" | endl;
    41964179\end{lstlisting}
    41974180\begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
     
    41994182\end{lstlisting}
    42004183\item
    4201 A seperator does not appear before or after a C string begining/ending with the characters: \lstinline@\f\n\r\t\v\`'"@
     4184A 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@
    42024185\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
     4186sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x" | "x " | 4 | " x" | "x\t" | 1 | "\tx" | endl;
     4187\end{lstlisting}
     4188\begin{lstlisting}[mathescape=off,showspaces=true,showtabs=true,aboveskip=0pt,belowskip=0pt]
     4189x`1`x'2'x"3"x x 4 x x   1       x
    42114190\end{lstlisting}
    42124191\end{enumerate}
     
    42404219\end{lstlisting}
    42414220\begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt]
    4242 1 2 3
     4221 1 2 3
    42434222\end{lstlisting}
    42444223\begin{lstlisting}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt]
     
    42514230\end{lstlisting}
    42524231%$
    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]
     4232\begin{comment}
    42574233#include <fstream>
    42584234
    42594235int 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}
     4236        int x = 3, y = 5, z = 7;
     4237        sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl;
     4238        sout | 1 | 2 | 3 | endl;
     4239        sout | '1' | '2' | '3' | endl;
     4240        sout | 1 | "" | 2 | "" | 3 | endl;
     4241        sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x $" | 4 | "x £" | 5 | "x ¥" | 6 | "x ¡" | 7 | "x ¿" | 8 | "x «" | 9 | endl;
     4242        sout | 1 | ", x" | 2 | ". x" | 3 | ": x" | 4 | "; x" | 5 | "! x" | 6 | "? x" | 7 | ") x" | 8 | "] x" | 9 | "} x"
     4243                 | 10 | "% x" | 11 | "¢ x" | 12 | "» x" | endl;
     4244        sout | "x`" | 1 | "`x'" | 2 | "'x\"" | 3 | "\"x" | "x " | 4 | " x" | "x\t" | 1 | "\tx" | endl;
     4245        sout | sepOn | 1 | 2 | 3 | sepOn | endl;        // separator at start of line
     4246        sout | 1 | sepOff | 2 | 3 | endl;                       // turn off implicit separator temporarily
     4247        sout | sepDisable | 1 | 2 | 3 | endl;           // turn off implicit separation, affects all subsequent prints
     4248        sout | 1 | sepOn | 2 | 3 | endl;                        // turn on implicit separator temporarily
     4249        sout | sepEnable | 1 | 2 | 3 | endl;            // turn on implicit separation, affects all subsequent prints
     4250        sepSet( sout, ", $" );                                          // change separator from " " to ", $"
     4251        sout | 1 | 2 | 3 | endl;
     4252
     4253}
     4254
     4255// Local Variables: //
     4256// tab-width: 4 //
     4257// End: //
     4258\end{comment}
     4259%$
    43224260
    43234261
     
    43314269
    43324270\begin{lstlisting}
    4333 forall( otype T ) T * malloc( void );
     4271forall( otype T ) T * malloc( void );§\indexc{malloc}§
    43344272forall( otype T ) T * malloc( char fill );
    43354273forall( otype T ) T * malloc( T * ptr, size_t size );
    43364274forall( 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 );
     4275forall( otype T ) T * calloc( size_t nmemb );§\indexc{calloc}§
     4276forall( otype T ) T * realloc( T * ptr, size_t size );§\indexc{ato}§
    43394277forall( otype T ) T * realloc( T * ptr, size_t size, unsigned char fill );
    43404278
    4341 forall( otype T ) T * aligned_alloc( size_t alignment );
     4279forall( otype T ) T * aligned_alloc( size_t alignment );§\indexc{ato}§
    43424280forall( otype T ) T * memalign( size_t alignment );             // deprecated
    43434281forall( otype T ) int posix_memalign( T ** ptr, size_t alignment );
     
    43484286
    43494287
    4350 \subsection{ato/strto}
    4351 
    4352 \begin{lstlisting}
    4353 int ato( const char * ptr );
     4288\subsection{ato / strto}
     4289
     4290\begin{lstlisting}
     4291int ato( const char * ptr );§\indexc{ato}§
    43544292unsigned int ato( const char * ptr );
    43554293long int ato( const char * ptr );
     
    43794317
    43804318
    4381 \subsection{bsearch/qsort}
     4319\subsection{bsearch / qsort}
    43824320
    43834321\begin{lstlisting}
    43844322forall( otype T | { int ?<?( T, T ); } )
    4385 T * bsearch( const T key, const T * arr, size_t dimension );
     4323T * bsearch( const T key, const T * arr, size_t dimension );§\indexc{bsearch}§
    43864324
    43874325forall( otype T | { int ?<?( T, T ); } )
    4388 void qsort( const T * arr, size_t dimension );
     4326void qsort( const T * arr, size_t dimension );§\indexc{qsort}§
    43894327\end{lstlisting}
    43904328
     
    43934331
    43944332\begin{lstlisting}
    4395 char abs( char );
    4396 extern "C" {
    4397 int abs( int );                         // use default C routine for int
    4398 } // extern "C"
     4333char abs( char );§\indexc{abs}§
     4334int abs( int );
    43994335long int abs( long int );
    44004336long long int abs( long long int );
     
    44024338double abs( double );
    44034339long 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 );
     4340float abs( float _Complex );
     4341double abs( double _Complex );
     4342long double abs( long double _Complex );
    44244343\end{lstlisting}
    44254344
     
    44284347
    44294348\begin{lstlisting}
    4430 void rand48seed( long int s );
    4431 char rand48();
     4349void rand48seed( long int s );§\indexc{rand48seed}§
     4350char rand48();§\indexc{rand48}§
    44324351int rand48();
    44334352unsigned int rand48();
     
    44424361
    44434362
    4444 \subsection{min/max/swap}
     4363\subsection{min / max / swap}
    44454364
    44464365\begin{lstlisting}
    44474366forall( otype T | { int ?<?( T, T ); } )
    4448 T min( const T t1, const T t2 );
     4367T min( const T t1, const T t2 );§\indexc{min}§
    44494368
    44504369forall( otype T | { int ?>?( T, T ); } )
    4451 T max( const T t1, const T t2 );
     4370T max( const T t1, const T t2 );§\indexc{max}§
    44524371
    44534372forall( otype T )
    4454 void swap( T * t1, T * t2 );
     4373void swap( T * t1, T * t2 );§\indexc{swap}§
     4374\end{lstlisting}
     4375
     4376
     4377\section{Math Library}
     4378\label{s:Math Library}
     4379
     4380The 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.
     4381
     4382
     4383\subsection{General}
     4384
     4385\begin{lstlisting}
     4386float fabs( float );§\indexc{fabs}§
     4387double fabs( double );
     4388long double fabs( long double );
     4389float cabs( float _Complex );
     4390double cabs( double _Complex );
     4391long double cabs( long double _Complex );
     4392
     4393float ?%?( float, float );§\indexc{fmod}§
     4394float fmod( float, float );
     4395double ?%?( double, double );
     4396double fmod( double, double );
     4397long double ?%?( long double, long double );
     4398long double fmod( long double, long double );
     4399
     4400float remainder( float, float );§\indexc{remainder}§
     4401double remainder( double, double );
     4402long double remainder( long double, long double );
     4403
     4404[ int, float ] remquo( float, float );§\indexc{remquo}§
     4405float remquo( float, float, int * );
     4406[ int, double ] remquo( double, double );
     4407double remquo( double, double, int * );
     4408[ int, long double ] remquo( long double, long double );
     4409long double remquo( long double, long double, int * );
     4410
     4411[ int, float ] div( float, float );                                             // alternative name for remquo
     4412float div( float, float, int * );§\indexc{div}§
     4413[ int, double ] div( double, double );
     4414double div( double, double, int * );
     4415[ int, long double ] div( long double, long double );
     4416long double div( long double, long double, int * );
     4417
     4418float fma( float, float, float );§\indexc{fma}§
     4419double fma( double, double, double );
     4420long double fma( long double, long double, long double );
     4421
     4422float fdim( float, float );§\indexc{fdim}§
     4423double fdim( double, double );
     4424long double fdim( long double, long double );
     4425
     4426float nan( const char * );§\indexc{nan}§
     4427double nan( const char * );
     4428long double nan( const char * );
     4429\end{lstlisting}
     4430
     4431
     4432\subsection{Exponential}
     4433
     4434\begin{lstlisting}
     4435float exp( float );§\indexc{exp}§
     4436double exp( double );
     4437long double exp( long double );
     4438float _Complex exp( float _Complex );
     4439double _Complex exp( double _Complex );
     4440long double _Complex exp( long double _Complex );
     4441
     4442float exp2( float );§\indexc{exp2}§
     4443double exp2( double );
     4444long double exp2( long double );
     4445float _Complex exp2( float _Complex );
     4446double _Complex exp2( double _Complex );
     4447long double _Complex exp2( long double _Complex );
     4448
     4449float expm1( float );§\indexc{expm1}§
     4450double expm1( double );
     4451long double expm1( long double );
     4452
     4453float log( float );§\indexc{log}§
     4454double log( double );
     4455long double log( long double );
     4456float _Complex log( float _Complex );
     4457double _Complex log( double _Complex );
     4458long double _Complex log( long double _Complex );
     4459
     4460float log2( float );§\indexc{log2}§
     4461double log2( double );
     4462long double log2( long double );
     4463float _Complex log2( float _Complex );
     4464double _Complex log2( double _Complex );
     4465long double _Complex log2( long double _Complex );
     4466
     4467float log10( float );§\indexc{log10}§
     4468double log10( double );
     4469long double log10( long double );
     4470float _Complex log10( float _Complex );
     4471double _Complex log10( double _Complex );
     4472long double _Complex log10( long double _Complex );
     4473
     4474float log1p( float );§\indexc{log1p}§
     4475double log1p( double );
     4476long double log1p( long double );
     4477
     4478int ilogb( float );§\indexc{ilogb}§
     4479int ilogb( double );
     4480int ilogb( long double );
     4481
     4482float logb( float );§\indexc{logb}§
     4483double logb( double );
     4484long double logb( long double );
     4485\end{lstlisting}
     4486
     4487
     4488\subsection{Power}
     4489
     4490\begin{lstlisting}
     4491float sqrt( float );§\indexc{sqrt}§
     4492double sqrt( double );
     4493long double sqrt( long double );
     4494float _Complex sqrt( float _Complex );
     4495double _Complex sqrt( double _Complex );
     4496long double _Complex sqrt( long double _Complex );
     4497
     4498float cbrt( float );§\indexc{cbrt}§
     4499double cbrt( double );
     4500long double cbrt( long double );
     4501
     4502float hypot( float, float );§\indexc{hypot}§
     4503double hypot( double, double );
     4504long double hypot( long double, long double );
     4505
     4506float pow( float, float );§\indexc{pow}§
     4507double pow( double, double );
     4508long double pow( long double, long double );
     4509float _Complex pow( float _Complex, float _Complex );
     4510double _Complex pow( double _Complex, double _Complex );
     4511long double _Complex pow( long double _Complex, long double _Complex );
     4512\end{lstlisting}
     4513
     4514
     4515\subsection{Trigonometric}
     4516
     4517\begin{lstlisting}
     4518float sin( float );§\indexc{sin}§
     4519double sin( double );
     4520long double sin( long double );
     4521float _Complex sin( float _Complex );
     4522double _Complex sin( double _Complex );
     4523long double _Complex sin( long double _Complex );
     4524
     4525float cos( float );§\indexc{cos}§
     4526double cos( double );
     4527long double cos( long double );
     4528float _Complex cos( float _Complex );
     4529double _Complex cos( double _Complex );
     4530long double _Complex cos( long double _Complex );
     4531
     4532float tan( float );§\indexc{tan}§
     4533double tan( double );
     4534long double tan( long double );
     4535float _Complex tan( float _Complex );
     4536double _Complex tan( double _Complex );
     4537long double _Complex tan( long double _Complex );
     4538
     4539float asin( float );§\indexc{asin}§
     4540double asin( double );
     4541long double asin( long double );
     4542float _Complex asin( float _Complex );
     4543double _Complex asin( double _Complex );
     4544long double _Complex asin( long double _Complex );
     4545
     4546float acos( float );§\indexc{acos}§
     4547double acos( double );
     4548long double acos( long double );
     4549float _Complex acos( float _Complex );
     4550double _Complex acos( double _Complex );
     4551long double _Complex acos( long double _Complex );
     4552
     4553float atan( float );§\indexc{atan}§
     4554double atan( double );
     4555long double atan( long double );
     4556float _Complex atan( float _Complex );
     4557double _Complex atan( double _Complex );
     4558long double _Complex atan( long double _Complex );
     4559
     4560float atan2( float, float );§\indexc{atan2}§
     4561double atan2( double, double );
     4562long double atan2( long double, long double );
     4563
     4564float atan( float, float );                                                             // alternative name for atan2
     4565double atan( double, double );§\indexc{atan}§
     4566long double atan( long double, long double );
     4567\end{lstlisting}
     4568
     4569
     4570\subsection{Hyperbolic}
     4571
     4572\begin{lstlisting}
     4573float sinh( float );§\indexc{sinh}§
     4574double sinh( double );
     4575long double sinh( long double );
     4576float _Complex sinh( float _Complex );
     4577double _Complex sinh( double _Complex );
     4578long double _Complex sinh( long double _Complex );
     4579
     4580float cosh( float );§\indexc{cosh}§
     4581double cosh( double );
     4582long double cosh( long double );
     4583float _Complex cosh( float _Complex );
     4584double _Complex cosh( double _Complex );
     4585long double _Complex cosh( long double _Complex );
     4586
     4587float tanh( float );§\indexc{tanh}§
     4588double tanh( double );
     4589long double tanh( long double );
     4590float _Complex tanh( float _Complex );
     4591double _Complex tanh( double _Complex );
     4592long double _Complex tanh( long double _Complex );
     4593
     4594float asinh( float );§\indexc{asinh}§
     4595double asinh( double );
     4596long double asinh( long double );
     4597float _Complex asinh( float _Complex );
     4598double _Complex asinh( double _Complex );
     4599long double _Complex asinh( long double _Complex );
     4600
     4601float acosh( float );§\indexc{acosh}§
     4602double acosh( double );
     4603long double acosh( long double );
     4604float _Complex acosh( float _Complex );
     4605double _Complex acosh( double _Complex );
     4606long double _Complex acosh( long double _Complex );
     4607
     4608float atanh( float );§\indexc{atanh}§
     4609double atanh( double );
     4610long double atanh( long double );
     4611float _Complex atanh( float _Complex );
     4612double _Complex atanh( double _Complex );
     4613long double _Complex atanh( long double _Complex );
     4614\end{lstlisting}
     4615
     4616
     4617\subsection{Error / Gamma}
     4618
     4619\begin{lstlisting}
     4620float erf( float );§\indexc{erf}§
     4621double erf( double );
     4622long double erf( long double );
     4623float _Complex erf( float _Complex );
     4624double _Complex erf( double _Complex );
     4625long double _Complex erf( long double _Complex );
     4626
     4627float erfc( float );§\indexc{erfc}§
     4628double erfc( double );
     4629long double erfc( long double );
     4630float _Complex erfc( float _Complex );
     4631double _Complex erfc( double _Complex );
     4632long double _Complex erfc( long double _Complex );
     4633
     4634float lgamma( float );§\indexc{lgamma}§
     4635double lgamma( double );
     4636long double lgamma( long double );
     4637float lgamma( float, int * );
     4638double lgamma( double, int * );
     4639long double lgamma( long double, int * );
     4640
     4641float tgamma( float );§\indexc{tgamma}§
     4642double tgamma( double );
     4643long double tgamma( long double );
     4644\end{lstlisting}
     4645
     4646
     4647\subsection{Nearest Integer}
     4648
     4649\begin{lstlisting}
     4650float floor( float );§\indexc{floor}§
     4651double floor( double );
     4652long double floor( long double );
     4653
     4654float ceil( float );§\indexc{ceil}§
     4655double ceil( double );
     4656long double ceil( long double );
     4657
     4658float trunc( float );§\indexc{trunc}§
     4659double trunc( double );
     4660long double trunc( long double );
     4661
     4662float rint( float );§\indexc{rint}§
     4663long double rint( long double );
     4664long int rint( float );
     4665long int rint( double );
     4666long int rint( long double );
     4667long long int rint( float );
     4668long long int rint( double );
     4669long long int rint( long double );
     4670
     4671long int lrint( float );§\indexc{lrint}§
     4672long int lrint( double );
     4673long int lrint( long double );
     4674long long int llrint( float );
     4675long long int llrint( double );
     4676long long int llrint( long double );
     4677
     4678float nearbyint( float );§\indexc{nearbyint}§
     4679double nearbyint( double );
     4680long double nearbyint( long double );
     4681
     4682float round( float );§\indexc{round}§
     4683long double round( long double );
     4684long int round( float );
     4685long int round( double );
     4686long int round( long double );
     4687long long int round( float );
     4688long long int round( double );
     4689long long int round( long double );
     4690
     4691long int lround( float );§\indexc{lround}§
     4692long int lround( double );
     4693long int lround( long double );
     4694long long int llround( float );
     4695long long int llround( double );
     4696long long int llround( long double );
     4697\end{lstlisting}
     4698
     4699
     4700\subsection{Manipulation}
     4701
     4702\begin{lstlisting}
     4703float copysign( float, float );§\indexc{copysign}§
     4704double copysign( double, double );
     4705long double copysign( long double, long double );
     4706
     4707float frexp( float, int * );§\indexc{frexp}§
     4708double frexp( double, int * );
     4709long double frexp( long double, int * );
     4710
     4711float ldexp( float, int );§\indexc{ldexp}§
     4712double ldexp( double, int );
     4713long double ldexp( long double, int );
     4714
     4715[ float, float ] modf( float );§\indexc{modf}§
     4716float modf( float, float * );
     4717[ double, double ] modf( double );
     4718double modf( double, double * );
     4719[ long double, long double ] modf( long double );
     4720long double modf( long double, long double * );
     4721
     4722float nextafter( float, float );§\indexc{nextafter}§
     4723double nextafter( double, double );
     4724long double nextafter( long double, long double );
     4725
     4726float nexttoward( float, long double );§\indexc{nexttoward}§
     4727double nexttoward( double, long double );
     4728long double nexttoward( long double, long double );
     4729
     4730float scalbn( float, int );§\indexc{scalbn}§
     4731double scalbn( double, int );
     4732long double scalbn( long double, int );
     4733
     4734float scalbln( float, long int );§\indexc{scalbln}§
     4735double scalbln( double, long int );
     4736long double scalbln( long double, long int );
    44554737\end{lstlisting}
    44564738
     
    44644746\begin{lstlisting}
    44654747// implementation
    4466 struct Rational {
     4748struct Rational {§\indexc{Rational}§
    44674749        long int numerator, denominator;                                        // invariant: denominator > 0
    44684750}; // Rational
  • src/CodeGen/CodeGenerator.cc

    rbb8ea30 rd668182  
    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 : Fri May 06 16:01:00 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();
     
    7576        //*** Declarations
    7677        void CodeGenerator::visit( FunctionDecl *functionDecl ) {
     78                // generalize this
     79                FunctionDecl::Attribute attr = functionDecl->get_attribute();
     80                switch ( attr.type ) {
     81                        case FunctionDecl::Attribute::Constructor:
     82                                output << "__attribute__ ((constructor";
     83                                if ( attr.priority != FunctionDecl::Attribute::Default ) {
     84                                        output << "(" << attr.priority << ")";
     85                                }
     86                                output << ")) ";
     87                                break;
     88                        case FunctionDecl::Attribute::Destructor:
     89                                output << "__attribute__ ((destructor";
     90                                if ( attr.priority != FunctionDecl::Attribute::Default ) {
     91                                        output << "(" << attr.priority << ")";
     92                                }
     93                                output << ")) ";
     94                                break;
     95                        default:
     96                                break;
     97                }
    7798                handleStorageClass( functionDecl );
    7899                if ( functionDecl->get_isInline() ) {
     
    99120                handleStorageClass( objectDecl );
    100121                output << genType( objectDecl->get_type(), mangleName( objectDecl ) );
    101        
     122
    102123                if ( objectDecl->get_init() ) {
    103124                        output << " = ";
     
    113134                if ( aggDecl->get_name() != "" )
    114135                        output << aggDecl->get_name();
    115        
     136
    116137                std::list< Declaration * > &memb = aggDecl->get_members();
    117138
     
    119140                        output << " {" << endl;
    120141
    121                         cur_indent += CodeGenerator::tabsize; 
     142                        cur_indent += CodeGenerator::tabsize;
    122143                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    123                                 output << indent; 
     144                                output << indent;
    124145                                (*i)->accept( *this );
    125146                                output << ";" << endl;
    126147                        }
    127148
    128                         cur_indent -= CodeGenerator::tabsize; 
     149                        cur_indent -= CodeGenerator::tabsize;
    129150
    130151                        output << indent << "}";
     
    141162                handleAggregate( aggregateDecl );
    142163        }
    143  
     164
    144165        void CodeGenerator::visit( EnumDecl *aggDecl ) {
    145166                output << "enum ";
     
    147168                if ( aggDecl->get_name() != "" )
    148169                        output << aggDecl->get_name();
    149        
     170
    150171                std::list< Declaration* > &memb = aggDecl->get_members();
    151172
     
    153174                        output << " {" << endl;
    154175
    155                         cur_indent += CodeGenerator::tabsize; 
     176                        cur_indent += CodeGenerator::tabsize;
    156177                        for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end();  i++) {
    157178                                ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i );
    158179                                assert( obj );
    159                                 output << indent << mangleName( obj ); 
     180                                output << indent << mangleName( obj );
    160181                                if ( obj->get_init() ) {
    161182                                        output << " = ";
     
    165186                        } // for
    166187
    167                         cur_indent -= CodeGenerator::tabsize; 
     188                        cur_indent -= CodeGenerator::tabsize;
    168189
    169190                        output << indent << "}";
    170191                } // if
    171192        }
    172  
     193
    173194        void CodeGenerator::visit( TraitDecl *aggregateDecl ) {}
    174  
     195
    175196        void CodeGenerator::visit( TypedefDecl *typeDecl ) {
    176197                output << "typedef ";
    177198                output << genType( typeDecl->get_base(), typeDecl->get_name() );
    178199        }
    179  
     200
    180201        void CodeGenerator::visit( TypeDecl *typeDecl ) {
    181202                // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes,
     
    213234                printDesignators( init->get_designators() );
    214235                output << "{ ";
    215                 genCommaList( init->begin_initializers(), init->end_initializers() );
     236                if ( init->begin_initializers() == init->end_initializers() ) {
     237                        // illegal to leave initializer list empty for scalar initializers,
     238                        // but always legal to have 0
     239                        output << "0";
     240                } else {
     241                        genCommaList( init->begin_initializers(), init->end_initializers() );
     242                }
    216243                output << " }";
    217244        }
    218245
    219         void CodeGenerator::visit( Constant *constant ) { 
     246        void CodeGenerator::visit( Constant *constant ) {
    220247                output << constant->get_value() ;
    221248        }
     
    231258                                  case OT_POSTFIXASSIGN:
    232259                                  case OT_INFIXASSIGN:
     260                                  case OT_CTOR:
     261                                  case OT_DTOR:
    233262                                        {
    234263                                                assert( arg != applicationExpr->get_args().end() );
    235264                                                if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) {
    236                
     265                                                        // remove & from first assignment/ctor argument
    237266                                                        *arg = addrExpr->get_arg();
    238267                                                } else {
     268                                                        // no address-of operator, so must be a pointer - add dereference
    239269                                                        UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) );
    240270                                                        newExpr->get_args().push_back( *arg );
     
    243273                                                break;
    244274                                        }
    245              
     275
    246276                                  default:
    247277                                        // do nothing
    248278                                        ;
    249279                                }
    250            
     280
    251281                                switch ( opInfo.type ) {
    252282                                  case OT_INDEX:
     
    257287                                        output << "]";
    258288                                        break;
    259              
     289
    260290                                  case OT_CALL:
    261291                                        // there are no intrinsic definitions of the function call operator
    262292                                        assert( false );
    263293                                        break;
    264              
     294
     295                                  case OT_CTOR:
     296                                  case OT_DTOR:
     297                                        if ( applicationExpr->get_args().size() == 1 ) {
     298                                                // the expression fed into a single parameter constructor or destructor
     299                                                // may contain side effects - output as a void expression
     300                                                output << "((void)(";
     301                                                (*arg++)->accept( *this );
     302                                                output << ")) /* " << opInfo.inputName << " */";
     303                                        } else if ( applicationExpr->get_args().size() == 2 ) {
     304                                                // intrinsic two parameter constructors are essentially bitwise assignment
     305                                                output << "(";
     306                                                (*arg++)->accept( *this );
     307                                                output << opInfo.symbol;
     308                                                (*arg)->accept( *this );
     309                                                output << ") /* " << opInfo.inputName << " */";
     310                                        } else {
     311                                                // no constructors with 0 or more than 2 parameters
     312                                                assert( false );
     313                                        }
     314                                        break;
     315
    265316                                  case OT_PREFIX:
    266317                                  case OT_PREFIXASSIGN:
     
    271322                                        output << ")";
    272323                                        break;
    273              
     324
    274325                                  case OT_POSTFIX:
    275326                                  case OT_POSTFIXASSIGN:
     
    278329                                        output << opInfo.symbol;
    279330                                        break;
     331
    280332
    281333                                  case OT_INFIX:
     
    288340                                        output << ")";
    289341                                        break;
    290              
     342
    291343                                  case OT_CONSTANT:
    292344                                  case OT_LABELADDRESS:
     
    307359                } // if
    308360        }
    309  
     361
    310362        void CodeGenerator::visit( UntypedExpr *untypedExpr ) {
    311363                if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) {
     
    321373                                        output << "]";
    322374                                        break;
    323              
     375
    324376                                  case OT_CALL:
    325377                                        assert( false );
    326                                         break;
    327              
     378
     379
     380                                  case OT_CTOR:
     381                                  case OT_DTOR:
     382                                        if ( untypedExpr->get_args().size() == 1 ) {
     383                                                // the expression fed into a single parameter constructor or destructor
     384                                                // may contain side effects - output as a void expression
     385                                                output << "((void)(";
     386                                                (*arg++)->accept( *this );
     387                                                output << ")) /* " << opInfo.inputName << " */";
     388                                        } else if ( untypedExpr->get_args().size() == 2 ) {
     389                                                // intrinsic two parameter constructors are essentially bitwise assignment
     390                                                output << "(";
     391                                                (*arg++)->accept( *this );
     392                                                output << opInfo.symbol;
     393                                                (*arg)->accept( *this );
     394                                                output << ") /* " << opInfo.inputName << " */";
     395                                        } else {
     396                                                // no constructors with 0 or more than 2 parameters
     397                                                assert( false );
     398                                        }
     399                                        break;
     400
    328401                                  case OT_PREFIX:
    329402                                  case OT_PREFIXASSIGN:
     
    335408                                        output << ")";
    336409                                        break;
    337              
     410
    338411                                  case OT_POSTFIX:
    339412                                  case OT_POSTFIXASSIGN:
     
    342415                                        output << opInfo.symbol;
    343416                                        break;
    344  
     417
    345418                                  case OT_INFIX:
    346419                                  case OT_INFIXASSIGN:
     
    352425                                        output << ")";
    353426                                        break;
    354                                        
     427
    355428                                  case OT_CONSTANT:
    356429                                        // there are no intrinsic definitions of 0 or 1 as functions
     
    370443                } // if
    371444        }
    372  
     445
    373446        void CodeGenerator::visit( NameExpr *nameExpr ) {
    374447                OperatorInfo opInfo;
     
    380453                } // if
    381454        }
    382  
     455
    383456        void CodeGenerator::visit( AddressExpr *addressExpr ) {
    384457                output << "(&";
     
    409482                output << ")";
    410483        }
    411  
     484
    412485        void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) {
    413486                assert( false );
    414487        }
    415  
     488
    416489        void CodeGenerator::visit( MemberExpr *memberExpr ) {
    417490                memberExpr->get_aggregate()->accept( *this );
    418491                output << "." << mangleName( memberExpr->get_member() );
    419492        }
    420  
     493
    421494        void CodeGenerator::visit( VariableExpr *variableExpr ) {
    422495                OperatorInfo opInfo;
     
    427500                } // if
    428501        }
    429  
     502
    430503        void CodeGenerator::visit( ConstantExpr *constantExpr ) {
    431504                assert( constantExpr->get_constant() );
    432505                constantExpr->get_constant()->accept( *this );
    433506        }
    434  
     507
    435508        void CodeGenerator::visit( SizeofExpr *sizeofExpr ) {
    436509                output << "sizeof(";
     
    469542                assert( false && "OffsetPackExpr should not reach code generation" );
    470543        }
    471  
     544
    472545        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
    473546                output << "(";
     
    481554                output << ")";
    482555        }
    483  
     556
    484557        void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) {
    485558                output << "(";
     
    491564                output << ")";
    492565        }
    493  
     566
    494567        void CodeGenerator::visit( CommaExpr *commaExpr ) {
    495568                output << "(";
     
    499572                output << ")";
    500573        }
    501  
     574
    502575        void CodeGenerator::visit( TupleExpr *tupleExpr ) {}
    503  
     576
    504577        void CodeGenerator::visit( TypeExpr *typeExpr ) {}
    505578
     
    532605                        }
    533606                }
    534                 cur_indent -= CodeGenerator::tabsize; 
     607                cur_indent -= CodeGenerator::tabsize;
    535608
    536609                output << indent << "}";
     
    538611
    539612        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, 
     613                // I don't see why this check is necessary.
     614                // If this starts to cause problems then put it back in,
    542615                // with an explanation
    543616                assert( exprStmt );
     
    589662                switchStmt->get_condition()->accept( *this );
    590663                output << " ) ";
    591                
     664
    592665                output << "{" << std::endl;
    593666                cur_indent += CodeGenerator::tabsize;
     
    609682                } // if
    610683                output << ":\n";
    611                
     684
    612685                std::list<Statement *> sts = caseStmt->get_statements();
    613686
     
    626699                        if ( ! branchStmt->get_target().empty() )
    627700                                output << "goto " << branchStmt->get_target();
    628                         else { 
     701                        else {
    629702                                if ( branchStmt->get_computedTarget() != 0 ) {
    630703                                        output << "goto *";
     
    677750
    678751        void CodeGenerator::visit( ForStmt *forStmt ) {
    679                 // initialization is always hoisted, so don't 
    680                 // bother doing anything with that 
     752                // initialization is always hoisted, so don't
     753                // bother doing anything with that
    681754                output << "for (;";
    682755
     
    702775        void CodeGenerator::visit( DeclStmt *declStmt ) {
    703776                declStmt->get_decl()->accept( *this );
    704        
     777
    705778                if ( doSemicolon( declStmt->get_decl() ) ) {
    706779                        output << ";";
  • src/CodeGen/FixNames.cc

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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
    501                         addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ),
     501                        addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from_ulong( n_members ) ) ),
    502502                                                                              derefVar( sizeParam ) ) );
    503503                        ++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
     
    20662069                                if ( n_members == 0 ) {
    20672070                                        // all empty structs have the same layout - size 1, align 1
    2068                                         makeVar( sizeofName( typeName ), layoutType, new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
    2069                                         makeVar( alignofName( typeName ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from( (unsigned long)1 ) ) ) );
     2071                                        makeVar( sizeofName( typeName ), layoutType, new SingleInit( new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
     2072                                        makeVar( alignofName( typeName ), layoutType->clone(), new SingleInit( new ConstantExpr( Constant::from_ulong( 1 ) ) ) );
    20702073                                        // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array
    20712074                                } else {
    20722075                                        ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType );
    20732076                                        ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() );
    2074                                         ObjectDecl *offsetVar = makeVar( offsetofName( typeName ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from( n_members ) ), false, false ) );
     2077                                        ObjectDecl *offsetVar = makeVar( offsetofName( typeName ), new ArrayType( Type::Qualifiers(), layoutType->clone(), new ConstantExpr( Constant::from_int( n_members ) ), false, false ) );
    20752078
    20762079                                        // generate call to layout function
     
    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
     
    21912194
    21922195                                        // build the offset array and replace the pack with a reference to it
    2193                                         ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from( baseMembers.size() ) ), false, false ),
     2196                                        ObjectDecl *offsetArray = makeVar( offsetName, new ArrayType( Type::Qualifiers(), offsetType, new ConstantExpr( Constant::from_ulong( baseMembers.size() ) ), false, false ),
    21942197                                                        new ListInit( inits ) );
    21952198                                        ret = new VariableExpr( offsetArray );
  • src/GenPoly/CopyParams.cc

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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 : Fri May 13 11:36:24 2016
     14## Update Count     : 3
    1515###############################################################################
    1616
    17 SRC += InitTweak/RemoveInit.cc
     17SRC += InitTweak/GenInit.cc \
     18        InitTweak/FixInit.cc \
     19        InitTweak/FixGlobalInit.cc \
     20        InitTweak/InitTweak.cc
    1821
  • src/MakeLibCfa.cc

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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) \
     127        InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT) \
     128        InitTweak/driver_cfa_cpp-InitTweak.$(OBJEXT) \
    126129        Parser/driver_cfa_cpp-parser.$(OBJEXT) \
    127130        Parser/driver_cfa_cpp-lex.$(OBJEXT) \
     
    159162        SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT) \
    160163        SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT) \
     164        SymTab/driver_cfa_cpp-Autogen.$(OBJEXT) \
    161165        SynTree/driver_cfa_cpp-Type.$(OBJEXT) \
    162166        SynTree/driver_cfa_cpp-VoidType.$(OBJEXT) \
     
    345349        GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
    346350        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 \
     351        GenPoly/DeclMutator.cc InitTweak/GenInit.cc \
     352        InitTweak/FixInit.cc InitTweak/FixGlobalInit.cc \
     353        InitTweak/InitTweak.cc Parser/parser.yy Parser/lex.ll \
     354        Parser/TypedefTable.cc Parser/ParseNode.cc \
     355        Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
     356        Parser/StatementNode.cc Parser/InitializerNode.cc \
     357        Parser/TypeData.cc Parser/LinkageSpec.cc \
     358        Parser/parseutility.cc Parser/Parser.cc \
    353359        ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \
    354360        ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \
     
    362368        SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \
    363369        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 \
     370        SymTab/Autogen.cc SynTree/Type.cc SynTree/VoidType.cc \
     371        SynTree/BasicType.cc SynTree/PointerType.cc \
     372        SynTree/ArrayType.cc SynTree/FunctionType.cc \
     373        SynTree/ReferenceToType.cc SynTree/TupleType.cc \
     374        SynTree/TypeofType.cc SynTree/AttrType.cc \
    368375        SynTree/VarArgsType.cc SynTree/Constant.cc \
    369376        SynTree/Expression.cc SynTree/TupleExpr.cc \
     
    561568        @$(MKDIR_P) InitTweak/$(DEPDIR)
    562569        @: > InitTweak/$(DEPDIR)/$(am__dirstamp)
    563 InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT):  \
     570InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
     571        InitTweak/$(DEPDIR)/$(am__dirstamp)
     572InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT): InitTweak/$(am__dirstamp) \
     573        InitTweak/$(DEPDIR)/$(am__dirstamp)
     574InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT):  \
     575        InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)
     576InitTweak/driver_cfa_cpp-InitTweak.$(OBJEXT):  \
    564577        InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp)
    565578Parser/parser.h: Parser/parser.cc
     
    670683SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT): SymTab/$(am__dirstamp) \
    671684        SymTab/$(DEPDIR)/$(am__dirstamp)
     685SymTab/driver_cfa_cpp-Autogen.$(OBJEXT): SymTab/$(am__dirstamp) \
     686        SymTab/$(DEPDIR)/$(am__dirstamp)
    672687SynTree/$(am__dirstamp):
    673688        @$(MKDIR_P) SynTree
     
    792807        -rm -f GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT)
    793808        -rm -f GenPoly/driver_cfa_cpp-Specialize.$(OBJEXT)
    794         -rm -f InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT)
     809        -rm -f InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT)
     810        -rm -f InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT)
     811        -rm -f InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT)
     812        -rm -f InitTweak/driver_cfa_cpp-InitTweak.$(OBJEXT)
    795813        -rm -f Parser/driver_cfa_cpp-DeclarationNode.$(OBJEXT)
    796814        -rm -f Parser/driver_cfa_cpp-ExpressionNode.$(OBJEXT)
     
    822840        -rm -f ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT)
    823841        -rm -f ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT)
     842        -rm -f SymTab/driver_cfa_cpp-Autogen.$(OBJEXT)
    824843        -rm -f SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT)
    825844        -rm -f SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT)
     
    897916@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@
    898917@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@
     918@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Po@am__quote@
     919@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po@am__quote@
     920@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po@am__quote@
     921@AMDEP_TRUE@@am__include@ @am__quote@InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Po@am__quote@
    900922@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po@am__quote@
    901923@AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Po@am__quote@
     
    927949@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Po@am__quote@
    928950@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po@am__quote@
     951@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po@am__quote@
    929952@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po@am__quote@
    930953@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po@am__quote@
     
    13661389@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`
    13671390
    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`
     1391InitTweak/driver_cfa_cpp-GenInit.o: InitTweak/GenInit.cc
     1392@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
     1393@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po
     1394@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/GenInit.cc' object='InitTweak/driver_cfa_cpp-GenInit.o' libtool=no @AMDEPBACKSLASH@
     1395@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1396@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
     1397
     1398InitTweak/driver_cfa_cpp-GenInit.obj: InitTweak/GenInit.cc
     1399@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`
     1400@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-GenInit.Po
     1401@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/GenInit.cc' object='InitTweak/driver_cfa_cpp-GenInit.obj' libtool=no @AMDEPBACKSLASH@
     1402@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1403@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`
     1404
     1405InitTweak/driver_cfa_cpp-FixInit.o: InitTweak/FixInit.cc
     1406@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
     1407@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po
     1408@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.o' libtool=no @AMDEPBACKSLASH@
     1409@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1410@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
     1411
     1412InitTweak/driver_cfa_cpp-FixInit.obj: InitTweak/FixInit.cc
     1413@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`
     1414@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixInit.Po
     1415@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/FixInit.cc' object='InitTweak/driver_cfa_cpp-FixInit.obj' libtool=no @AMDEPBACKSLASH@
     1416@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1417@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`
     1418
     1419InitTweak/driver_cfa_cpp-FixGlobalInit.o: InitTweak/FixGlobalInit.cc
     1420@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixGlobalInit.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.o `test -f 'InitTweak/FixGlobalInit.cc' || echo '$(srcdir)/'`InitTweak/FixGlobalInit.cc
     1421@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Po
     1422@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/FixGlobalInit.cc' object='InitTweak/driver_cfa_cpp-FixGlobalInit.o' libtool=no @AMDEPBACKSLASH@
     1423@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1424@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.o `test -f 'InitTweak/FixGlobalInit.cc' || echo '$(srcdir)/'`InitTweak/FixGlobalInit.cc
     1425
     1426InitTweak/driver_cfa_cpp-FixGlobalInit.obj: InitTweak/FixGlobalInit.cc
     1427@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-FixGlobalInit.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.obj `if test -f 'InitTweak/FixGlobalInit.cc'; then $(CYGPATH_W) 'InitTweak/FixGlobalInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixGlobalInit.cc'; fi`
     1428@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-FixGlobalInit.Po
     1429@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/FixGlobalInit.cc' object='InitTweak/driver_cfa_cpp-FixGlobalInit.obj' libtool=no @AMDEPBACKSLASH@
     1430@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1431@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-FixGlobalInit.obj `if test -f 'InitTweak/FixGlobalInit.cc'; then $(CYGPATH_W) 'InitTweak/FixGlobalInit.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/FixGlobalInit.cc'; fi`
     1432
     1433InitTweak/driver_cfa_cpp-InitTweak.o: InitTweak/InitTweak.cc
     1434@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-InitTweak.o -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo -c -o InitTweak/driver_cfa_cpp-InitTweak.o `test -f 'InitTweak/InitTweak.cc' || echo '$(srcdir)/'`InitTweak/InitTweak.cc
     1435@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Po
     1436@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/InitTweak.cc' object='InitTweak/driver_cfa_cpp-InitTweak.o' libtool=no @AMDEPBACKSLASH@
     1437@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1438@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-InitTweak.o `test -f 'InitTweak/InitTweak.cc' || echo '$(srcdir)/'`InitTweak/InitTweak.cc
     1439
     1440InitTweak/driver_cfa_cpp-InitTweak.obj: InitTweak/InitTweak.cc
     1441@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT InitTweak/driver_cfa_cpp-InitTweak.obj -MD -MP -MF InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo -c -o InitTweak/driver_cfa_cpp-InitTweak.obj `if test -f 'InitTweak/InitTweak.cc'; then $(CYGPATH_W) 'InitTweak/InitTweak.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/InitTweak.cc'; fi`
     1442@am__fastdepCXX_TRUE@   $(am__mv) InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Tpo InitTweak/$(DEPDIR)/driver_cfa_cpp-InitTweak.Po
     1443@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='InitTweak/InitTweak.cc' object='InitTweak/driver_cfa_cpp-InitTweak.obj' libtool=no @AMDEPBACKSLASH@
     1444@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1445@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o InitTweak/driver_cfa_cpp-InitTweak.obj `if test -f 'InitTweak/InitTweak.cc'; then $(CYGPATH_W) 'InitTweak/InitTweak.cc'; else $(CYGPATH_W) '$(srcdir)/InitTweak/InitTweak.cc'; fi`
    13811446
    13821447Parser/driver_cfa_cpp-parser.o: Parser/parser.cc
     
    18691934@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    18701935@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`
     1936
     1937SymTab/driver_cfa_cpp-Autogen.o: SymTab/Autogen.cc
     1938@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
     1939@am__fastdepCXX_TRUE@   $(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po
     1940@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='SymTab/Autogen.cc' object='SymTab/driver_cfa_cpp-Autogen.o' libtool=no @AMDEPBACKSLASH@
     1941@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1942@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
     1943
     1944SymTab/driver_cfa_cpp-Autogen.obj: SymTab/Autogen.cc
     1945@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`
     1946@am__fastdepCXX_TRUE@   $(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-Autogen.Po
     1947@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='SymTab/Autogen.cc' object='SymTab/driver_cfa_cpp-Autogen.obj' libtool=no @AMDEPBACKSLASH@
     1948@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1949@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`
    18711950
    18721951SynTree/driver_cfa_cpp-Type.o: SynTree/Type.cc
  • src/Parser/DeclarationNode.cc

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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 : Fri May 13 11:36:40 2016
     13// Update Count     : 203
    1414//
    1515
     
    2525#include "SymTab/Indexer.h"
    2626#include "Common/utility.h"
     27#include "InitTweak/InitTweak.h"
    2728
    2829#include <iostream>
     
    3334          public:
    3435                Resolver() : SymTab::Indexer( false ), switchType( 0 ) {}
    35  
     36
    3637                virtual void visit( FunctionDecl *functionDecl );
    3738                virtual void visit( ObjectDecl *functionDecl );
     
    5455                virtual void visit( SingleInit *singleInit );
    5556                virtual void visit( ListInit *listInit );
     57                virtual void visit( ConstructorInit *ctorInit );
    5658          private:
    5759        typedef std::list< Initializer * >::iterator InitIterator;
     
    5961          void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & );
    6062          void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & );
    61 
     63          void fallbackInit( ConstructorInit * ctorInit );
    6264                std::list< Type * > functionReturn;
    6365                Type *initContext;
     
    8284        }
    8385
     86
    8487        namespace {
    8588                void finishExpr( Expression *expr, const TypeEnvironment &env ) {
     
    8790                        env.makeSubstitution( *expr->get_env() );
    8891                }
    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  
     92        } // namespace
     93
     94        Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
     95                global_renamer.reset();
     96                TypeEnvironment env;
     97                Expression *newExpr = resolveInVoidContext( untyped, indexer, env );
     98                finishExpr( newExpr, env );
     99                return newExpr;
     100        }
     101
     102        namespace {
    98103                Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    99104                        TypeEnvironment env;
     
    126131                        } // if
    127132                }
    128  
     133
    129134                Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) {
    130135                        TypeEnvironment env;
     
    159164                        return newExpr;
    160165                }
    161  
    162         }
    163  
     166
     167        }
     168
    164169        void Resolver::visit( ObjectDecl *objectDecl ) {
    165170                Type *new_type = resolveTypeof( objectDecl->get_type(), *this );
     
    258263                        forStmt->set_condition( newExpr );
    259264                } // if
    260                
     265
    261266                if ( forStmt->get_increment() ) {
    262267                        Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this );
     
    272277                delete switchStmt->get_condition();
    273278                switchStmt->set_condition( newExpr );
    274  
     279
    275280                visitor.Visitor::visit( switchStmt );
    276281        }
     
    314319        bool isCharType( T t ) {
    315320                if ( BasicType * bt = dynamic_cast< BasicType * >( t ) ) {
    316                         return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar || 
     321                        return bt->get_kind() == BasicType::Char || bt->get_kind() == BasicType::SignedChar ||
    317322                                bt->get_kind() == BasicType::UnsignedChar;
    318323                }
     
    326331                                string n = ne->get_name();
    327332                                if (n == "0") {
    328                                         initContext = new BasicType(Type::Qualifiers(), 
     333                                        initContext = new BasicType(Type::Qualifiers(),
    329334                                                                                                BasicType::SignedInt);
    330335                                } else {
     
    332337                                        initContext = decl->get_type();
    333338                                }
    334                         } else if (ConstantExpr * e = 
     339                        } else if (ConstantExpr * e =
    335340                                           dynamic_cast<ConstantExpr*>(singleInit->get_value())) {
    336341                                Constant *c = e->get_constant();
     
    355360                                                        singleInit->set_value( ce->get_arg() );
    356361                                                        ce->set_arg( NULL );
    357                                                         delete ce;                                                                     
     362                                                        delete ce;
    358363                                                }
    359364                                        }
     
    471476#endif
    472477        }
     478
     479        // ConstructorInit - fall back on C-style initializer
     480        void Resolver::fallbackInit( ConstructorInit * ctorInit ) {
     481                // could not find valid constructor, or found an intrinsic constructor
     482                // fall back on C-style initializer
     483                delete ctorInit->get_ctor();
     484                ctorInit->set_ctor( NULL );
     485                maybeAccept( ctorInit->get_init(), *this );
     486        }
     487
     488        void Resolver::visit( ConstructorInit *ctorInit ) {
     489                try {
     490                        maybeAccept( ctorInit->get_ctor(), *this );
     491                        maybeAccept( ctorInit->get_dtor(), *this );
     492                } catch ( SemanticError ) {
     493                        // no alternatives for the constructor initializer - fallback on C-style initializer
     494                        // xxx- not sure if this makes a ton of sense - should maybe never be able to have this situation?
     495                        fallbackInit( ctorInit );
     496                        return;
     497                }
     498
     499                // found a constructor - can get rid of C-style initializer
     500                delete ctorInit->get_init();
     501                ctorInit->set_init( NULL );
     502
     503                // intrinsic single parameter constructors and destructors do nothing. Since this was
     504                // implicitly generated, there's no way for it to have side effects, so get rid of it
     505                // to clean up generated code.
     506                if ( InitTweak::isInstrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
     507                        delete ctorInit->get_ctor();
     508                        ctorInit->set_ctor( NULL );
     509                }
     510                if ( InitTweak::isInstrinsicSingleArgCallStmt( ctorInit->get_ctor() ) ) {
     511                        delete ctorInit->get_dtor();
     512                        ctorInit->set_dtor( NULL );
     513                }
     514        }
    473515} // namespace ResolvExpr
    474516
  • src/ResolvExpr/Resolver.h

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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 : Wed May 11 13:17:52 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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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/Constant.cc

    rbb8ea30 rd668182  
    3030Constant::~Constant() { delete type; }
    3131
    32 Constant Constant::from( int i ) {
     32Constant Constant::from_int( int i ) {
    3333        return Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), std::to_string( i ) );
    3434}
    3535
    36 Constant Constant::from( unsigned long i ) {
     36Constant Constant::from_ulong( unsigned long i ) {
    3737        return Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::to_string( i ) );
    3838}
    3939
    40 Constant Constant::from( double d ) {
     40Constant Constant::from_double( double d ) {
    4141        return Constant( new BasicType( Type::Qualifiers(), BasicType::Double ), std::to_string( d ) );
    4242}
  • src/SynTree/Constant.h

    rbb8ea30 rd668182  
    3333
    3434        /// generates an integer constant of the given int
    35         static Constant from( int i );
     35        static Constant from_int( int i );
    3636        /// generates an integer constant of the given unsigned long int
    37         static Constant from( unsigned long i );
     37        static Constant from_ulong( unsigned long i );
    3838        /// generates a floating point constant of the given double
    39         static Constant from( double d );
     39        static Constant from_double( double d );
    4040
    4141        virtual Constant *clone() const;
  • src/SynTree/Declaration.h

    rbb8ea30 rd668182  
    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
     11// Last Modified By : Rob Schluntz
     12// Last Modified On : Fri May 06 16:26:12 2016
    1313// Update Count     : 33
    1414//
     
    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
     
    106115        typedef DeclarationWithType Parent;
    107116  public:
    108         FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn );
     117        // temporary - merge this into general GCC attributes
     118        struct Attribute {
     119                enum Type {
     120                        NoAttribute, Constructor, Destructor,
     121                } type;
     122                enum Priority {
     123                        // priorities 0-100 are reserved by gcc, so it's okay to use 100 an exceptional case
     124                        Default = 100, High,
     125                } priority;
     126                Attribute(Type t = NoAttribute, Priority p = Default) : type(t), priority(p) {};
     127        };
     128
     129        FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, Attribute attribute = Attribute() );
    109130        FunctionDecl( const FunctionDecl &other );
    110131        virtual ~FunctionDecl();
     
    119140        std::list< std::string >& get_oldIdents() { return oldIdents; }
    120141        std::list< Declaration* >& get_oldDecls() { return oldDecls; }
     142        Attribute get_attribute() const { return attribute; }
     143        void set_attribute( Attribute newValue ) { attribute = newValue; }
    121144
    122145        virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); }
     
    130153        std::list< std::string > oldIdents;
    131154        std::list< Declaration* > oldDecls;
     155        Attribute attribute;
    132156};
    133157
  • src/SynTree/DeclarationWithType.cc

    rbb8ea30 rd668182  
    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

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

    rbb8ea30 rd668182  
    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/FunctionDecl.cc

    rbb8ea30 rd668182  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue May 03 15:37:43 2016
     12// Last Modified On : Fri May 06 15:59:48 2016
    1313// Update Count     : 19
    1414//
     
    2121#include "Common/utility.h"
    2222
    23 FunctionDecl::FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn )
    24                 : Parent( name, sc, linkage ), type( type ), statements( statements ) {
     23FunctionDecl::FunctionDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, FunctionType *type, CompoundStmt *statements, bool isInline, bool isNoreturn, Attribute attribute )
     24                : Parent( name, sc, linkage ), type( type ), statements( statements ), attribute( attribute ) {
    2525        set_isInline( isInline );
    2626        set_isNoreturn( isNoreturn );
     
    3232
    3333FunctionDecl::FunctionDecl( const FunctionDecl &other )
    34         : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ) {
     34        : Parent( other ), type( maybeClone( other.type ) ), statements( maybeClone( other.statements ) ), attribute( other.attribute ) {
    3535}
    3636
     
    6565                os << "_Noreturn ";
    6666        } // if
     67        switch ( attribute.type ) {
     68                case Attribute::Constructor:
     69                        os << "Global Constructor ";
     70                        break;
     71                case Attribute::Destructor:
     72                        os << "Global Destructor ";
     73                        break;
     74                default:
     75                        break;
     76        }
     77        if ( attribute.priority != Attribute::Default ) {
     78                os << "with priority " << attribute.priority << " ";
     79        }
    6780        if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
    6881                os << DeclarationNode::storageName[ get_storageClass() ] << ' ';
     
    105118                os << "_Noreturn ";
    106119        } // if
     120        switch ( attribute.type ) {
     121                case Attribute::Constructor:
     122                        os << " Global Constructor ";
     123                        break;
     124                case Attribute::Destructor:
     125                        os << " Global Destructor ";
     126                        break;
     127                default:
     128                        break;
     129        }
     130        if ( attribute.priority != Attribute::Default ) {
     131                os << "with priority " << attribute.priority << " ";
     132        }
    107133        if ( get_storageClass() != DeclarationNode::NoStorageClass ) {
    108134                os << DeclarationNode::storageName[ get_storageClass() ] << ' ';
  • src/SynTree/Initializer.cc

    rbb8ea30 rd668182  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri May 13 13:19:30 2016
     12// Last Modified On : Fri May 13 13:23:03 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}
     
    5657}
    5758
    58 ListInit::ListInit( std::list<Initializer*> &_initializers, std::list<Expression *> &_designators )
    59         : initializers( _initializers ), designators( _designators ) {
     59ListInit::ListInit( const std::list<Initializer*> &_initializers, const std::list<Expression *> &_designators, bool maybeConstructed )
     60        : Initializer( maybeConstructed), initializers( _initializers ), designators( _designators ) {
    6061}
    6162
     
    8182                (*i)->print( os, indent + 2 );
    8283}
     84
     85
     86ConstructorInit::ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init ) : Initializer( true ), ctor( ctor ), dtor( dtor ), init( init ) {}
     87ConstructorInit::~ConstructorInit() {
     88        delete ctor;
     89        delete init;
     90}
     91
     92ConstructorInit *ConstructorInit::clone() const {
     93        return new ConstructorInit( *this );
     94}
     95
     96void ConstructorInit::print( std::ostream &os, int indent ) {
     97        os << std::endl << std::string(indent, ' ') << "Constructor initializer: " << std::endl;
     98        if ( ctor ) {
     99                os << std::string(indent+2, ' ');
     100                os << "initially constructed with ";
     101                ctor->print( os, indent+4 );
     102        } // if
     103
     104        if ( dtor ) {
     105                os << std::string(indent+2, ' ');
     106                os << "destructed with ";
     107                dtor->print( os, indent+4 );
     108        }
     109
     110        if ( init ) {
     111                os << std::string(indent+2, ' ');
     112                os << "with fallback C-style initializer: ";
     113                init->print( os, indent+4 );
     114        }
     115}
     116
     117std::ostream & operator<<( std::ostream & out, Initializer * init ) {
     118        init->print( out );
     119        return out;
     120}
     121
    83122// Local Variables: //
    84123// tab-width: 4 //
  • src/SynTree/Initializer.h

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Rob Schluntz
    12 // Last Modified On : Fri May 13 13:20:17 2016
     12// Last Modified On : Fri May 13 13:23:32 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 )
     
    5859                os << " with initializer ";
    5960                init->print( os, indent );
     61                os << std::endl << std::string(indent, ' ');
     62                os << "maybeConstructed? " << init->get_maybeConstructed();
    6063        } // if
    6164
  • src/SynTree/SynTree.h

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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/driver/cc1.cc

    rbb8ea30 rd668182  
    1010// Created On       : Fri Aug 26 14:23:51 2005
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jan 25 16:05:15 2016
    13 // Update Count     : 56
     12// Last Modified On : Thu May  5 16:04:30 2016
     13// Update Count     : 77
    1414//
    1515
     
    108108        const char *args[argc + 100];                                           // leave space for 100 additional cpp command line values
    109109        int nargs = 1;                                                                          // number of arguments in args list; 0 => command name
    110         const char *uargs[20];                                                          // leave space for 20 additional cfa-cpp command line values
    111         int nuargs = 1;                                                                         // 0 => command name
     110        const char *cargs[20];                                                          // leave space for 20 additional cfa-cpp command line values
     111        int ncargs = 1;                                                                         // 0 => command name
    112112
    113113        signal( SIGINT,  sigTermHandler );
    114114        signal( SIGTERM, sigTermHandler );
     115
     116#ifdef __DEBUG_H__
     117        cerr << "Stage1" << endl;
     118#endif // __DEBUG_H__
    115119
    116120        // process all the arguments
     
    153157                                CFA_flag = true;
    154158                        } else if ( prefix( arg, D__CFA_FLAGPREFIX__ ) ) {
    155                                 uargs[nuargs] = ( *new string( arg.substr( D__CFA_FLAGPREFIX__.size() ) ) ).c_str();
    156                                 nuargs += 1;
     159                                cargs[ncargs] = ( *new string( arg.substr( D__CFA_FLAGPREFIX__.size() ) ) ).c_str();
     160                                ncargs += 1;
    157161                        } else if ( arg == "-D" && prefix( argv[i + 1], D__CFA_FLAGPREFIX__.substr(2) ) ) {
    158                                 uargs[nuargs] = ( *new string( string( argv[i + 1] ).substr( D__CFA_FLAGPREFIX__.size() - 2 ) ) ).c_str();
    159                                 nuargs += 1;
     162                                cargs[ncargs] = ( *new string( string( argv[i + 1] ).substr( D__CFA_FLAGPREFIX__.size() - 2 ) ) ).c_str();
     163                                ncargs += 1;
    160164                                i += 1;                                                                 // and the argument
    161165                        } else if ( prefix( arg, D__GCC_BPREFIX__ ) ) {
     
    317321
    318322        if ( fork() == 0 ) {                                                            // child runs CFA
    319                 uargs[0] = ( *new string( bprefix + "/cfa-cpp" ) ).c_str();
    320 
    321                 uargs[nuargs] = tmpname;
    322                 nuargs += 1;
     323                cargs[0] = ( *new string( bprefix + "/cfa-cpp" ) ).c_str();
     324
     325                // Source file-name used to generate routine names containing global initializations for TU.
     326                cargs[ncargs] = ( *new string( "-F" ) ).c_str();
     327                ncargs += 1;
     328                cargs[ncargs] = ( *new string( string( cpp_in ) ) ).c_str();
     329                ncargs += 1;
     330
     331                cargs[ncargs] = tmpname;
     332                ncargs += 1;
    323333                if ( o_name != NULL ) {
    324                         uargs[nuargs] = o_name;
    325                         nuargs += 1;
     334                        cargs[ncargs] = o_name;
     335                        ncargs += 1;
    326336                } else if ( ! CFA_flag ) {                                              // run cfa-cpp ?
    327                         uargs[nuargs] = cpp_out;
    328                         nuargs += 1;
     337                        cargs[ncargs] = cpp_out;
     338                        ncargs += 1;
    329339                } // if
    330                 uargs[nuargs] = NULL;                                                   // terminate argument list
    331 
    332 #ifdef __DEBUG_H__
    333                 cerr << "cfa-cpp nuargs: " << o_name << " " << CFA_flag << " " << nuargs << endl;
    334                 for ( i = 0; uargs[i] != NULL; i += 1 ) {
    335                         cerr << uargs[i] << " ";
     340                cargs[ncargs] = NULL;                                                   // terminate argument list
     341
     342#ifdef __DEBUG_H__
     343                cerr << "cfa-cpp ncargs: " << o_name << " " << CFA_flag << " " << ncargs << endl;
     344                for ( i = 0; cargs[i] != NULL; i += 1 ) {
     345                        cerr << cargs[i] << " ";
    336346                } // for
    337347                cerr << endl;
    338348#endif // __DEBUG_H__
    339349
    340                 execvp( uargs[0], (char * const *)uargs );              // should not return
     350                execvp( cargs[0], (char * const *)cargs );              // should not return
    341351                perror( "CFA Translator error: cpp level, execvp" );
    342352                exit( EXIT_FAILURE );
     
    370380        const char *args[argc + 100];                                           // leave space for 100 additional cfa command line values
    371381        int nargs = 1;                                                                          // number of arguments in args list; 0 => command name
     382
     383#ifdef __DEBUG_H__
     384        cerr << "Stage2" << endl;
     385#endif // __DEBUG_H__
    372386
    373387        // process all the arguments
     
    467481
    468482        if ( arg == "-E" ) {
    469 #ifdef __DEBUG_H__
    470                 cerr << "Stage1" << endl;
    471 #endif // __DEBUG_H__
    472483                Stage1( argc, argv );
    473484        } else if ( arg == "-fpreprocessed" ) {
    474 #ifdef __DEBUG_H__
    475                 cerr << "Stage2" << endl;
    476 #endif // __DEBUG_H__
    477485                Stage2( argc, argv );
    478486        } else {
  • src/examples/abstype.c

    rbb8ea30 rd668182  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 27 18:10:01 2015
    13 // Update Count     : 4
     12// Last Modified On : Wed Apr  6 22:16:08 2016
     13// Update Count     : 8
    1414//
    1515
    16 type T | { T x( T ); };
     16otype T | { T x( T ); };
    1717
    1818T y( T t ) {
     
    2121}
    2222
    23 forall(type T) lvalue T *?( T* );
    24 int ?++( int *);
    25 int ?=?( int*, int );
    26 forall(dtype DT) DT* ?=?( DT **, DT* );
     23forall( otype T ) lvalue T *?( T* );
     24int ?++( int * );
     25int ?=?( int *, int );
     26forall( dtype DT ) DT * ?=?( DT **, DT* );
    2727
    28 type U = int*;
     28otype U = int *;
    2929
    3030U x( U u ) {
  • src/examples/alloc.c

    rbb8ea30 rd668182  
    1111// Created On       : Wed Feb  3 07:56:22 2016
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Wed Feb 17 11:43:23 2016
    14 // Update Count     : 40
     13// Last Modified On : Fri Mar 11 17:42:08 2016
     14// Update Count     : 59
    1515//
    1616
     17forall( otype T ) T * malloc( char fill );
     18forall( dtype T ) T *?=?( T **, void * );
     19void *malloc( unsigned long int );
     20#if 0
    1721#include <fstream>
    1822#include <stdlib>
     
    2529int * bar( int * p, int c ) { return p; }
    2630int * baz( int * p, int c ) { return p; }
     31#endif
    2732
    2833int main( void ) {
     34#if 0
    2935    size_t size = 10;
    3036    int * p;
    3137    struct S { int x; double y; } * s;
     38#endif
    3239
     40#if 0
    3341    p = malloc( sizeof(*p) );                                                   // C malloc, type unsafe
    3442        printf( "here1\n" );
     
    3745        printf( "here2\n" );
    3846    free( p );
    39     p = malloc( (char)'\0' );                                                                   // CFA malloc, type safe
     47#endif
     48//    int * p;
     49//    p = malloc( (char)'\0' );                                                                 // CFA malloc, type safe
     50    (int *)malloc( (char)'\0' );                                                                        // CFA malloc, type safe
     51    (void *)malloc( (char)'\0' );                                                                       // CFA malloc, type safe
     52#if 0
    4053        printf( "here3\n" );
    4154    p = malloc( p, 1000 );                                                              // CFA remalloc, type safe
     
    6073        printf( "here9\n" );
    6174    free( p );
    62 #if 0
     75
    6376    float * fp = malloc() + 1;
    6477    fprintf( stderr, "%p %p\n", fp, fp - 1 );
  • src/examples/array.c

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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/fstream_test.c

    rbb8ea30 rd668182  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Mar  6 20:58:29 2016
    13 // Update Count     : 54
     12// Last Modified On : Mon May  2 15:25:54 2016
     13// Update Count     : 61
    1414//
    1515
  • src/examples/includes.c

    rbb8ea30 rd668182  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 23:28:02 2016
    13 // Update Count     : 328
     12// Last Modified On : Wed Apr 13 22:30:02 2016
     13// Update Count     : 370
    1414//
    1515
     
    2424#if 1
    2525#define _GNU_SOURCE
    26 #include <aio.h>
    27 #include <a.out.h>
    28 #include <aliases.h>
    29 #include <alloca.h>
    30 #include <ansidecl.h>
    31 #include <ar.h>
    32 #include <argp.h>
     26//#include <aio.h>
     27//#include <a.out.h>
     28//#include <aliases.h>
     29//#include <alloca.h>
     30//#include <ansidecl.h>
     31//#include <ar.h>
     32//#include <argp.h>
    3333#include <argz.h>
    34 #include <assert.h>
     34//#include <assert.h>
    3535#include <bfd.h>
     36#if 0
    3637#include <bfdlink.h>
    3738#include <byteswap.h>
     
    5657#include <err.h>
    5758#include <errno.h>
    58 #if 0
    5959#include <error.h>
    60 #endif
    6160#include <eti.h>
    6261#include <evdns.h>
    6362#include <event.h>
    6463#include <evhttp.h>
     64#endif
    6565#if 0
    6666#include <evrpc.h>
     
    129129
    130130//#define _GNU_SOURCE
    131 #include <error.h>
     131#include <bfd.h>
     132//#include <error.h>
    132133
    133134#endif // 0
  • src/examples/io.c

    rbb8ea30 rd668182  
    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/rational.c

    rbb8ea30 rd668182  
    1111// Created On       : Mon Mar 28 08:43:12 2016
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Fri Apr  8 11:27:48 2016
    14 // Update Count     : 21
     13// Last Modified On : Wed May  4 14:19:36 2016
     14// Update Count     : 24
    1515//
    1616
     
    2020
    2121int main() {
    22         Rational a, b, c;
    2322        sout | "constructor" | endl;
    24         a = rational( 3 );
    25         b = rational( 4 );
    26         c = rational();
     23        Rational a = { 3 }, b = { 4 }, c;
    2724        sout | a | b | c | endl;
    28         a = rational( 4, 8 );
    29         b = rational( 5, 7 );
     25        a = (Rational){ 4, 8 };
     26        b = (Rational){ 5, 7 };
    3027        sout | a | b | endl;
    31         a = rational( -2, -3 );
    32         b = rational( 3, -2 );
     28        a = (Rational){ -2, -3 };
     29        b = (Rational){ 3, -2 };
    3330        sout | a | b | endl;
    34         a = rational( -2, 3 );
    35         b = rational( 3, 2 );
     31        a = (Rational){ -2, 3 };
     32        b = (Rational){ 3, 2 };
    3633        sout | a | b | endl;
    3734
    3835        sout | "logical" | endl;
    39         a = rational( -2 );
    40         b = rational( -3, 2 );
     36        a = (Rational){ -2 };
     37        b = (Rational){ -3, 2 };
    4138        sout | a | b | endl;
    4239        sout | a == 1 | endl;
     
    5552
    5653        sout | "conversion" | endl;
    57         a = rational( 3, 4 );
     54        a = (Rational){ 3, 4 };
    5855        sout | widen( a ) | endl;
    59         a = rational( 1, 7 );
     56        a = (Rational){ 1, 7 };
    6057        sout | widen( a ) | endl;
    61         a = rational( 355, 113 );
     58        a = (Rational){ 355, 113 };
    6259        sout | widen( a ) | endl;
    6360        sout | narrow( 0.75, 4 ) | endl;
     
    6562        sout | narrow( 3.14159265358979, 256 ) | endl;
    6663
    67         Rational x, y;
    68         x = rational( 1, 2 );
    69         y = rational( 2 );
     64        Rational x = { 1, 2 }, y = { 2 };
    7065        sout | x - y | endl;
    7166        sout | x > y | endl;
     
    7368        sout | y | denominator( y, -2 ) | y | endl;
    7469
    75         Rational z;
    76         z = rational( 0, 5 );
     70        Rational z = { 0, 5 };
    7771        sout | z | endl;
    7872
    7973        sout | x | numerator( x, 0 ) | x | endl;
    8074
    81         x = rational( 1, MAX ) + rational( 1, MAX );
     75        x = (Rational){ 1, MAX } + (Rational){ 1, MAX };
    8276        sout | x | endl;
    83         x = rational( 3, MAX ) + rational( 2, MAX );
     77        x = (Rational){ 3, MAX } + (Rational){ 2, MAX };
    8478        sout | x | endl;
    8579
  • src/examples/sum.c

    rbb8ea30 rd668182  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Mar  4 15:06:47 2016
    13 // Update Count     : 196
     12// Last Modified On : Mon May  2 15:07:57 2016
     13// Update Count     : 198
    1414//
    1515
     
    4848        } // for
    4949        sout | "sum from" | low | "to" | High | "is"
    50                  | (int)sum( size, a ) | "" | ", check" | (int)s | endl;
     50                 | (int)sum( size, a ) | ", check" | (int)s | endl;
    5151
    5252        int s = 0, a[size], v = low;
     
    5656        } // for
    5757        sout | "sum from" | low | "to" | High | "is"
    58                  | sum( size, (int *)a ) | "" | ", check" | (int)s | endl;
     58                 | sum( size, (int *)a ) | ", check" | (int)s | endl;
    5959
    6060        float s = 0.0, a[size], v = low / 10.0;
     
    6464        } // for
    6565        sout | "sum from" | low / 10.0 | "to" | High / 10.0 | "is"
    66                  | sum( size, (float *)a ) | "" | ", check" | (float)s | endl;
     66                 | sum( size, (float *)a ) | ", check" | (float)s | endl;
    6767
    6868        double s = 0, a[size], v = low / 10.0;
     
    7272        } // for
    7373        sout | "sum from" | low / 10.0 | "to" | High / 10.0 | "is"
    74                  | sum( size, (double *)a ) | "" | ", check" | (double)s | endl;
     74                 | sum( size, (double *)a ) | ", check" | (double)s | endl;
    7575
    7676        struct S { int i, j; } 0 = { 0, 0 }, 1 = { 1, 1 };
     
    8787        } // for
    8888        sout | "sum from" | low | "to" | High | "is"
    89                  | sum( size, (S *)a ) | "" | ", check" | (S)s | endl;
     89                 | sum( size, (S *)a ) | ", check" | (S)s | endl;
    9090} // main
    9191
  • src/examples/vector_int.c

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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/rational

    rbb8ea30 rd668182  
    1212// Created On       : Wed Apr  6 17:56:25 2016
    1313// Last Modified By : Peter A. Buhr
    14 // Last Modified On : Fri Apr  8 11:38:27 2016
    15 // Update Count     : 15
     14// Last Modified On : Wed May  4 14:11:45 2016
     15// Update Count     : 16
    1616//
    1717
     
    2828
    2929// constructors
    30 Rational rational();
    31 Rational rational( long int n );
    32 Rational rational( long int n, long int d );
     30void ?{}( Rational * r );
     31void ?{}( Rational * r, long int n );
     32void ?{}( Rational * r, long int n, long int d );
    3333
    3434// getter/setter for numerator/denominator
  • src/libcfa/rational.c

    rbb8ea30 rd668182  
    1111// Created On       : Wed Apr  6 17:54:28 2016
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Thu Apr 21 07:33:03 2016
    14 // Update Count     : 22
     13// Last Modified On : Wed May  4 14:16:14 2016
     14// Update Count     : 25
    1515//
    1616
     
    5353// constructors
    5454
    55 Rational rational() {
    56     return (Rational){ 0, 1 };
     55void ?{}( Rational * r ) {
     56    r{ 0, 1 };
    5757} // rational
    5858
    59 Rational rational( long int n ) {
    60     return (Rational){ n, 1 };
     59void ?{}( Rational * r, long int n ) {
     60    r{ n, 1 };
    6161} // rational
    6262
    63 Rational rational( long int n, long int d ) {
     63void ?{}( Rational * r, long int n, long int d ) {
    6464    long int t = simplify( &n, &d );                                    // simplify
    65     return (Rational){ n / t, d / t };
     65    r->numerator = n / t;
     66        r->denominator = d / t;
    6667} // rational
    6768
     
    172173Rational narrow( double f, long int md ) {
    173174        if ( md <= 1 ) {                                                                        // maximum fractional digits too small?
    174                 Rational t = rational( f, 1 );                                  // truncate fraction
    175                 return t;
     175                return (Rational){ f, 1};                                               // truncate fraction
    176176        } // if
    177177
     
    199199                k[2] = x * k[1] + k[0]; k[0] = k[1]; k[1] = k[2];
    200200        } // for
    201         Rational t = rational( neg ? -h[1] : h[1], k[1] );
    202         return t;
     201        return (Rational){ neg ? -h[1] : h[1], k[1] };
    203202} // narrow
    204203
  • src/libcfa/stdlib

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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

    rbb8ea30 rd668182  
    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 May 06 15:59:09 2016
     13// Update Count     : 203
    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"
     44#include "InitTweak/FixGlobalInit.h"
    4345//#include "Explain/GenProlog.h"
    4446//#include "Try/Visit.h"
     
    5557
    5658static void parse( FILE * input, LinkageSpec::Type t, bool shouldExit = false );
    57 static void dump( std::list< Declaration * > & translationUnit );
     59static void dump( std::list< Declaration * > & translationUnit, std::ostream & out = std::cout );
    5860
    5961bool
    6062        astp = false,
    6163        bresolvep = false,
     64        bboxp = false,
     65        ctorinitp = false,
    6266        exprp = false,
    6367        expraltp = false,
     
    7478        codegenp = false;
    7579
    76 enum { Ast, Bresolver, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, };
     80enum { Ast, Bbox, Bresolver, CtorInitFix, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, };
    7781
    7882static struct option long_opts[] = {
    7983        { "ast", no_argument, 0, Ast },
     84        { "before-box", no_argument, 0, Bbox },
    8085        { "before-resolver", no_argument, 0, Bresolver },
     86        { "ctorinitfix", no_argument, 0, CtorInitFix },
    8187        { "expr", no_argument, 0, Expr },
    8288        { "expralt", no_argument, 0, ExprAlt },
     
    97103        std::ostream *output = &std::cout;
    98104        int long_index;
    99         std::list< Declaration* > translationUnit;
     105        std::list< Declaration * > translationUnit;
     106        const char *filename = NULL;
    100107
    101108        opterr = 0;                                                                                     // prevent getopt from printing error messages
    102        
     109
    103110        int c;
    104         while ( (c = getopt_long( argc, argv, "abefglnpqrstvyzD:", long_opts, &long_index )) != -1 ) {
     111        while ( (c = getopt_long( argc, argv, "abBcefglnpqrstvyzD:F:", long_opts, &long_index )) != -1 ) {
    105112                switch ( c ) {
    106113                  case Ast:
     
    112119                        bresolvep = true;
    113120                        break;
     121                  case 'B':                                                                             // print before resolver steps
     122                        bboxp = true;
     123                        break;
     124                  case CtorInitFix:
     125                  case 'c':
     126                        ctorinitp = true;
     127                        break;
    114128                  case Expr:
    115129                  case 'e':                                                                             // dump AST after expression analysis
     
    162176                        break;
    163177                  case 'D':                                                                             // ignore -Dxxx
     178                        break;
     179                  case 'F':                                                                             // source file-name without suffix
     180                        filename = optarg;
    164181                        break;
    165182                  case '?':
     
    176193                        input = fopen( argv[ optind ], "r" );
    177194                        if ( ! input ) {
    178                                 std::cout << "Error: can't open " << argv[optind] << std::endl;
     195                                std::cout << "Error: can't open " << argv[ optind ] << std::endl;
    179196                                exit( 1 );
    180197                        } // if
     198                        // if running cfa-cpp directly, might forget to pass -F option (and really shouldn't have to)
     199                        if ( filename == NULL ) filename = argv[ optind ];
     200                        // prelude filename comes in differently
     201                        if ( libcfap ) filename = "prelude.cf";
    181202                        optind += 1;
    182203                } else {
     
    187208                        output = new ofstream( argv[ optind ] );
    188209                } // if
    189        
     210
    190211                Parser::get_parser().set_debug( grammarp );
    191212
     
    208229                                        exit( 1 );
    209230                                } // if
    210                    
     231
    211232                                parse( prelude, LinkageSpec::Intrinsic );
    212233                        } // if
    213234                } // if
    214235
    215                 parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp );     
    216  
     236                parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp );
     237
    217238                if ( parsep ) {
    218239                        Parser::get_parser().get_parseTree()->printList( std::cout );
     
    249270                OPTPRINT( "mutate" )
    250271                ControlStruct::mutate( translationUnit );
    251                 OPTPRINT( "fixNames" ) 
     272                OPTPRINT( "fixNames" )
    252273                CodeGen::fixNames( translationUnit );
    253                 OPTPRINT( "tweak" )
    254                 InitTweak::tweak( translationUnit );
     274                OPTPRINT( "fixGlobalInit" );
     275                InitTweak::fixGlobalInit( translationUnit, filename, libcfap || treep );
     276                OPTPRINT( "tweakInit" )
     277                InitTweak::genInit( translationUnit );
    255278
    256279                if ( libcfap ) {
     
    268291                if ( exprp ) {
    269292                        dump( translationUnit );
     293                        return 0;
     294                }
     295
     296                OPTPRINT( "fixInit" )
     297                // fix ObjectDecl - replaces ConstructorInit nodes
     298                InitTweak::fix( translationUnit );
     299                if ( ctorinitp ) {
     300                        dump ( translationUnit );
     301                        return 0;
    270302                }
    271303
     
    276308                OPTPRINT( "convertLvalue" )
    277309                GenPoly::convertLvalue( translationUnit );
     310
     311                if ( bboxp ) {
     312                        dump( translationUnit );
     313                        return 0;
     314                }
    278315                OPTPRINT( "box" )
    279316                GenPoly::box( translationUnit );
    280                
     317
    281318                // print tree right before code generation
    282319                if ( codegenp ) {
     
    292329        } catch ( SemanticError &e ) {
    293330                if ( errorp ) {
    294                         dump( translationUnit );
     331                        std::cerr << "---AST at error:---" << std::endl;
     332                        dump( translationUnit, std::cerr );
     333                        std::cerr << std::endl << "---End of AST, begin error message:---\n" << std::endl;
    295334                }
    296335                e.print( std::cerr );
     
    314353        } // try
    315354
     355        deleteAll( translationUnit );
    316356        return 0;
    317357} // main
     
    331371}
    332372
    333 static void dump( std::list< Declaration * > & translationUnit ) {
     373static void dump( std::list< Declaration * > & translationUnit, std::ostream & out ) {
    334374        std::list< Declaration * > decls;
    335375        if ( noprotop ) {
    336                 filter( translationUnit.begin(), translationUnit.end(), 
     376                filter( translationUnit.begin(), translationUnit.end(),
    337377                                std::back_inserter( decls ), notPrelude );
    338378        } else {
     
    340380        }
    341381
    342         printAll( decls, std::cout );
     382        printAll( decls, out );
    343383        deleteAll( translationUnit );
    344384}
Note: See TracChangeset for help on using the changeset viewer.