Changes in / [bb8ea30:d668182]
- Files:
-
- 8 added
- 2 deleted
- 73 edited
-
doc/LaTeXmacros/common.tex (modified) (10 diffs)
-
doc/refrat/refrat.tex (modified) (163 diffs)
-
doc/user/user.tex (modified) (87 diffs)
-
src/CodeGen/CodeGenerator.cc (modified) (37 diffs)
-
src/CodeGen/FixNames.cc (modified) (4 diffs)
-
src/CodeGen/OperatorTable.cc (modified) (2 diffs)
-
src/CodeGen/OperatorTable.h (modified) (2 diffs)
-
src/GenPoly/Box.cc (modified) (34 diffs)
-
src/GenPoly/CopyParams.cc (modified) (4 diffs)
-
src/GenPoly/GenPoly.cc (modified) (6 diffs)
-
src/GenPoly/PolyMutator.cc (modified) (3 diffs)
-
src/GenPoly/Specialize.cc (modified) (4 diffs)
-
src/InitTweak/FixGlobalInit.cc (added)
-
src/InitTweak/FixGlobalInit.h (added)
-
src/InitTweak/FixInit.cc (added)
-
src/InitTweak/FixInit.h (added)
-
src/InitTweak/GenInit.cc (added)
-
src/InitTweak/GenInit.h (added)
-
src/InitTweak/InitModel.cc (modified) (3 diffs)
-
src/InitTweak/RemoveInit.cc (deleted)
-
src/InitTweak/RemoveInit.h (deleted)
-
src/InitTweak/module.mk (modified) (1 diff)
-
src/MakeLibCfa.cc (modified) (6 diffs)
-
src/Makefile.in (modified) (12 diffs)
-
src/Parser/DeclarationNode.cc (modified) (7 diffs)
-
src/Parser/InitializerNode.cc (modified) (5 diffs)
-
src/Parser/ParseNode.h (modified) (4 diffs)
-
src/Parser/TypeData.cc (modified) (3 diffs)
-
src/Parser/parser.cc (modified) (1 diff)
-
src/Parser/parser.yy (modified) (3 diffs)
-
src/ResolvExpr/AlternativeFinder.cc (modified) (2 diffs)
-
src/ResolvExpr/AlternativeFinder.h (modified) (3 diffs)
-
src/ResolvExpr/Resolver.cc (modified) (16 diffs)
-
src/ResolvExpr/Resolver.h (modified) (2 diffs)
-
src/SymTab/AddVisit.h (modified) (2 diffs)
-
src/SymTab/Autogen.cc (added)
-
src/SymTab/Autogen.h (added)
-
src/SymTab/Validate.cc (modified) (9 diffs)
-
src/SymTab/module.mk (modified) (2 diffs)
-
src/SynTree/CommaExpr.cc (modified) (1 diff)
-
src/SynTree/CompoundStmt.cc (modified) (3 diffs)
-
src/SynTree/Constant.cc (modified) (1 diff)
-
src/SynTree/Constant.h (modified) (1 diff)
-
src/SynTree/Declaration.h (modified) (7 diffs)
-
src/SynTree/DeclarationWithType.cc (modified) (2 diffs)
-
src/SynTree/Expression.cc (modified) (3 diffs)
-
src/SynTree/Expression.h (modified) (3 diffs)
-
src/SynTree/FunctionDecl.cc (modified) (5 diffs)
-
src/SynTree/Initializer.cc (modified) (5 diffs)
-
src/SynTree/Initializer.h (modified) (7 diffs)
-
src/SynTree/Mutator.cc (modified) (3 diffs)
-
src/SynTree/Mutator.h (modified) (4 diffs)
-
src/SynTree/ObjectDecl.cc (modified) (3 diffs)
-
src/SynTree/SynTree.h (modified) (3 diffs)
-
src/SynTree/TypeSubstitution.cc (modified) (3 diffs)
-
src/SynTree/TypeSubstitution.h (modified) (8 diffs)
-
src/SynTree/Visitor.cc (modified) (3 diffs)
-
src/SynTree/Visitor.h (modified) (4 diffs)
-
src/driver/cc1.cc (modified) (6 diffs)
-
src/examples/abstype.c (modified) (2 diffs)
-
src/examples/alloc.c (modified) (4 diffs)
-
src/examples/array.c (modified) (3 diffs)
-
src/examples/array.h (modified) (3 diffs)
-
src/examples/fstream_test.c (modified) (1 diff)
-
src/examples/includes.c (modified) (4 diffs)
-
src/examples/io.c (modified) (3 diffs)
-
src/examples/rational.c (modified) (5 diffs)
-
src/examples/sum.c (modified) (6 diffs)
-
src/examples/vector_int.c (modified) (3 diffs)
-
src/examples/vector_int.h (modified) (3 diffs)
-
src/examples/vector_test.c (modified) (3 diffs)
-
src/initialization.txt (modified) (1 diff)
-
src/libcfa/Makefile.am (modified) (3 diffs)
-
src/libcfa/Makefile.in (modified) (3 diffs)
-
src/libcfa/fstream (modified) (2 diffs)
-
src/libcfa/fstream.c (modified) (6 diffs)
-
src/libcfa/iostream.c (modified) (23 diffs)
-
src/libcfa/prelude.cf (modified) (3 diffs)
-
src/libcfa/rational (modified) (2 diffs)
-
src/libcfa/rational.c (modified) (4 diffs)
-
src/libcfa/stdlib (modified) (2 diffs)
-
src/libcfa/stdlib.c (modified) (2 diffs)
-
src/main.cc (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.tex
rbb8ea30 rd668182 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sat Apr 9 10:06:39201614 %% Update Count : 113 %% Last Modified On : Wed May 4 08:01:10 2016 14 %% Update Count : 54 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 19 19 % Names used in the document. 20 20 21 \newcommand{\CFA}{C$\mathbf\forall$\xspace} % set language symbolic name22 \newcommand{\CFL}{Cforall\xspace} % set language text name21 \newcommand{\CFA}{C$\mathbf\forall$\xspace} % set language symbolic name 22 \newcommand{\CFL}{Cforall\xspace} % set language text name 23 23 \newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace} % CC symbolic name 24 24 \def\c11{ISO/IEC C} % C11 name (cannot have numbers in latex command name) … … 43 43 \belowdisplayskip \abovedisplayskip 44 44 } 45 \usepackage{relsize} % must be after change to small or selects old size45 \usepackage{relsize} % must be after change to small or selects old size 46 46 47 47 % reduce size of chapter/section titles … … 66 66 \vskip 50\p@ 67 67 }} 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}} 70 70 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 71 71 \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}} … … 109 109 \newcommand{\@sIndex}[2][\@empty]{#2\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi} 110 110 111 \newcommand{\Indexc}[1]{\lstinline$#1$\index{#1@\lstinline$#1$}} 112 \newcommand{\indexc}[1]{\index{#1@\lstinline$#1$}} 113 111 114 \newcommand{\newtermFontInline}{\emph} 112 115 \newcommand{\newterm}{\@ifstar\@snewterm\@newterm} … … 129 132 % blocks and titles 130 133 \newcommand{\define}[1]{\emph{#1\/}\index{#1}} 131 \newcommand{\rewrite}{\(\Rightarrow\)}132 134 \newcommand{\rewriterules}{\paragraph{Rewrite Rules}~\par\noindent} 133 135 \newcommand{\examples}{\paragraph{Examples}~\par\noindent} … … 141 143 \newcommand{\lhs}[1]{\par{\emph{#1:}}\index{#1@{\emph{#1}}|italic}} 142 144 \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}} 144 146 \newcommand{\nonterm}[1]{\emph{#1\/}\index{#1@{\emph{#1}}|italic}} 145 147 \newcommand{\opt}{$_{opt}$\ } … … 179 181 fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,__label__,lvalue,_Noreturn,otype,restrict,_Static_assert, 180 182 _Thread_local,throw,throwResume,trait,try,typeof,__typeof,__typeof__,}, 181 moredelim=**[is][\color{red}]{`}{`}, % red highlighting of program text182 183 }% 183 184 … … 186 187 columns=flexible, 187 188 basicstyle=\sf\relsize{-1}, 189 stringstyle=\tt, 188 190 tabsize=4, 189 191 xleftmargin=\parindent, 190 escapechar=@, 192 extendedchars=true, 193 escapechar=§, 191 194 mathescape=true, 192 195 keepspaces=true, 193 196 showstringspaces=false, 194 197 showlines=true, 195 aboveskip=6pt, 196 belowskip=4pt, 197 literate={\\`}{\raisebox{0.3ex}{\ttfamily\upshape \hspace*{-2pt}`}}1, % escape \`, otherwise used for red highlighting 198 aboveskip=4pt, 199 belowskip=2pt, 200 moredelim=**[is][\color{red}]{®}{®}, % red highlighting 201 % moredelim=**[is][\color{blue}]{¢}{¢}, % blue highlighting 202 moredelim=[is][\lstset{keywords={}}]{¶}{¶}, % temporarily turn off keywords 203 % literate={\\`}{\raisebox{0.3ex}{\ttfamily\upshape \hspace*{-2pt}`}}1, % escape \`, otherwise used for red highlighting 204 literate={...}{{$\dots$}}1 {<-}{{$\leftarrow$}}1 {=>}{{$\Rightarrow$}}1, 198 205 }% 206 207 \lstMakeShortInline© % single-character for \lstinline 199 208 200 209 \makeatletter … … 203 212 \lst@ProcessOther{"22}{\lst@ttfamily{"}{\raisebox{0.3ex}{\ttfamily\upshape "}}} % replace double quote 204 213 \lst@ProcessOther{"27}{\lst@ttfamily{'}{\raisebox{0.3ex}{\ttfamily\upshape '\hspace*{-2pt}}}} % replace single quote 205 \lst@ProcessOther{"2D}{\lst@ttfamily{-}{\t tfamily\upshape -}} % replace minus206 \lst@ProcessOther{"3C}{\lst@ttfamily{<}{\text tt{<}}} % replace less than207 \lst@ProcessOther{"3E}{\lst@ttfamily{ <}{\texttt{>}}} % replace greater than214 \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 208 217 \lst@ProcessOther{"5E}{\raisebox{0.4ex}{$\scriptstyle\land\,$}} % replace circumflex 209 218 \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 -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%%``%% 3 2 %% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 4 3 %% … … 11 10 %% Created On : Wed Apr 6 14:52:25 2016 12 11 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sat Apr 9 10:19:12201614 %% Update Count : 812 %% Last Modified On : Tue May 3 18:00:28 2016 13 %% Update Count : 64 15 14 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 15 17 16 % 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) 18 23 19 24 \documentclass[openright,twoside]{report} … … 21 26 22 27 % 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} 23 32 \usepackage{fullpage,times} 33 \usepackage{epic,eepic} 24 34 \usepackage{xspace} 25 35 \usepackage{varioref} … … 41 51 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 42 52 53 % Names used in the document. 54 55 \newcommand{\Version}{1.0.0} 56 57 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 58 43 59 \setcounter{secnumdepth}{3} % number subsubsections 44 60 \setcounter{tocdepth}{3} % subsubsections in table of contents … … 123 139 \subsection{Scopes of identifiers}\index{scopes} 124 140 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. 142 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 ©type©\use{type} or ©typedef©\use{typedef} declaration and the other is not. 143 The outer declaration becomes \Index{visible} when the scope of the inner declaration terminates. 144 \begin{rationale} 145 Hence, a \CFA program can declare an ©int v© and a ©float v© in the same scope; 132 146 a {\CC} program can not. 133 147 \end{rationale} … … 138 152 139 153 \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. 154 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 \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. 142 155 Within one translation unit, each instance of an identifier with \Index{internal linkage} denotes the same object or function in the same circumstances. 143 156 Identifiers with \Index{no linkage} always denote unique entities. 144 157 \begin{rationale} 145 A \CFA program can declare an \lstinline$extern int v$ and an \lstinline$extern float v$;158 A \CFA program can declare an ©extern int v© and an ©extern float v©; 146 159 a C program cannot. 147 160 \end{rationale} … … 166 179 \end{lstlisting} 167 180 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$.181 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., ©sumable©. 169 182 The instantiation then has the semantics that would result if the type parameters were substituted into the type generator declaration by macro substitution. 170 183 … … 214 227 \CFA defines situations where values of one type are automatically converted to another type. 215 228 These conversions are called \define{implicit conversion}s. 216 The programmer can request 217 \define{explicit conversion}s using cast expressions. 229 The programmer can request \define{explicit conversion}s using cast expressions. 218 230 219 231 … … 227 239 In \CFA, these conversions play a role in overload resolution, and collectively are called the \define{safe arithmetic conversion}s. 228 240 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.241 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$. 242 Let ©unsigned$_{mr}$© be the unsigned integer type with maximal rank. 231 243 232 244 The following conversions are \emph{direct} safe arithmetic conversions. … … 235 247 The \Index{integer promotion}s. 236 248 \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$.249 For every rank $r$ greater than or equal to the rank of ©int©, conversion from ©int$_r$© to ©unsigned$_r$©. 250 \item 251 For 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 253 Conversion from ©unsigned$_{mr}$© to ©float©. 242 254 \item 243 255 Conversion from an enumerated type to its compatible integer type. 244 256 \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$.257 Conversion from ©float© to ©double©, and from ©double© to ©long double©. 258 \item 259 Conversion from ©float _Complex© to ©double _Complex©, and from ©double _Complex© to ©long double _Complex©. 248 260 \begin{sloppypar} 249 261 \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.262 Conversion from ©float _Imaginary© to ©double _Imaginary©, and from ©double _Imaginary© to ©long double _Imaginary©, if the implementation supports imaginary types. 251 263 \end{sloppypar} 252 264 \end{itemize} 253 265 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.266 If 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. 255 267 256 268 \begin{rationale} … … 266 278 \label{anon-conv} 267 279 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. 280 If 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. 270 281 The result of the conversion is a pointer to the member. 271 282 … … 275 286 int x, y; 276 287 }; 277 void move_by( struct point * p1, struct point * p2 ) { @\impl{move_by}@288 void move_by( struct point * p1, struct point * p2 ) {§\impl{move_by}§ 278 289 p1->x += p2.x; 279 290 p1->y += p2.y; … … 285 296 move_to( &cp1, &cp2 ); 286 297 \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. 298 Thanks to implicit conversion, the two arguments that ©move_by()© receives are pointers to ©cp1©'s second member and ©cp2©'s second member. 289 299 290 300 … … 328 338 a direct safe arithmetic conversion; 329 339 \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$;340 from any object type or incomplete type to ©void©; 341 \item 342 from a pointer to any non-©void© type to a pointer to ©void©; 333 343 \item 334 344 from a pointer to any type to a pointer to a more qualified version of the type\index{qualified type}; … … 341 351 Conversions that are not safe conversions are \define{unsafe conversion}s. 342 352 \begin{rationale} 343 As in C, there is an implicit conversion from \lstinline$void *$to any pointer type.353 As in C, there is an implicit conversion from ©void *© to any pointer type. 344 354 This is clearly dangerous, and {\CC} does not have this implicit conversion. 345 355 \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. … … 367 377 \begin{itemize} 368 378 \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. 379 The cost of an implicit conversion from ©int© to ©long© is 1. 380 The 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 383 If ©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©. 384 Otherwise, ©unsigned short© is converted directly to ©unsigned©, and the cost is 1. 385 386 \item 387 If ©long© can represent all the values of ©unsigned©, then the conversion cost of ©unsigned© to ©long© is 1. 379 388 Otherwise, the conversion is an unsafe conversion, and its conversion cost is undefined. 380 389 \end{itemize} … … 384 393 \begin{syntax} 385 394 \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© 392 401 \end{syntax} 393 402 … … 396 405 397 406 \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.407 Furthermore, 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. 399 408 Programmers can use these identifiers to declare functions and objects that implement operators and constants for their own types. 400 409 … … 405 414 \begin{syntax} 406 415 \oldlhs{identifier} 407 \rhs \lstinline$0$408 \rhs \lstinline$1$416 \rhs ©0© 417 \rhs ©1© 409 418 \end{syntax} 410 419 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. 412 421 No other tokens defined by the rules for integer constants are considered to be identifiers. 413 422 \begin{rationale} 414 Why `` \lstinline$0$'' and ``\lstinline$1$''? Those integers have special status in C.423 Why ``©0©'' and ``©1©''? Those integers have special status in C. 415 424 All 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.425 The operations ``©&&©'', ``©||©'', and ``©!©'' can be applied to any scalar arguments, and are defined in terms of comparison against 0. 417 426 A \nonterm{constant-expression} that evaluates to 0 is effectively compatible with every pointer type. 418 427 419 428 In 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. 420 429 However, 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.430 Defining special constants for a user-defined type is more efficient than defining a conversion to the type from ©_Bool©. 431 432 Why \emph{just} ``©0©'' and ``©1©''? Why not other integers? No other integers have special status in C. 433 A facility that let programmers declare specific constants---``©const Rational 12©'', for instance---would not be much of an improvement. 425 434 Some facility for defining the creation of values of programmer-defined types from arbitrary integer tokens would be needed. 426 435 The complexity of such a feature doesn't seem worth the gain. … … 438 447 \begin{tabular}[t]{ll} 439 448 %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{?/?}\\ 453 462 \end{tabular}\hfil 454 463 \begin{tabular}[t]{ll} 455 464 %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{?&?}\\ 468 477 \end{tabular}\hfil 469 478 \begin{tabular}[t]{ll} 470 479 %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{?"|=?}\\ 484 493 \end{tabular} 485 494 \hfil … … 496 505 497 506 \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 a499 \CFA compiler detects a syntax error because it treats `` \lstinline$?--$'' as an identifier, not as the two tokens ``\lstinline$?$'' and ``\lstinline$--$''.507 The 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 ``©--©''. 500 509 \end{rationale} 501 510 … … 504 513 \begin{itemize} 505 514 \item 506 The logical operators ``\lstinline$&&$'' and ``\lstinline$||$'', and the conditional operator 507 ``\lstinline$?:$''. 515 The logical operators ``©&&©'' and ``©||©'', and the conditional operator ``©?:©''. 508 516 These 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.517 Note 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. 510 518 511 519 \item … … 516 524 \item 517 525 The ``address of'' operator. 518 It would seem useful to define a unary `` \lstinline$&$'' operator that returns values of some programmer-defined pointer-like type.526 It would seem useful to define a unary ``©&©'' operator that returns values of some programmer-defined pointer-like type. 519 527 The 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 )$'' 528 Consider the expression ``©p = &x©'', where ©x© is of type ©T© and ©p© has the programmer-defined type ©T_ptr©. 529 The expression might be treated as a call to the unary function ``©&?©''. 530 Now 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. 531 Hence the parameter must have type ©T *©. 532 But then the expression must be rewritten as ``©p = &?( &x )©'' 526 533 ---which doesn't seem like progress! 527 534 528 535 The 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.536 It seems simpler to define a conversion function from ©T *© to ©T_ptr©. 537 538 \item 539 The ©sizeof© operator. 533 540 It is already defined for every object type, and intimately tied into the language's storage allocation model. 534 541 Redefining it seems pointless. 535 542 536 543 \item 537 The ``member of'' operators `` \lstinline$.$'' and ``\lstinline$->$''.544 The ``member of'' operators ``©.©'' and ``©->©''. 538 545 These are not really infix operators, since their right ``operand'' is not a value or object. 539 546 … … 572 579 The ``fewest unsafe conversions'' rule ensures that the usual conversions are done, if possible. 573 580 The ``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$.581 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: ©(double)-i© will be preferred to ©-(double)i©. 575 582 576 583 The ``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}). 584 It also gives preference to monomorphic values (such as the ©int© ©0©) over polymorphic values (such as the \Index{null pointer} ©0©\use{0}). 580 585 However, interpretations that call polymorphic functions are preferred to interpretations that perform unsafe conversions, because those conversions potentially lose accuracy or violate strong typing. 581 586 … … 597 602 \begin{rationale} 598 603 Predefined 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)$''.604 For instance, ``©an_int + an_int©'' is equivalent to ``©?+?(an_int, an_int)©''. 600 605 If integer addition has not been redefined in the current scope, a compiler can generate code to perform the addition directly. 601 606 If predefined functions had external linkage, this optimization would be difficult. … … 623 628 \rhs \nonterm{constant} 624 629 \rhs \nonterm{string-literal} 625 \rhs \lstinline$($ \nonterm{expression} \lstinline$)$630 \rhs ©(© \nonterm{expression} ©)© 626 631 \rhs \nonterm{generic-selection} 627 632 \end{syntax} … … 629 634 \predefined 630 635 \begin{lstlisting} 631 const int 1; @\use{1}@632 const int 0; @\use{0}@636 const int 1;§\use{1}§ 637 const int 0;§\use{0}§ 633 638 forall( dtype DT ) DT * const 0; 634 639 forall( ftype FT ) FT * const 0; … … 639 644 640 645 A \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.646 The predefined integer identifiers ``©1©'' and ``©0©'' have the integer values 1 and 0, respectively. 647 The 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. 643 648 644 649 A parenthesised expression has the same interpretations as the contained \nonterm{expression}. 645 650 646 651 \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. 652 The 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 *©. 653 In each case, the null pointer conversion is better\index{best valid interpretations} than the unsafe conversion of the integer ©0© to a pointer. 650 654 651 655 \begin{rationale} … … 653 657 654 658 \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 659 The C token ``©0©'' is an expression of type ©int© with the value ``zero'', and it \emph{also} is a null pointer constant. 660 Similarly, ``©(void *)0© is an expression of type ©(void *)© whose value is a null pointer, and it also is a null pointer constant. 661 However, in C, ``©(void *)(void *)0©'' is 659 662 \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. 660 663 … … 663 666 \begin{lstlisting} 664 667 forall( 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. 666 669 The only such value is the null pointer. 667 670 Therefore the type \emph{alone} is enough to identify a null pointer. … … 673 676 674 677 \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.678 If 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. 676 679 677 680 \semantics … … 684 687 \lhs{postfix-expression} 685 688 \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} ©,© ©}© 695 698 \lhs{argument-expression-list} 696 699 \rhs \nonterm{assignment-expression} 697 \rhs \nonterm{argument-expression-list} \lstinline$,$700 \rhs \nonterm{argument-expression-list} ©,© 698 701 \nonterm{assignment-expression} 699 702 \end{syntax} … … 701 704 \rewriterules 702 705 \begin{lstlisting} 703 a[b] @\rewrite@ ?[?]( b, a ) // if a has integer type@\use{?[?]}@704 a[b] @\rewrite@?[?]( a, b ) // otherwise705 a( @\emph{arguments}@ ) @\rewrite@ ?()( a, @\emph{arguments}@ )@\use{?()}@706 a++ @\rewrite@ ?++(&( a ))@\use{?++}@707 a-- @\rewrite@ ?--(&( a ))@\use{?--}@706 a[b] => ?[?]( b, a ) // if a has integer type§\use{?[?]}§ 707 a[b] => ?[?]( a, b ) // otherwise 708 a( §\emph{arguments}§ ) => ?()( a, §\emph{arguments}§ )§\use{?()}§ 709 a++ => ?++(&( a ))§\use{?++}§ 710 a-- => ?--(&( a ))§\use{?--}§ 708 711 \end{lstlisting} 709 712 … … 713 716 \predefined 714 717 \begin{lstlisting} 715 forall( otype T ) lvalue T ?[?]( T *, ptrdiff_t ); @\use{ptrdiff_t}@718 forall( otype T ) lvalue T ?[?]( T *, ptrdiff_t );§\use{ptrdiff_t}§ 716 719 forall( otype T ) lvalue _Atomic T ?[?]( _Atomic T *, ptrdiff_t ); 717 720 forall( otype T ) lvalue const T ?[?]( const T *, ptrdiff_t ); … … 733 736 The interpretations of subscript expressions are the interpretations of the corresponding function call expressions. 734 737 \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$?[?]$. 738 C 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 ©?[?]©. 737 739 738 740 Subscript expressions are rewritten as function calls that pass the first parameter by value. 739 741 This 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.742 The alternative is to use the rewrite rule ``©a[b] => ?[?](&(a), b)©''. 743 However, C semantics forbid this approach: the ©a© in ``©a[b]©'' can be an arbitrary pointer value, which does not have an address. 742 744 743 745 The repetitive form of the predefined identifiers shows up a deficiency\index{deficiencies!pointers … … 754 756 \nonterm{postfix-expression} in a function call may have some interpretations that are function designators and some that are not. 755 757 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$?()$''.758 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 ``©?()©''. 757 759 The valid interpretations of the rewritten expression are determined in the manner described below. 758 760 … … 761 763 \begin{itemize} 762 764 \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. 765 766 \end{itemize} 766 767 The type of the valid interpretation is the return type of the function designator. 767 768 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 769 For 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 770 770 \begin{itemize} 771 771 \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.772 If the declaration of the implicit parameter uses \Index{type-class} ©type©\use{type}, the implicit argument must be an object type; 773 if it uses ©dtype©, the implicit argument must be an object type or an incomplete type; 774 and if it uses ©ftype©, the implicit argument must be a function type. 775 775 776 776 \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. … … 791 791 \begin{rationale} 792 792 One 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. 793 For 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. 797 796 Consider 798 797 \begin{lstlisting} … … 805 804 f = g( d, f ); // (3) (unsafe conversion to float) 806 805 \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. 806 If ©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 808 Another example is the function ``©void h( int *);©''. 809 This function can be passed a ©void *© argument, but the generalization ``©forall( otype T ) void h( T *);©'' can not. 810 In this case, ©void© is not a valid value for ©T© because it is not an object type. 811 If unsafe conversions were allowed, ©T© could be inferred to be \emph{any} object type, which is undesirable. 815 812 \end{rationale} 816 813 817 814 \examples 818 A function called `` \lstinline$?()$'' might be part of a numerical differentiation package.815 A function called ``©?()©'' might be part of a numerical differentiation package. 819 816 \begin{lstlisting} 820 817 extern otype Derivative; … … 827 824 d = sin_dx( 12.9 ); 828 825 \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 )$''.826 Here, the only interpretation of ©sin_dx© is as an object of type ©Derivative©. 827 For that interpretation, the function call is treated as ``©?()( sin_dx, 12.9 )©''. 831 828 \begin{lstlisting} 832 829 int f( long ); // (1) … … 835 832 int i = f( 5 ); // calls (1) 836 833 \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.834 Function (1) provides a valid interpretation of ``©f( 5 )©'', using an implicit ©int© to ©long© conversion. 835 The 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. 839 836 840 837 \begin{lstlisting} … … 842 839 double d = h( 1.5 ); 843 840 \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©. 846 842 847 843 \begin{lstlisting} 848 844 forall( otype T, otype U ) void g( T, U ); // (4) 849 845 forall( otype T ) void g( T, T ); // (5) 850 forall( otype T ) void g( T, long ); // (6)846 forall( otype T ) void g( T, long ); // (6) 851 847 void g( long, long ); // (7) 852 848 double d; 853 849 int i; 854 850 int *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).851 g( d, d ); // calls (5) 852 g( d, i ); // calls (6) 853 g( i, i ); // calls (7) 854 g( i, p ); // calls (4) 855 \end{lstlisting} 856 The 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). 861 857 862 858 For 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.859 Of the remaining interpretations for (4), (5), and (6) (with ©i© converted to ©long©), (6) is chosen because it is the least polymorphic. 864 860 865 861 The third call has valid interpretations for all of the functions; … … 870 866 forall( otype T ) T min( T, T ); 871 867 double max( double, double ); 872 trait min_max( T ) { @\impl{min_max}@868 trait min_max( T ) {§\impl{min_max}§ 873 869 T min( T, T ); 874 870 T max( T, T ); … … 877 873 shuffle( 9, 10 ); 878 874 \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) 875 The 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} 877 extern void q( int ); // (8) 878 extern void q( void * ); // (9) 884 879 extern void r(); 885 880 q( 0 ); 886 881 r( 0 ); 887 882 \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.883 The ©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). 884 The former is chosen because the ©int© ©0© is \Index{less polymorphic}. 885 For the same reason, ©int© ©0© is passed to ©r()©, even though it has \emph{no} declared parameter types. 891 886 892 887 893 888 \subsubsection{Structure and union members} 894 889 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©. 891 If 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. 892 If 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. 900 893 The expression has no other interpretations. 901 894 902 The expression ``\lstinline$p->m$'' has the same interpretations as the expression 903 ``\lstinline$(*p).m$''. 895 The expression ``©p->m©'' has the same interpretations as the expression ``©(*p).m©''. 904 896 905 897 … … 996 988 * ?--( _Atomic const restrict volatile T * _Atomic restrict volatile * ); 997 989 \end{lstlisting} 998 For every extended integer type \lstinline$X$there exist990 For every extended integer type ©X© there exist 999 991 % Don't use predefined: keep this out of prelude.cf. 1000 992 \begin{lstlisting} … … 1002 994 ?--( volatile X * ), ?--( _Atomic volatile X * ); 1003 995 \end{lstlisting} 1004 For every complete enumerated type \lstinline$E$there exist996 For every complete enumerated type ©E© there exist 1005 997 % Don't use predefined: keep this out of prelude.cf. 1006 998 \begin{lstlisting} … … 1010 1002 1011 1003 \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.1004 Note 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. 1013 1005 This partially enforces the C semantic rule that such operands must be \emph{modifiable} lvalues. 1014 1006 \end{rationale} … … 1016 1008 \begin{rationale} 1017 1009 In 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$.1010 Hence, ©void *© objects cannot be incremented. 1011 In \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©. 1020 1012 \end{rationale} 1021 1013 1022 1014 \semantics 1023 1015 First, 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. 1016 For 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. 1026 1017 1027 1018 For the remaining interpretations, the expression is rewritten, and the interpretations of the expression are the interpretations of the corresponding function call. … … 1036 1027 \end{lstlisting} 1037 1028 \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. 1029 Since ©&(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 *©. 1031 Note that there is no conversion that adds an ©_Atomic© qualifier, so the ©_Atomic volatile short int© overloading does not provide a valid interpretation. 1043 1032 \end{sloppypar} 1044 1033 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.1034 There 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 1036 The 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. 1048 1037 \begin{lstlisting} 1049 1038 char * const restrict volatile * restrict volatile pqpc; … … 1052 1041 ppc++; 1053 1042 \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$.1043 Since ©&(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©. 1057 1046 1058 1047 \begin{rationale} … … 1068 1057 \begin{enumerate} 1069 1058 \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 by1059 ``©char * p; p++;©''. 1060 The argument to ©?++© has type ©char * *©, and the result has type ©char *©. 1061 The expression would be valid if ©?++© were declared by 1073 1062 \begin{lstlisting} 1074 1063 forall( 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++©''. 1068 The 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. 1080 1069 Hence the actual predefined function is 1081 1070 \begin{lstlisting} 1082 1071 forall( 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++©''. 1076 The result again has type ©char *©, but no safe conversion adds an ©_Atomic© qualifier, so the function in point 2 is not applicable. 1077 A separate overloading of ©?++© is required. 1078 1079 \item 1080 ``©char const volatile * pq; pq++©''. 1081 Here the result has type ©char const volatile *©, so a new overloading is needed: 1095 1082 \begin{lstlisting} 1096 1083 forall( otype T ) T const volatile * ?++( T const volatile *restrict volatile * ); … … 1099 1086 1100 1087 \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++©''. 1089 The ©restrict© qualifier is handled just like ©const© and ©volatile© in the previous case: 1103 1090 \begin{lstlisting} 1104 1091 forall( 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 *©. 1093 This 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. 1107 1094 \end{enumerate} 1108 1095 \end{rationale} … … 1120 1107 \lhs{unary-expression} 1121 1108 \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} 1124 1111 \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 ©&© ©*© ©+© ©-© ©~© ©!© 1128 1115 \end{syntax} 1129 1116 1130 1117 \rewriterules 1131 1118 \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{--?}§ 1139 1126 \end{lstlisting} 1140 1127 … … 1232 1219 * --?( _Atomic const restrict volatile T * _Atomic restrict volatile * ); 1233 1220 \end{lstlisting} 1234 For every extended integer type \lstinline$X$there exist1221 For every extended integer type ©X© there exist 1235 1222 % Don't use predefined: keep this out of prelude.cf. 1236 1223 \begin{lstlisting} … … 1240 1227 --?( _Atomic volatile X * ); 1241 1228 \end{lstlisting} 1242 For every complete enumerated type \lstinline$E$there exist1229 For every complete enumerated type ©E© there exist 1243 1230 % Don't use predefined: keep this out of prelude.cf. 1244 1231 \begin{lstlisting} … … 1277 1264 1278 1265 \constraints 1279 The operand of the unary ``\lstinline$&$'' operator shall have exactly one 1280 \Index{interpretation}\index{ambiguous interpretation}, which shall be unambiguous. 1266 The operand of the unary ``©&©'' operator shall have exactly one \Index{interpretation}\index{ambiguous interpretation}, which shall be unambiguous. 1281 1267 1282 1268 \semantics 1283 The ``\lstinline$&$'' expression has one interpretation which is of type \lstinline$T *$, where 1284 \lstinline$T$ is the type of the operand. 1269 The ``©&©'' expression has one interpretation which is of type ©T *©, where ©T© is the type of the operand. 1285 1270 1286 1271 The interpretations of an indirection expression are the interpretations of the corresponding function call. … … 1311 1296 forall( ftype FT ) int !?( FT * ); 1312 1297 \end{lstlisting} 1313 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1298 For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist 1314 1299 % Don't use predefined: keep this out of prelude.cf. 1315 1300 \begin{lstlisting} … … 1324 1309 \begin{lstlisting} 1325 1310 long 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) are1311 void eat_double( double );§\use{eat_double}§ 1312 eat_double(-li ); // => eat_double( -?( li ) ); 1313 \end{lstlisting} 1314 The valid interpretations of ``©-li©'' (assuming no extended integer types exist) are 1330 1315 \begin{center} 1331 1316 \begin{tabular}{llc} interpretation & result type & expression conversion cost \\ 1332 1317 \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) \\ 1345 1330 \end{tabular} 1346 1331 \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, are1332 The valid interpretations of the ©eat_double© call, with the cost of the argument conversion and the cost of the entire expression, are 1348 1333 \begin{center} 1349 1334 \begin{tabular}{lcc} interpretation & argument cost & expression cost \\ 1350 1335 \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) \\ 1363 1348 \end{tabular} 1364 1349 \end{center} 1365 Each has result type \lstinline$void$, so the best must be selected.1350 Each has result type ©void©, so the best must be selected. 1366 1351 The 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} 1352 The 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} 1373 1356 1374 1357 \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 1358 The operand of ©sizeof© or ©_Alignof© shall not be ©type©, ©dtype©, or ©ftype©. 1359 1360 When 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 1362 When ©sizeof© is applied to an identifier declared by a \nonterm{type-declaration} or a 1381 1363 \nonterm{type-parameter}, it yields the size in bytes of the type that implements the operand. 1382 1364 When the operand is an opaque type or an inferred type parameter\index{inferred parameter}, the expression is not a constant expression. 1383 1365 1384 When \lstinline$_Alignof$is applied to an identifier declared by a \nonterm{type-declaration} or a1366 When ©_Alignof© is applied to an identifier declared by a \nonterm{type-declaration} or a 1385 1367 \nonterm{type-parameter}, it yields the alignment requirement of the type that implements the operand. 1386 1368 When the operand is an opaque type or an inferred type parameter\index{inferred parameter}, the expression is not a constant expression. … … 1389 1371 otype Pair = struct { int first, second; }; 1390 1372 size_t p_size = sizeof(Pair); // constant expression 1391 extern otype Rational; @\use{Rational}@1373 extern otype Rational;§\use{Rational}§ 1392 1374 size_t c_size = sizeof(Rational); // non-constant expression 1393 1375 forall(type T) T f(T p1, T p2) { … … 1396 1378 } 1397 1379 \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. 1381 Within ©f()©, ``©sizeof(T)©'' is fixed for each call of ©f()©, but may vary from call to call. 1401 1382 \end{rationale} 1402 1383 … … 1407 1388 \lhs{cast-expression} 1408 1389 \rhs \nonterm{unary-expression} 1409 \rhs \lstinline$($ \nonterm{type-name} \lstinline$)$\nonterm{cast-expression}1390 \rhs ©(© \nonterm{type-name} ©)© \nonterm{cast-expression} 1410 1391 \end{syntax} 1411 1392 1412 1393 \constraints 1413 The \nonterm{type-name} in a \nonterm{cast-expression} shall not be \lstinline$type$, 1414 \lstinline$dtype$, or \lstinline$ftype$. 1394 The \nonterm{type-name} in a \nonterm{cast-expression} shall not be ©type©, ©dtype©, or ©ftype©. 1415 1395 1416 1396 \semantics 1417 1397 1418 In a \Index{cast expression} `` \lstinline$($\nonterm{type-name}\lstinline$)e$'', if1419 \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.1398 In 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; 1400 otherwise, ©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. 1421 1401 The 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. 1422 1402 … … 1431 1411 \lhs{multiplicative-expression} 1432 1412 \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} 1436 1416 \end{syntax} 1437 1417 1438 1418 \rewriterules 1439 1419 \begin{lstlisting} 1440 a * b @\rewrite@ ?*?( a, b )@\use{?*?}@1441 a / b @\rewrite@ ?/?( a, b )@\use{?/?}@1442 a % b @\rewrite@ ?%?( a, b )@\use{?%?}@1420 a * b => ?*?( a, b )§\use{?*?}§ 1421 a / b => ?/?( a, b )§\use{?/?}§ 1422 a % b => ?%?( a, b )§\use{?%?}§ 1443 1423 \end{lstlisting} 1444 1424 … … 1467 1447 ?*?( _Complex long double, _Complex long double ), ?/?( _Complex long double, _Complex long double ); 1468 1448 \end{lstlisting} 1469 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1449 For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist 1470 1450 % Don't use predefined: keep this out of prelude.cf. 1471 1451 \begin{lstlisting} … … 1474 1454 1475 1455 \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. 1478 1457 \end{rationale} 1479 1458 … … 1485 1464 int i; 1486 1465 long li; 1487 void eat_double( double ); @\use{eat_double}@1466 void eat_double( double );§\use{eat_double}§ 1488 1467 eat_double( li % i ); 1489 1468 \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 ) are1469 ``©li % i©'' is rewritten as ``©?%?(li, i )©''. 1470 The 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 1492 1471 \begin{center} 1493 1472 \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 \\ 1501 1480 \end{tabular} 1502 1481 \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 )$''. 1482 The 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©. 1486 If ©s© is a ©short int©, ``©s *s©'' does not have type ©short int©; 1487 it is treated as ``©( (int)s ) * ( (int)s )©'', and has type ©int©. \CFA matches that pattern; 1488 it does not predefine ``©short ?*?( short, short )©''. 1511 1489 1512 1490 These ``missing'' operators limit polymorphism. … … 1517 1495 square( s ); 1518 1496 \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$. 1497 Since \CFA does not define a multiplication operator for ©short int©, ©square( s )© is treated as ©square( (int)s )©, and the result has type ©int©. 1522 1498 This is mildly surprising, but it follows the {\c11} operator pattern. 1523 1499 … … 1528 1504 product( sa, 5); 1529 1505 \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$''. 1506 This has no valid interpretations, because \CFA has no conversion from ``array of ©short int©'' to ``array of ©int©''. 1532 1507 The alternatives in such situations include 1533 1508 \begin{itemize} 1534 1509 \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. 1510 Defining monomorphic overloadings of ©product© for ©short© and the other ``small'' types. 1511 \item 1512 Defining ``©short ?*?( short, short )©'' within the scope containing the call to ©product©. 1513 \item 1514 Defining ©product© to take as an argument a conversion function from the ``small'' type to the operator's argument type. 1542 1515 \end{itemize} 1543 1516 \end{rationale} … … 1549 1522 \lhs{additive-expression} 1550 1523 \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} 1553 1526 \end{syntax} 1554 1527 1555 1528 \rewriterules 1556 1529 \begin{lstlisting} 1557 a + b @\rewrite@ ?+?( a, b )@\use{?+?}@1558 a - b @\rewrite@ ?-?( a, b )@\use{?-?}@1530 a + b => ?+?( a, b )§\use{?+?}§ 1531 a - b => ?-?( a, b )§\use{?-?}§ 1559 1532 \end{lstlisting} 1560 1533 … … 1609 1582 * ?-?( _Atomic const restrict volatile T *, _Atomic const restrict volatile T * ); 1610 1583 \end{lstlisting} 1611 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1584 For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist 1612 1585 % Don't use predefined: keep this out of prelude.cf. 1613 1586 \begin{lstlisting} … … 1619 1592 1620 1593 \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. 1622 1595 It 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.1596 The {\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. 1624 1597 \end{rationale} 1625 1598 … … 1630 1603 \lhs{shift-expression} 1631 1604 \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} 1634 1607 \end{syntax} 1635 1608 1636 \rewriterules \use{?>>?}%use{?<<?}1637 \begin{lstlisting} 1638 a << b @\rewrite@ ?<<?( a, b )1639 a >> b @\rewrite@ ?>>?( a, b )1609 \rewriterules 1610 \begin{lstlisting} 1611 a << b => ?<<?( a, b )§\use{?<<?}§ 1612 a >> b => ?>>?( a, b )§\use{?>>?}§ 1640 1613 \end{lstlisting} 1641 1614 … … 1649 1622 long long unsigned int ?<<?( long long unsigned int, int ), ?>>?( long long unsigned int, int); 1650 1623 \end{lstlisting} 1651 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1624 For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist 1652 1625 % Don't use predefined: keep this out of prelude.cf. 1653 1626 \begin{lstlisting} … … 1669 1642 \lhs{relational-expression} 1670 1643 \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} 1675 1648 \end{syntax} 1676 1649 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} 1652 a < b => ?<?( a, b )§\use{?<?}§ 1653 a > b => ?>?( a, b )§\use{?>?}§ 1654 a <= b => ?<=?( a, b )§\use{?<=?}§ 1655 a >= b => ?>=?( a, b )§\use{?>=?}§ 1683 1656 \end{lstlisting} 1684 1657 … … 1712 1685 ?>=?( _Atomic const restrict volatile DT *, _Atomic const restrict volatile DT * ); 1713 1686 \end{lstlisting} 1714 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1687 For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist 1715 1688 % Don't use predefined: keep this out of prelude.cf. 1716 1689 \begin{lstlisting} … … 1730 1703 \lhs{equality-expression} 1731 1704 \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} 1734 1707 \end{syntax} 1735 1708 1736 1709 \rewriterules 1737 1710 \begin{lstlisting} 1738 a == b @\rewrite@ ?==?( a, b )@\use{?==?}@1739 a != b @\rewrite@ ?!=?( a, b )@\use{?"!=?}@1711 a == b => ?==?( a, b )§\use{?==?}§ 1712 a != b => ?!=?( a, b )§\use{?"!=?}§ 1740 1713 \end{lstlisting} 1741 1714 … … 1790 1763 ?==?( forall( ftype FT2) FT2*, forall( ftype FT3) FT3 * ), ?!=?( forall( ftype FT2) FT2*, forall( ftype FT3) FT3 * ); 1791 1764 \end{lstlisting} 1792 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1765 For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist 1793 1766 % Don't use predefined: keep this out of prelude.cf. 1794 1767 \begin{lstlisting} … … 1798 1771 1799 1772 \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.1773 The 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. 1801 1774 In the last case, a special constraint rule for null pointer constant operands has been replaced by a consequence of the \CFA type system. 1802 1775 \end{rationale} … … 1819 1792 \lhs{AND-expression} 1820 1793 \rhs \nonterm{equality-expression} 1821 \rhs \nonterm{AND-expression} \lstinline$&$\nonterm{equality-expression}1794 \rhs \nonterm{AND-expression} ©&© \nonterm{equality-expression} 1822 1795 \end{syntax} 1823 1796 1824 1797 \rewriterules 1825 1798 \begin{lstlisting} 1826 a & b @\rewrite@ ?&?( a, b )@\use{?&?}@1799 a & b => ?&?( a, b )§\use{?&?}§ 1827 1800 \end{lstlisting} 1828 1801 … … 1836 1809 long long unsigned int ?&?( long long unsigned int, long long unsigned int ); 1837 1810 \end{lstlisting} 1838 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1811 For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist 1839 1812 % Don't use predefined: keep this out of prelude.cf. 1840 1813 \begin{lstlisting} … … 1851 1824 \lhs{exclusive-OR-expression} 1852 1825 \rhs \nonterm{AND-expression} 1853 \rhs \nonterm{exclusive-OR-expression} \lstinline$^$\nonterm{AND-expression}1826 \rhs \nonterm{exclusive-OR-expression} ©^© \nonterm{AND-expression} 1854 1827 \end{syntax} 1855 1828 1856 1829 \rewriterules 1857 1830 \begin{lstlisting} 1858 a ^ b @\rewrite@ ?^?( a, b )@\use{?^?}@1831 a ^ b => ?^?( a, b )§\use{?^?}§ 1859 1832 \end{lstlisting} 1860 1833 … … 1868 1841 long long unsigned int ?^?( long long unsigned int, long long unsigned int ); 1869 1842 \end{lstlisting} 1870 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1843 For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist 1871 1844 % Don't use predefined: keep this out of prelude.cf. 1872 1845 \begin{lstlisting} … … 1883 1856 \lhs{inclusive-OR-expression} 1884 1857 \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} 1886 1859 \end{syntax} 1887 1860 1888 \rewriterules \use{?"|?}1889 \begin{lstlisting} 1890 a | b @\rewrite@ ?|?( a, b )1861 \rewriterules 1862 \begin{lstlisting} 1863 a | b => ?|?( a, b )§\use{?"|?}§ 1891 1864 \end{lstlisting} 1892 1865 … … 1900 1873 long long unsigned int ?|?( long long unsigned int, long long unsigned int ); 1901 1874 \end{lstlisting} 1902 For every extended integer type \lstinline$X$ with \Index{integer conversion rank} greater than the rank of \lstinline$int$there exist1875 For every extended integer type ©X© with \Index{integer conversion rank} greater than the rank of ©int© there exist 1903 1876 % Don't use predefined: keep this out of prelude.cf. 1904 1877 \begin{lstlisting} … … 1915 1888 \lhs{logical-AND-expression} 1916 1889 \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} 1918 1891 \end{syntax} 1919 1892 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. 1894 The expression has only one interpretation, which is of type ©int©. 1895 \begin{rationale} 1896 When 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 1898 A common C idiom omits comparisons to ©0© in the controlling expressions of loops and ©if© statements. 1899 For instance, the loop below iterates as long as ©rp© points at a ©Rational© value that is non-zero. 1900 1901 \begin{lstlisting} 1902 extern otype Rational;§\use{Rational}§ 1903 extern const Rational 0;§\use{0}§ 1933 1904 extern int ?!=?( Rational, Rational ); 1934 1905 Rational *rp; 1935 1906 while ( rp && *rp ) { ... } 1936 1907 \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.1908 The logical expression calls the ©Rational© inequality operator, passing it ©*rp© and the ©Rational 0©, and getting a 1 or 0 as a result. 1909 In contrast, {\CC} would apply a programmer-defined ©Rational©-to-©int© conversion to ©*rp© in the equivalent situation. 1910 The 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. 1940 1911 \end{rationale} 1941 1912 … … 1946 1917 \lhs{logical-OR-expression} 1947 1918 \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} 1949 1920 \end{syntax} 1950 1921 1951 1922 \semantics 1952 1923 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$.1924 The operands of the expression ``©a || b©'' are treated as ``©(int)((a)!=0)©'' and ``©(int)((b))!=0)©'', which shall both be unambiguous. 1925 The expression has only one interpretation, which is of type ©int©. 1955 1926 1956 1927 … … 1960 1931 \lhs{conditional-expression} 1961 1932 \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} 1964 1935 \end{syntax} 1965 1936 1966 1937 \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 to1938 In 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 1968 1939 \begin{lstlisting} 1969 1940 ( int)(( a)!=0) ? ( void)( b) : ( void)( c) 1970 1941 \end{lstlisting} 1971 1942 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 as1943 If 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 1973 1944 \begin{lstlisting} 1974 1945 forall( otype T ) T cond( int, T, T ); … … 2022 1993 rand() ? i : l; 2023 1994 \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$. 1995 The best interpretation infers the expression's type to be ©long© and applies the safe ©int©-to-©long© conversion to ©i©. 2026 1996 2027 1997 \begin{lstlisting} … … 2030 2000 rand() ? cip : vip; 2031 2001 \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.2002 The expression has type ©const volatile int *©, with safe conversions applied to the second and third operands to add ©volatile© and ©const© qualifiers, respectively. 2033 2003 2034 2004 \begin{lstlisting} 2035 2005 rand() ? cip : 0; 2036 2006 \end{lstlisting} 2037 The expression has type \lstinline$const int *$, with a specialization conversion applied to 2038 \lstinline$0$. 2007 The expression has type ©const int *©, with a specialization conversion applied to ©0©. 2039 2008 2040 2009 … … 2047 2016 \nonterm{assignment-expression} 2048 2017 \lhs{assignment-operator} one of 2049 \rhs \lstinline$=$\ \ \lstinline$*=$\ \ \lstinline$/=$\ \ \lstinline$%=$\ \ \lstinline$+=$\ \ \lstinline$-=$\ \ 2050 \lstinline$<<=$\ \ \lstinline$>>=$\ \ \lstinline$&=$\ \ \lstinline$^=$\ \ \lstinline$|=$ 2018 \rhs ©=©\ \ ©*=©\ \ ©/=©\ \ ©%=©\ \ ©+=©\ \ ©-=©\ \ ©<<=©\ \ ©>>=©\ \ ©&=©\ \ ©^=©\ \ ©|=© 2051 2019 \end{syntax} 2052 2020 2053 2021 \rewriterules 2054 Let `` \(\leftarrow\)'' be any of the assignment operators.2022 Let ``©<-©'' be any of the assignment operators. 2055 2023 Then 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} 2026 a <- b => ?<-?( &( a ), b ) 2060 2027 \end{lstlisting} 2061 2028 2062 2029 \semantics 2063 2030 Each 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.2031 For 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. 2065 2032 The right operand is cast to that type, and the assignment expression is ambiguous if either operand is. 2066 2033 For the remaining interpretations, the expression is rewritten, and the interpretations of the assignment expression are the interpretations of the corresponding function call. … … 2295 2262 \end{lstlisting} 2296 2263 \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 exist2264 The 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 2267 For every complete structure or union type ©S© there exist 2301 2268 % Don't use predefined: keep this out of prelude.cf. 2302 2269 \begin{lstlisting} … … 2304 2271 \end{lstlisting} 2305 2272 2306 For every extended integer type \lstinline$X$there exist2273 For every extended integer type ©X© there exist 2307 2274 % Don't use predefined: keep this out of prelude.cf. 2308 2275 \begin{lstlisting} … … 2310 2277 \end{lstlisting} 2311 2278 2312 For every complete enumerated type \lstinline$E$there exist2279 For every complete enumerated type ©E© there exist 2313 2280 % Don't use predefined: keep this out of prelude.cf. 2314 2281 \begin{lstlisting} … … 2316 2283 \end{lstlisting} 2317 2284 \begin{rationale} 2318 The right-hand argument is \lstinline$int$ because enumeration constants have type \lstinline$int$.2285 The right-hand argument is ©int© because enumeration constants have type ©int©. 2319 2286 \end{rationale} 2320 2287 … … 2577 2544 \end{lstlisting} 2578 2545 2579 For every extended integer type \lstinline$X$there exist2546 For every extended integer type ©X© there exist 2580 2547 % Don't use predefined: keep this out of prelude.cf. 2581 2548 \begin{lstlisting} … … 2592 2559 \end{lstlisting} 2593 2560 2594 For every complete enumerated type \lstinline$E$there exist2561 For every complete enumerated type ©E© there exist 2595 2562 % Don't use predefined: keep this out of prelude.cf. 2596 2563 \begin{lstlisting} … … 2613 2580 \lhs{expression} 2614 2581 \rhs \nonterm{assignment-expression} 2615 \rhs \nonterm{expression} \lstinline$,$\nonterm{assignment-expression}2582 \rhs \nonterm{expression} ©,© \nonterm{assignment-expression} 2616 2583 \end{syntax} 2617 2584 2618 2585 \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}. 2586 In the comma expression ``©a, b©'', the first operand is interpreted as ``©( void )(a)©'', which shall be unambiguous\index{ambiguous interpretation}. 2621 2587 The interpretations of the expression are the interpretations of the second operand. 2622 2588 … … 2653 2619 { ... } 2654 2620 \end{lstlisting} 2655 Without the rule, \lstinline$Complex$would be a type in the first case, and a parameter name in the second.2621 Without the rule, ©Complex© would be a type in the first case, and a parameter name in the second. 2656 2622 \end{rationale} 2657 2623 … … 2679 2645 \examples 2680 2646 \begin{lstlisting} 2681 struct point { @\impl{point}@2647 struct point {§\impl{point}§ 2682 2648 int x, y; 2683 2649 }; 2684 struct color_point { @\impl{color_point}@2650 struct color_point {§\impl{color_point}§ 2685 2651 enum { RED, BLUE, GREEN } color; 2686 2652 struct point; … … 2689 2655 cp.x = 0; 2690 2656 cp.color = RED; 2691 struct literal { @\impl{literal}@2657 struct literal {§\impl{literal}§ 2692 2658 enum { NUMBER, STRING } tag; 2693 2659 union { … … 2710 2676 \begin{syntax} 2711 2677 \lhs{forall-specifier} 2712 \rhs \lstinline$forall$ \lstinline$($ \nonterm{type-parameter-list} \lstinline$)$2678 \rhs ©forall© ©(© \nonterm{type-parameter-list} ©)© 2713 2679 \end{syntax} 2714 2680 … … 2722 2688 } mkPair( T, T ); // illegal 2723 2689 \end{lstlisting} 2724 If an instance of \lstinline$struct Pair$was declared later in the current scope, what would the members' type be?2690 If an instance of ©struct Pair© was declared later in the current scope, what would the members' type be? 2725 2691 \end{rationale} 2726 2692 \end{comment} … … 2729 2695 The \nonterm{type-parameter-list}s and assertions of the \nonterm{forall-specifier}s declare type identifiers, function and object identifiers with \Index{no linkage}. 2730 2696 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. 2697 If, in the declaration ``©T D©'', ©T© contains \nonterm{forall-specifier}s and ©D© has the form 2698 \begin{lstlisting} 2699 D( §\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. 2738 2702 The identifiers declared by assertions that use an inferred parameter of a function declarator are \Index{assertion parameter}s of that function declarator. 2739 2703 … … 2744 2708 If this restriction were lifted, it would be possible to write 2745 2709 \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}@ 2710 forall( otype T ) T * alloc( void );§\use{alloc}§ int *p = alloc(); 2711 \end{lstlisting} 2712 Here ©alloc()© would receive ©int© as an inferred argument, and return an ©int *©. 2713 In 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 2715 With the current restriction, ©alloc()© must be given an argument that determines ©T©: 2716 \begin{lstlisting} 2717 forall( otype T ) T * alloc( T initial_value );§\use{alloc}§ 2756 2718 \end{lstlisting} 2757 2719 \end{rationale} … … 2759 2721 2760 2722 If 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}. 2723 otherwise, identifiers declared by assertions have a \define{declaration scope}, which terminates at the end of the \nonterm{declaration}. 2763 2724 2764 2725 A function type that has at least one inferred parameter is a \define{polymorphic function} type. … … 2769 2730 Let $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. 2770 2731 Let $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. 2732 Then $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. 2773 2733 2774 2734 \examples … … 2778 2738 forall( otype T ) T fT( T ); 2779 2739 \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©. 2782 2741 \begin{lstlisting} 2783 2742 int (*pfi )( int ) = fi; 2784 2743 forall( otype T ) T (*pfT )( T ) = fT; 2785 2744 \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. 2787 2746 \begin{lstlisting} 2788 2747 int (*fvpfi( void ))( int ) { … … 2793 2752 } 2794 2753 \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. 2796 2755 \begin{lstlisting} 2797 2756 forall( otype T ) int ( *fTpfi( T ) )( int ); … … 2799 2758 forall( otype T, otype U ) U ( *fTpfU( T ) )( U ); 2800 2759 \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. 2761 It 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()©. 2763 For 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 *©. 2808 2765 \begin{lstlisting} 2809 2766 forall( otype T, otype U, otype V ) U * f( T *, U, V * const ); 2810 2767 forall( otype U, otype V, otype W ) U * g( V *, U, W * const ); 2811 2768 \end{lstlisting} 2812 The functions \lstinline$f()$ and \lstinline$g()$have compatible types.2769 The functions ©f()© and ©g()© have compatible types. 2813 2770 Let \(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$.2771 then \(f_1\) = ©T©, \(f_2\) = ©U©, \(f_3\) = ©V©, \(g_1\) 2772 = ©V©, \(g_2\) = ©U©, and \(g_3\) = ©W©. 2816 2773 Replacing every \(f_i\) by \(g_i\) in \(f\) gives 2817 2774 \begin{lstlisting} … … 2819 2776 \end{lstlisting} which has a return type and parameter list that is compatible with \(g\). 2820 2777 \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.2778 The 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. 2822 2779 2823 2780 Even without parameterized types, I might try to allow … … 2845 2802 \subsection{Type qualifiers} 2846 2803 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}. 2848 2805 \begin{syntax} 2849 2806 \oldlhs{type-qualifier} 2850 \rhs \lstinline$lvalue$2807 \rhs ©lvalue© 2851 2808 \end{syntax} 2852 2809 2853 2810 \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. 2855 2812 2856 2813 \semantics 2857 An object's type may be a restrict-qualified type parameter. \lstinline$restrict$ does not establish any special semantics in that case. 2814 An object's type may be a restrict-qualified type parameter. 2815 ©restrict© does not establish any special semantics in that case. 2858 2816 2859 2817 \begin{rationale} … … 2861 2819 \end{rationale} 2862 2820 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. 2822 Let ©T© be an unqualified version of a type; 2823 then 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} 2826 The ©const© and ©volatile© qualifiers can only be sensibly used to qualify the return type of a function if the ©lvalue© qualifier is also used. 2870 2827 \end{rationale} 2871 2828 … … 2874 2831 2875 2832 \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. 2877 2834 Reference types have four uses in {\CC}. 2878 2835 \begin{itemize} 2879 2836 \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. 2837 They are necessary for user-defined operators that return lvalues, such as ``subscript'' and ``dereference''. 2838 2839 \item 2840 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 ©with© statement. 2885 2841 The following {\CC} code gives an example. 2886 2842 \begin{lstlisting} … … 2895 2851 A reference parameter can be used to allow a function to modify an argument without forcing the caller to pass the address of the argument. 2896 2852 This is most useful for user-defined assignment operators. 2897 In {\CC}, plain assignment is done by a function called `` \lstinline$operator=$'', and the two expressions2853 In {\CC}, plain assignment is done by a function called ``©operator=©'', and the two expressions 2898 2854 \begin{lstlisting} 2899 2855 a = b; 2900 2856 operator=( a, b ); 2901 2857 \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$&$''. 2858 If ©a© and ©b© are of type ©T©, then the first parameter of ©operator=© must have type ``©T&©''. 2859 It 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 2861 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 ``©a = b;©'' is equivalent to ``©operator=(&( a), b )©''. 2862 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 ``©&©''. 2910 2863 2911 2864 \item 2912 2865 References 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$is2914 \lstinline$Thing$, the type of \lstinline$fiddle$could be either of2866 {\CC} function call ``©fiddle( a_thing )©'', where the type of ©a_thing© is 2867 ©Thing©, the type of ©fiddle© could be either of 2915 2868 \begin{lstlisting} 2916 2869 void fiddle( Thing ); 2917 2870 void fiddle( const Thing & ); 2918 2871 \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.2872 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 ©fiddle© the parameter is subject to the usual problems caused by aliases. 2873 The reference form might be chosen for efficiency's sake if ©Thing©s are too large or their constructors or destructors are too expensive. 2921 2874 An implementation may switch between them without causing trouble for well-behaved clients. 2922 2875 This leaves the implementor to define ``too large'' and ``too expensive''. … … 2926 2879 void fiddle( const volatile Thing ); 2927 2880 \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''.2881 Since 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''. 2929 2882 \end{itemize} 2930 2883 … … 2946 2899 \begin{syntax} 2947 2900 \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 ©}© 2951 2904 \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} ©;© 2954 2907 \lhs{spec-declaration} 2955 2908 \rhs \nonterm{specifier-qualifier-list} \nonterm{declarator-list} 2956 2909 \lhs{declarator-list} 2957 2910 \rhs \nonterm{declarator} 2958 \rhs \nonterm{declarator-list} \lstinline$,$\nonterm{declarator}2911 \rhs \nonterm{declarator-list} ©,© \nonterm{declarator} 2959 2912 \end{syntax} 2960 2913 \begin{rationale} … … 2978 2931 \rhs \nonterm{assertion-list} \nonterm{assertion} 2979 2932 \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} 2982 2935 \lhs{type-name-list} 2983 2936 \rhs \nonterm{type-name} 2984 \rhs \nonterm{type-name-list} \lstinline$,$\nonterm{type-name}2937 \rhs \nonterm{type-name-list} ©,© \nonterm{type-name} 2985 2938 \end{syntax} 2986 2939 … … 2989 2942 The \nonterm{type-name-list} shall contain one \nonterm{type-name} argument for each \nonterm{type-parameter} in that specification's \nonterm{spec-parameter-list}. 2990 2943 If 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}; 2945 if it uses ©dtype©, the argument shall be the type name of an object type or an \Index{incomplete type}; 2946 and if it uses ©ftype©, the argument shall be the type name of a \Index{function type}. 2994 2947 2995 2948 \semantics 2996 An \define{assertion} is a declaration of a collection of objects and functions, called 2997 \define{assertion parameters}. 2949 An \define{assertion} is a declaration of a collection of objects and functions, called \define{assertion parameters}. 2998 2950 2999 2951 The 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. … … 3004 2956 \examples 3005 2957 \begin{lstlisting} 3006 forall( otype T | T ?*?( T, T )) @\use{?*?}@3007 T square( T val ) { @\impl{square}@2958 forall( otype T | T ?*?( T, T ))§\use{?*?}§ 2959 T square( T val ) {§\impl{square}§ 3008 2960 return val + val; 3009 2961 } 3010 trait summable( otype T ) { @\impl{summable}@3011 T ?+=?( T *, T ); @\use{?+=?}@3012 const T 0; @\use{0}@2962 trait summable( otype T ) {§\impl{summable}§ 2963 T ?+=?( T *, T );§\use{?+=?}§ 2964 const T 0;§\use{0}§ 3013 2965 }; 3014 trait list_of( otype List, otype Element ) { @\impl{list_of}@2966 trait list_of( otype List, otype Element ) {§\impl{list_of}§ 3015 2967 Element car( List ); 3016 2968 List cdr( List ); … … 3021 2973 trait sum_list( otype List, otype Element | summable( Element ) | list_of( List, Element ) ) {}; 3022 2974 \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 parameters2975 ©sum_list© contains seven declarations, which describe a list whose elements can be added up. 2976 The assertion ``©|sum_list( i_list, int )©''\use{sum_list} produces the assertion parameters 3025 2977 \begin{lstlisting} 3026 2978 int ?+=?( int *, int ); … … 3039 2991 \lhs{type-parameter-list} 3040 2992 \rhs \nonterm{type-parameter} 3041 \rhs \nonterm{type-parameter-list} \lstinline$,$\nonterm{type-parameter}2993 \rhs \nonterm{type-parameter-list} ©,© \nonterm{type-parameter} 3042 2994 \lhs{type-parameter} 3043 2995 \rhs \nonterm{type-class} \nonterm{identifier} \nonterm{assertion-list}\opt 3044 2996 \lhs{type-class} 3045 \rhs \lstinline$type$3046 \rhs \lstinline$dtype$3047 \rhs \lstinline$ftype$2997 \rhs ©type© 2998 \rhs ©dtype© 2999 \rhs ©ftype© 3048 3000 \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|;| 3050 3002 \lhs{type-declarator-list} 3051 3003 \rhs \nonterm{type-declarator} 3052 \rhs \nonterm{type-declarator-list} \lstinline$,$\nonterm{type-declarator}3004 \rhs \nonterm{type-declarator-list} ©,© \nonterm{type-declarator} 3053 3005 \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} 3055 3007 \rhs \nonterm{identifier} \nonterm{assertion-list}\opt 3056 3008 \end{syntax} … … 3063 3015 3064 3016 An 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. 3017 Identifiers declared with type-class ©type©\use{type} are \Index{object type}s; 3018 those declared with type-class ©dtype©\use{dtype} are \Index{incomplete type}s; 3019 and those declared with type-class ©ftype©\use{ftype} are \Index{function type}s. 3070 3020 The 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}. 3071 3021 … … 3075 3025 Within 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. 3076 3026 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). 3027 A 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}. 3028 If 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). 3080 3029 \begin{rationale} 3081 3030 Incomplete type declarations allow compact mutually-recursive types. … … 3094 3043 \end{rationale} 3095 3044 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. 3045 A type declaration without an initializer and with \Index{storage-class specifier} ©extern©\use{extern} is an \define{opaque type declaration}. 3046 Opaque types are \Index{object type}s. 3100 3047 An 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 other3102 \Index{object type} is a \nonterm{constant-expression}.3048 neither is a structure or union that has a member whose type is not a \nonterm{constant-expression}. 3049 Every other \Index{object type} is a \nonterm{constant-expression}. 3103 3050 Objects with static storage duration shall be declared with a type that is a \nonterm{constant-expression}. 3104 3051 \begin{rationale} … … 3110 3057 \end{rationale} 3111 3058 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$. 3059 An \Index{incomplete type} which is not a qualified version\index{qualified type} of a type is a value of \Index{type-class} ©dtype©. 3060 An object type\index{object types} which is not a qualified version of a type is a value of type-classes ©type© and ©dtype©. 3061 A \Index{function type} is a value of type-class ©ftype©. 3116 3062 \begin{rationale} 3117 3063 Syntactically, a type value is a \nonterm{type-name}, which is a declaration for an object which omits the identifier being declared. … … 3122 3068 3123 3069 Type 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}@ 3070 Consider 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} 3072 char *strchr( const char *s, int c ) {§\impl{strchr}§ 3128 3073 char real_c = c; // done because c was declared as int. 3129 3074 for ( ; *s != real_c; s++ ) … … 3132 3077 } 3133 3078 \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. 3079 The 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. 3080 Hence the body must perform a cast, and ( even worse) ©strchr()© provides a type-safe way to attempt to modify constant strings. 3081 What is needed is some way to say that ©s©'s type might contain qualifiers, and the result type has exactly the same qualifiers. 3138 3082 Polymorphic 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.3083 Instead, overloading can be used to define ©strchr()© for each combination of qualifiers. 3140 3084 \end{rationale} 3141 3085 … … 3161 3105 }; 3162 3106 \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$. 3107 Without 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©. 3165 3108 3166 3109 A 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. … … 3168 3111 // File a.c: 3169 3112 extern type t1; 3170 type t2 = struct { t1 f1; ... } // illegal3113 type t2 = struct { t1 f1; ... } // illegal 3171 3114 // File b.c: 3172 3115 extern type t2; 3173 type t1 = struct { t2 f2; ... } // illegal3116 type t1 = struct { t2 f2; ... } // illegal 3174 3117 \end{lstlisting} 3175 3118 \end{rationale} … … 3179 3122 \nonterm{struct-declaration}, type declarations can not be structure members. 3180 3123 The 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©. 3182 3125 Hence the syntax of \nonterm{type-specifier} does not have to be extended to allow type-valued expressions. 3183 3126 It also side-steps the problem of type-valued expressions producing different values in different declarations. … … 3194 3137 #include <stdlib.h> 3195 3138 T * 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} 3141 This 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©; 3199 3142 it could be undefined, or a type name, or a function or variable name. 3200 3143 Nothing good can result from such a situation. … … 3213 3156 f2( v2 ); 3214 3157 \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]©. 3216 3159 3217 3160 A translation unit containing the declarations 3218 3161 \begin{lstlisting} 3219 extern type Complex; @\use{Complex}@// opaque type declaration3220 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$.3162 extern type Complex;§\use{Complex}§ // opaque type declaration 3163 extern float abs( Complex );§\use{abs}§ 3164 \end{lstlisting} can contain declarations of complex numbers, which can be passed to ©abs©. 3165 Some other translation unit must implement ©Complex© and ©abs©. 3223 3166 That unit might contain the declarations 3224 3167 \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 )}@3168 otype Complex = struct { float re, im; };§\impl{Complex}§ 3169 Complex cplx_i = { 0.0, 1.0 };§\impl{cplx_i}§ 3170 float abs( Complex c ) {§\impl{abs( Complex )}§ 3228 3171 return sqrt( c.re * c.re + c.im * c.im ); 3229 3172 } 3230 3173 \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{?+?}@3174 Note that ©c© is implicitly converted to a ©struct© so that its components can be retrieved. 3175 3176 \begin{lstlisting} 3177 otype Time_of_day = int;§\impl{Time_of_day}§ // seconds since midnight. 3178 Time_of_day ?+?( Time_of_day t1, int seconds ) {§\impl{?+?}§ 3236 3179 return (( int)t1 + seconds ) % 86400; 3237 3180 } 3238 3181 \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. 3240 3183 3241 3184 \begin{rationale} 3242 3185 Within 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.3186 In the ©Time_of_day© example, the difference is important. 3244 3187 Different languages have treated the distinction between the abstraction and the implementation in different ways. 3245 3188 \begin{itemize} 3246 3189 \item 3247 3190 Inside 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.3191 Two primitives called ©up© and ©down© can be used to convert between the views. 3249 3192 \item 3250 3193 The Simula class \cite{SIMULA87} is essentially a record type. 3251 3194 Since 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. 3252 3195 In {\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. 3254 3197 A ``scope resolution'' operator can be used inside the class to specify whether the abstract or implementation version of the operation should be used. 3255 3198 \item … … 3264 3207 In this case, explicit conversions between the derived type and the old type can be used. 3265 3208 \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©. 3267 3210 \end{rationale} 3268 3211 … … 3270 3213 \subsubsection{Default functions and objects} 3271 3214 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$. 3215 A 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©. 3275 3216 \begin{rationale} 3276 3217 Assignment 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). 3277 3218 Without 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. 3219 If a type parameter should not have an assignment operation, ©dtype© should be used. 3280 3220 If 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. 3281 3221 \end{rationale} 3282 3222 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$. 3223 A definition\index{type definition} of a type identifier ©T© with \Index{implementation type} ©I© and type-class ©type© implicitly defines a default assignment function. 3224 A 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. 3225 The default objects and functions have the same \Index{scope} and \Index{linkage} as the identifier ©T©. 3287 3226 Their values are determined as follows: 3288 3227 \begin{itemize} 3289 3228 \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.3229 If 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. 3230 Otherwise the scope of the declaration of ©T© must contain a definition of the default object. 3292 3231 3293 3232 \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.3233 If 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 3235 Otherwise, 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 3237 Otherwise the scope of the declaration of ©T© must contain a definition of the default function. 3299 3238 \end{itemize} 3300 3239 \begin{rationale} … … 3302 3241 \end{rationale} 3303 3242 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.3243 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 ©T© replaces the default function or object. 3305 3244 3306 3245 \examples … … 3312 3251 Pair b = { 1, 1 }; 3313 3252 \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. 3253 The definition of ©Pair© implicitly defines two objects ©a© and ©b©. 3254 ©Pair a© inherits its value from the ©struct impl a©. 3255 The definition of ©Pair b© is compulsory because there is no ©struct impl b© to construct a value from. 3318 3256 \begin{lstlisting} 3319 3257 trait ss( otype T ) { … … 3321 3259 void munge( T * ); 3322 3260 } 3323 otype Whatsit | ss( Whatsit ); @\use{Whatsit}@3324 otype Doodad | ss( Doodad ) = struct doodad { @\use{Doodad}@3261 otype Whatsit | ss( Whatsit );§\use{Whatsit}§ 3262 otype Doodad | ss( Doodad ) = struct doodad {§\use{Doodad}§ 3325 3263 Whatsit; // anonymous member 3326 3264 int extra; … … 3328 3266 Doodad clone( Doodad ) { ... } 3329 3267 \end{lstlisting} 3330 The definition of \lstinline$Doodad$implicitly defines three functions:3268 The definition of ©Doodad© implicitly defines three functions: 3331 3269 \begin{lstlisting} 3332 3270 Doodad ?=?( Doodad *, Doodad ); … … 3334 3272 void munge( Doodad * ); 3335 3273 \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. 3274 The 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. 3276 Hence the definition of ``©Doodad clone( Doodad )©'' is necessary. 3342 3277 3343 3278 Default functions and objects are subject to the normal scope rules. 3344 3279 \begin{lstlisting} 3345 otype T = @\ldots@;3346 T a_T = @\ldots@; // Default assignment used.3280 otype T = ...; 3281 T a_T = ...; // Default assignment used. 3347 3282 T ?=?( T *, T ); 3348 T a_T = @\ldots@; // Programmer-defined assignment called.3283 T a_T = ...; // Programmer-defined assignment called. 3349 3284 \end{lstlisting} 3350 3285 \begin{rationale} … … 3379 3314 \begin{syntax} 3380 3315 \oldlhs{labeled-statement} 3381 \rhs \lstinline$case$\nonterm{case-value-list} : \nonterm{statement}3316 \rhs ©case© \nonterm{case-value-list} : \nonterm{statement} 3382 3317 \lhs{case-value-list} 3383 3318 \rhs \nonterm{case-value} 3384 \rhs \nonterm{case-value-list} \lstinline$,$\nonterm{case-value}3319 \rhs \nonterm{case-value-list} ©,© \nonterm{case-value} 3385 3320 \lhs{case-value} 3386 3321 \rhs \nonterm{constant-expression} 3387 3322 \rhs \nonterm{subrange} 3388 3323 \lhs{subrange} 3389 \rhs \nonterm{constant-expression} \lstinline$~$\nonterm{constant-expression}3324 \rhs \nonterm{constant-expression} ©~© \nonterm{constant-expression} 3390 3325 \end{syntax} 3391 3326 … … 3400 3335 case 1~4, 9~14, 27~32: 3401 3336 \end{lstlisting} 3402 The \lstinline$case$ and \lstinline$default$ clauses are restricted within the \lstinline$switch$ and \lstinline$choose$statements, precluding Duff's device.3337 The ©case© and ©default© clauses are restricted within the ©switch© and ©choose© statements, precluding Duff's device. 3403 3338 3404 3339 3405 3340 \subsection{Expression and null statements} 3406 3341 3407 The expression in an expression statement is treated as being cast to \lstinline$void$.3342 The expression in an expression statement is treated as being cast to ©void©. 3408 3343 3409 3344 … … 3412 3347 \begin{syntax} 3413 3348 \oldlhs{selection-statement} 3414 \rhs \lstinline$choose$ \lstinline$($ \nonterm{expression} \lstinline$)$\nonterm{statement}3349 \rhs ©choose© ©(© \nonterm{expression} ©)© \nonterm{statement} 3415 3350 \end{syntax} 3416 3351 3417 The controlling expression \lstinline$E$ in the \lstinline$switch$ and \lstinline$choose$statement:3352 The controlling expression ©E© in the ©switch© and ©choose© statement: 3418 3353 \begin{lstlisting} 3419 3354 switch ( E ) ... … … 3421 3356 \end{lstlisting} may have more than one interpretation, but it shall have only one interpretation with an integral type. 3422 3357 An \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.3358 The constant expressions in ©case© statements with the switch are converted to the promoted type. 3424 3359 3425 3360 3426 3361 \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 3364 The ©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. 3365 The ©fallthru© statement is used to fall through to the next ©case© or ©default© labeled statement. 3431 3366 The following have identical meaning: 3432 3367 \begin{flushleft} … … 3453 3388 \end{tabular} 3454 3389 \end{flushleft} 3455 The \lstinline$choose$ statement addresses the problem of accidental fall-through associated with the \lstinline$switch$statement.3390 The ©choose© statement addresses the problem of accidental fall-through associated with the ©switch© statement. 3456 3391 3457 3392 3458 3393 \subsection{Iteration statements} 3459 3394 3460 The controlling expression \lstinline$E$in the loops3395 The controlling expression ©E© in the loops 3461 3396 \begin{lstlisting} 3462 3397 if ( E ) ... 3463 3398 while ( E ) ... 3464 3399 do ... while ( E ); 3465 \end{lstlisting} is treated as ``\lstinline$( int )((E)!=0)$''. 3400 \end{lstlisting} 3401 is treated as ``©( int )((E)!=0)©''. 3466 3402 3467 3403 The statement 3468 3404 \begin{lstlisting} 3469 for ( a; b; c ) @\ldots@3405 for ( a; b; c ) ... 3470 3406 \end{lstlisting} is treated as 3471 3407 \begin{lstlisting} … … 3478 3414 \begin{syntax} 3479 3415 \oldlhs{jump-statement} 3480 \rhs \lstinline$continue$\nonterm{identifier}\opt3481 \rhs \lstinline$break$\nonterm{identifier}\opt3416 \rhs ©continue© \nonterm{identifier}\opt 3417 \rhs ©break© \nonterm{identifier}\opt 3482 3418 \rhs \ldots 3483 \rhs \lstinline$throw$\nonterm{assignment-expression}\opt3484 \rhs \lstinline$throwResume$\nonterm{assignment-expression}\opt \nonterm{at-expression}\opt3485 \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} 3486 3422 \end{syntax} 3487 3423 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.3424 Labeled ©continue© and ©break© allow useful but restricted control-flow that reduces the need for the ©goto© statement for exiting multiple nested control-structures. 3489 3425 \begin{lstlisting} 3490 3426 L1: { // compound … … 3513 3449 3514 3450 \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 3453 The 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 3458 The 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 3463 An 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} 3531 3467 3532 3468 When an exception is raised, \Index{propagation} directs control from a raise in the source execution to a handler in the faulting execution. 3533 3469 3534 3470 3535 \subsubsection {The \lstinline$throwResume$statement}3471 \subsubsection[The throwResume statement]{The \lstinline@throwResume@ statement} 3536 3472 3537 3473 … … 3540 3476 \begin{syntax} 3541 3477 \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} 3545 3481 \lhs{handler-list} 3546 3482 \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} 3551 3487 \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} 3556 3492 \lhs{finally-clause} 3557 \rhs \lstinline$finally$\nonterm{compound-statement}3493 \rhs ©finally© \nonterm{compound-statement} 3558 3494 \lhs{exception-declaration} 3559 3495 \rhs \nonterm{type-specifier} … … 3563 3499 \rhs \nonterm{new-abstract-declarator-tuple} 3564 3500 \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} 3567 3503 \end{syntax} 3568 3504 … … 3570 3506 3571 3507 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 3510 The ©try© statement is a block with associated handlers, called a \Index{guarded block}; 3575 3511 all 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.3512 A ©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 3517 The ©enable©/©disable© statements toggle delivery of \Index{asynchronous exception}s. 3582 3518 3583 3519 … … 3589 3525 \subsection{Predefined macro names} 3590 3526 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. 3527 The implementation shall define the macro names ©__LINE__©, ©__FILE__©, ©__DATE__©, and ©__TIME__©, as in the {\c11} standard. 3528 It shall not define the macro name ©__STDC__©. 3529 3530 In addition, the implementation shall define the macro name ©__CFORALL__© to be the decimal constant 1. 3596 3531 3597 3532 … … 3610 3545 The pointer, integral, and floating-point types are all \define{scalar types}. 3611 3546 All 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}@3547 The assertion ``©scalar( Complex )©'' should be read as ``type ©Complex© is scalar''. 3548 \begin{lstlisting} 3549 trait scalar( otype T ) {§\impl{scalar}§ 3615 3550 int !?( T ); 3616 3551 int ?<?( T, T ), ?<=?( T, T ), ?==?( T, T ), ?>=?( T, T ), ?>?( T, T ), ?!=?( T, T ); … … 3622 3557 This is equivalent to inheritance of specifications. 3623 3558 \begin{lstlisting} 3624 trait arithmetic( otype T | scalar( T ) ) { @\impl{arithmetic}@@\use{scalar}@3559 trait arithmetic( otype T | scalar( T ) ) {§\impl{arithmetic}§§\use{scalar}§ 3625 3560 T +?( T ), -?( T ); 3626 3561 T ?*?( T, T ), ?/?( T, T ), ?+?( T, T ), ?-?( T, T ); … … 3628 3563 \end{lstlisting} 3629 3564 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}@ 3565 The various flavors of ©char© and ©int© and the enumerated types make up the \define{integral types}. 3566 \begin{lstlisting} 3567 trait integral( otype T | arithmetic( T ) ) {§\impl{integral}§§\use{arithmetic}§ 3634 3568 T ~?( T ); 3635 3569 T ?&?( T, T ), ?|?( T, T ), ?^?( T, T ); … … 3645 3579 The only operation that can be applied to all modifiable lvalues is simple assignment. 3646 3580 \begin{lstlisting} 3647 trait m_lvalue( otype T ) { @\impl{m_lvalue}@3581 trait m_lvalue( otype T ) {§\impl{m_lvalue}§ 3648 3582 T ?=?( T *, T ); 3649 3583 }; … … 3655 3589 Scalars can also be incremented and decremented. 3656 3590 \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}@3591 trait m_l_scalar( otype T | scalar( T ) | m_lvalue( T ) ) {§\impl{m_l_scalar}§ 3592 T ?++( T * ), ?--( T * );§\use{scalar}§§\use{m_lvalue}§ 3659 3593 T ++?( T * ), --?( T * ); 3660 3594 }; … … 3662 3596 3663 3597 Modifiable 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}@3598 Note that this results in the ``inheritance'' of ©scalar© along both paths. 3599 \begin{lstlisting} 3600 trait 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}§ 3668 3602 T ?+=?( T *, T ), ?-=?( T *, T ); 3669 3603 }; 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}@3604 trait 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}§ 3673 3607 }; 3674 3608 \end{lstlisting} … … 3677 3611 \subsection{Pointer and array types} 3678 3612 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. 3613 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 ``©a[i]©'' is equivalent to the dereferencing expression ``©(*( a+( i )))©''. 3614 Technically, 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. 3683 3615 Consequently, there is no need for a separate ``array type'' specification. 3684 3616 3685 3617 Pointer 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}@ 3618 Like 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} 3620 trait pointer( type P | scalar( P ) ) {§\impl{pointer}§§\use{scalar}§ 3691 3621 P ?+?( P, long int ), ?+?( long int, P ), ?-?( P, long int ); 3692 3622 ptrdiff_t ?-?( P, P ); 3693 3623 }; 3694 trait m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) { @\impl{m_l_pointer}@3624 trait m_l_pointer( type P | pointer( P ) | m_l_scalar( P ) ) {§\impl{m_l_pointer}§ 3695 3625 P ?+=?( P *, long int ), ?-=?( P *, long int ); 3696 3626 P ?=?( P *, void * ); … … 3701 3631 Specifications 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. 3702 3632 Different 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}@ 3633 The assertion ``©|ptr_to( Safe_pointer, int )©'' should be read as ``©Safe_pointer© acts like a pointer to ©int©''. 3634 \begin{lstlisting} 3635 trait ptr_to( otype P | pointer( P ), otype T ) {§\impl{ptr_to}§§\use{pointer}§ 3707 3636 lvalue T *?( P ); 3708 3637 lvalue T ?[?]( P, long int ); 3709 3638 }; 3710 trait ptr_to_const( otype P | pointer( P ), otype T ) { @\impl{ptr_to_const}@3639 trait ptr_to_const( otype P | pointer( P ), otype T ) {§\impl{ptr_to_const}§ 3711 3640 const lvalue T *?( P ); 3712 const lvalue T ?[?]( P, long int ); @\use{pointer}@3641 const lvalue T ?[?]( P, long int );§\use{pointer}§ 3713 3642 }; 3714 trait ptr_to_volatile( otype P | pointer( P ), otype T ) } @\impl{ptr_to_volatile}@3643 trait ptr_to_volatile( otype P | pointer( P ), otype T ) }§\impl{ptr_to_volatile}§ 3715 3644 volatile lvalue T *?( P ); 3716 volatile lvalue T ?[?]( P, long int ); @\use{pointer}@3645 volatile lvalue T ?[?]( P, long int );§\use{pointer}§ 3717 3646 }; 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}@3647 trait ptr_to_const_volatile( otype P | pointer( P ), otype T ) }§\impl{ptr_to_const_volatile}§ 3648 const volatile lvalue T *?( P );§\use{pointer}§ 3720 3649 const volatile lvalue T ?[?]( P, long int ); 3721 3650 }; 3722 3651 \end{lstlisting} 3723 3652 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}@ { 3653 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 ``©T *©'' can be assigned to a ``©const T *©'', a ``©volatile T *©'', and a ``©const volatile T *©''. 3654 Again, the pointed-at type is passed in, so that assertions can connect these specifications to the ``©ptr_to©'' specifications. 3655 \begin{lstlisting} 3656 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}§ { 3729 3657 P ?=?( P *, T * ); 3730 3658 T * ?=?( T **, P ); 3731 3659 }; 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}@) {3660 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}§) { 3733 3661 P ?=?( P *, const T * ); 3734 3662 const T * ?=?( const T **, P ); 3735 3663 }; 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}@3664 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}§ 3737 3665 P ?=?( P *, volatile T * ); 3738 3666 volatile T * ?=?( volatile T **, P ); 3739 3667 }; 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}@3668 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}§ 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}§ 3742 3670 P ?=?( P *, const volatile T * ); 3743 3671 const volatile T * ?=?( const volatile T **, P ); … … 3748 3676 An 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. 3749 3677 \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 ) ) {3678 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 ) ) { 3751 3679 MyP ?=?( MyP *, CP ); 3752 3680 CP ?=?( CP *, MyP ); 3753 3681 }; 3754 3682 \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. 3683 The assertion ``©| m_l_ptr_like( Safe_ptr, const int * )©'' should be read as ``©Safe_ptr© is a pointer type like ©const int *©''. 3684 This 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. 3760 3685 3761 3686 … … 3763 3688 3764 3689 Different operators often have related meanings; 3765 for instance, in C, ``\lstinline$+$'', 3766 ``\lstinline$+=$'', and the two versions of ``\lstinline$++$'' perform variations of addition. 3690 for instance, in C, ``©+©'', ``©+=©'', and the two versions of ``©++©'' perform variations of addition. 3767 3691 Languages 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. 3768 3692 Completeness and consistency is left to the good taste and discretion of the programmer. … … 3777 3701 The different comparison operators have obvious relationships, but there is no obvious subset of the operations to use in the implementation of the others. 3778 3702 However, 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.3703 the library function ©strcmp© is an example. 3704 3705 C and \CFA have an extra, non-obvious comparison operator: ``©!©'', logical negation, returns 1 if its operand compares equal to 0, and 0 otherwise. 3782 3706 \begin{lstlisting} 3783 3707 trait comparable( otype T ) { … … 3827 3751 \end{lstlisting} 3828 3752 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$. 3753 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 ©int_base©, ©arith_base© and ©comparable©. 3831 3754 Note 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! 3755 A truly minimal implementation of an arithmetic type might only provide ©0©, ©1©, and ©?-=?©, which would be used by polymorphic ©?+=?©, ©?*=?©, and ©?/=?© functions. 3756 3757 Note also that ©short© is an integer type in C11 terms, but has no operations! 3837 3758 3838 3759 … … 3841 3762 3842 3763 Restrict 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.3764 This gets into ©noalias© territory. 3765 Qualifying anything (``©short restrict rs©'') means pointer parameters of ©?++©, etc, would need restrict qualifiers. 3845 3766 3846 3767 Enumerated types. … … 3852 3773 Color, enum Color ) really make sense? ?++ does, but it adds (int)1. 3853 3774 3854 Operators on {,signed,unsigned} char and other small types. ?<?harmless;3775 Operators on {,signed,unsigned} char and other small types. ©?<?© harmless; 3855 3776 ?*? questionable for chars. 3856 3777 Generic 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. 3778 Safe 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 3782 Don't use ©ptrdiff_t© by name in the predefineds. 3863 3783 3864 3784 Polymorphic objects. -
doc/user/user.tex
rbb8ea30 rd668182 11 11 %% Created On : Wed Apr 6 14:53:29 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : T hu Apr 21 08:15:37201614 %% Update Count : 13113 %% Last Modified On : Tue May 3 08:05:33 2016 14 %% Update Count : 246 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 17 17 % 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) 18 24 19 25 \documentclass[openright,twoside]{article} … … 174 180 \CC~\cite{c++,ANSI14:C++} is an example of a similar project; 175 181 however, 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.}182 Two 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.} 177 183 Fortran~\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. 178 184 Java~\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. … … 199 205 200 206 However, 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@.207 For 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©. 208 Whereas, \CFA wraps each of these routines into one with the common name ©abs©. 203 209 \begin{lstlisting} 204 210 char abs( char ); … … 215 221 long double _Complex abs( long double _Complex ); 216 222 \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}.223 The problem is the name clash between the library routine ©abs© and the \CFA names ©abs©. 224 Hence, names appearing in an ©extern "C"© block have \newterm{C linkage}. 219 225 Then overloading polymorphism uses a mechanism called \newterm{name mangling} to create unique names that are different from C names, which are not mangled. 220 226 Hence, 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. 221 227 There is no way around this problem, other than C's approach of creating unique names for each pairing of operation and type. 222 228 This 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.229 The name ``©abs©'' evokes the notion of absolute value, and many mathematical types provide the notion of absolute value. 230 Hence, knowing the name ©abs© should be sufficient to apply it to any type where it is applicable. 225 231 The time savings and safety of using one name uniformly versus $N$ unique names should not be underestimated. 226 232 227 233 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 236 The command ©cfa© is used to compile \CFA program(s). 237 This command works like the GNU ©gcc©\index{gcc} command, e.g.: 238 \begin{lstlisting} 239 cfa§\indexc{cfa}\index{compilation!cfa@©cfa©}§ [ gcc-options ] C/§\CFA§-files [ assembler/loader-files ] 240 \end{lstlisting} 241 By default, \CFA programs having the following ©gcc© flags turned on: 237 242 \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©}} 241 244 The 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¶©}} 245 246 Use the traditional GNU semantics for inline routines in C99 mode. 246 247 \end{description} 247 248 The following new \CFA option is available: 248 249 \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©}} 252 251 Only 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. 253 252 \end{description} … … 255 254 The following preprocessor variables are available: 256 255 \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__©}} 260 257 is always available during preprocessing and its value is the current major \Index{version number} of \CFA.\footnote{ 261 258 The C preprocessor allows only integer values in a preprocessor variable so a value like ``\Version'' is not allowed. 262 259 Hence, the need to have three variables for the major, minor and patch version number.} 263 260 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__©}} 267 262 is always available during preprocessing and its value is the current minor \Index{version number} of \CFA. 268 263 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__©} 272 265 is always available during preprocessing and its value is the current patch \Index{version number} of \CFA. 273 266 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__©} 277 268 is always available during preprocessing and it has no value. 278 269 \end{description} … … 282 273 \begin{lstlisting} 283 274 #ifndef __CFORALL__ 284 #include <stdio.h> // C header file275 #include <stdio.h> // C header file 285 276 #else 286 #include <fstream> // @\CFA{}@header file277 #include <fstream> // §\CFA{}§ header file 287 278 #endif 288 279 \end{lstlisting} 289 which conditionally includes the correct header file, if the program is compiled using \lstinline@gcc@ or \lstinline@cfa@.280 which conditionally includes the correct header file, if the program is compiled using ©gcc© or ©cfa©. 290 281 291 282 … … 294 285 Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, e.g.: 295 286 \begin{lstlisting} 296 2 `_`147`_`483`_`648; // decimal constant287 2®_®147®_®483®_®648; // decimal constant 297 288 56_ul; // decimal unsigned long constant 298 289 0_377; // octal constant … … 308 299 \begin{enumerate} 309 300 \item 310 A sequence of underscores is disallowed, e.g., \lstinline@12__34@is invalid.301 A sequence of underscores is disallowed, e.g., ©12__34© is invalid. 311 302 \item 312 303 Underscores 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).304 In 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). 314 305 \item 315 306 A numeric prefix may end with an underscore; 316 307 a numeric infix may begin and/or end with an underscore; 317 308 a 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@.309 For example, the octal ©0© or hexadecimal ©0x© prefix may end with an underscore ©0_377© or ©0x_ff©; 310 the exponent infix ©E© may start or end with an underscore ©1.0_E10©, ©1.0E_10© or ©1.0_E_10©; 311 the type suffixes ©U©, ©L©, etc. may start with an underscore ©1_U©, ©1_ll© or ©1.0E10_f©. 321 312 \end{enumerate} 322 313 It 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). … … 353 344 C and the new \CFA declarations may appear together in the same program block, but cannot be mixed within a specific declaration. 354 345 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.346 In \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. 356 347 However, 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:348 For instance, variables ©x© and ©y© of type pointer to integer are defined in \CFA as follows: 358 349 \begin{quote2} 359 350 \begin{tabular}{@{}l@{\hspace{30pt}}l@{}} 360 351 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 361 352 \begin{lstlisting} 362 `* int x, y;` 353 ®* int x, y;® 363 354 \end{lstlisting} 364 355 & … … 407 398 \end{quote2} 408 399 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.:400 All type qualifiers, i.e., ©const© and ©volatile©, are used in the normal way with the new declarations but appear left to right, e.g.: 410 401 \begin{quote2} 411 402 \begin{tabular}{@{}l@{\hspace{30pt}}l@{\hspace{20pt}}l@{}} … … 427 418 \end{tabular} 428 419 \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}420 All 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} 430 421 The 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.: 431 422 \begin{quote2} … … 449 440 \end{quote2} 450 441 451 Unsupported are K\&R C declarations where the base type defaults to \lstinline@int@, if no type is specified\footnote{442 Unsupported are K\&R C declarations where the base type defaults to ©int©, if no type is specified\footnote{ 452 443 At 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}}, 453 444 e.g.: … … 466 457 \section{Type Operators} 467 458 468 The new declaration syntax can be used in other contexts where types are required, e.g., casts and the pseudo-routine \lstinline@sizeof@:459 The new declaration syntax can be used in other contexts where types are required, e.g., casts and the pseudo-routine ©sizeof©: 469 460 \begin{quote2} 470 461 \begin{tabular}{@{}l@{\hspace{30pt}}l@{}} … … 488 479 The point of the new syntax is to allow returning multiple values from a routine~\cite{CLU,Galletly96}, e.g.: 489 480 \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} 485 where routine ©f© has three output (return values) and three input parameters. 495 486 Existing C syntax cannot be extended with multiple return types because it is impossible to embed a single routine name within multiple return type specifications. 496 487 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{488 In 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{ 498 489 Michael Tiemann, with help from Doug Lea, provided named return values in g++, circa 1989.} 499 490 The value of each local return variable is automatically returned at routine termination. 500 491 Declaration qualifiers can only appear at the start of a routine definition, e.g.: 501 492 \begin{lstlisting} 502 extern [ int x ] g( int y ) { @\,@}493 extern [ int x ] g( int y ) {§\,§} 503 494 \end{lstlisting} 504 495 Lastly, if there are no output parameters or input parameters, the brackets and/or parentheses must still be specified; 505 496 in 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: 506 497 \begin{lstlisting} 507 [ @\,@] g(@\,@);// no input or output parameters498 [§\,§] g(); // no input or output parameters 508 499 [ void ] g( void ); // no input or output parameters 509 500 \end{lstlisting} … … 519 510 int (*f(x))[ 5 ] int x; {} 520 511 \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.512 The 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. 513 Since the strings overlap starting with the open bracket, ©[©, there is an ambiguous interpretation for the string. 523 514 As well, \CFA-style declarations cannot be used to declare parameters for C-style routine-definitions because of the following ambiguity: 524 515 \begin{lstlisting} … … 526 517 int f( int (* foo) ); // foo is redefined as a parameter name 527 518 \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.519 The 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. 520 The 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. 530 521 The 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. 531 522 … … 546 537 \subsection{Returning Values} 547 538 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:539 Named 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: 549 540 \begin{lstlisting} 550 541 int f() { … … 554 545 } 555 546 \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() {547 Because 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() { 559 550 ... x = 0; ... x = y; ... 560 `return;`// implicitly return x561 } 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} 554 When the return is encountered, the current value of ©x© is returned to the calling routine. 555 As well, ``falling off the end'' of a routine without a ©return© statement is permitted, as in: 565 556 \begin{lstlisting} 566 557 [ int x ] f() { … … 568 559 } // implicitly return x 569 560 \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.561 In this case, the current value of ©x© is returned to the calling routine just as if a ©return© had been encountered. 571 562 572 563 … … 781 772 \subsection{Type Nesting} 782 773 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. 784 775 \begin{quote2} 785 776 \begin{tabular}{@{}l@{\hspace{30pt}}l|l@{}} … … 836 827 837 828 int fred() { 838 s.t.c = `S.`R; // type qualification839 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; 842 833 } 843 834 \end{lstlisting} 844 835 \end{tabular} 845 836 \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@::@''.837 In the left example in C, types ©C©, ©U© and ©T© are implicitly hoisted outside of type ©S© into the containing block scope. 838 In 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 ``©::©''. 848 839 849 840 … … 863 854 qsort( ia, size ); // sort ascending order using builtin ?<? 864 855 { 865 `int ?<?( int x, int y ) { return x > y; }`// nested routine856 ®int ?<?( int x, int y ) { return x > y; }® // nested routine 866 857 qsort( ia, size ); // sort descending order by local redefinition 867 858 } … … 870 861 Nested routines are not first-class, meaning a nested routine cannot be returned if it has references to variables in its enclosing blocks; 871 862 the 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})863 The following program in undefined in \CFA (and ©gcc©\index{gcc}) 873 864 \begin{lstlisting} 874 865 [* [int]( int )] foo() { // int (*foo())( int ) 875 int `i`= 7;866 int ®i® = 7; 876 867 int bar( int p ) { 877 `i`+= 1; // dependent on local variable878 sout | `i`| endl;868 ®i® += 1; // dependent on local variable 869 sout | ®i® | endl; 879 870 } 880 871 return bar; // undefined because of local dependence … … 897 888 The general syntax of a tuple is: 898 889 \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} 892 where ©$\emph{exprlist}$© is a list of one or more expressions separated by commas. 893 The brackets, ©[]©, allow differentiating between tuples and expressions containing the C comma operator. 903 894 The following are examples of tuples: 904 895 \begin{lstlisting} … … 907 898 [ v+w, x*y, 3.14159, f() ] 908 899 \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.900 Tuples 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. 910 901 Note, a tuple is not a record (structure); 911 902 a record denotes a single value with substructure, whereas a tuple is multiple values with no substructure (see flattening coercion in Section 12.1). … … 917 908 The general syntax of a tuple type is: 918 909 \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} 912 where ©$\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. 922 913 Examples of tuple types include: 923 914 \begin{lstlisting} … … 927 918 [ * [ 5 ] int, * * char, * [ [ int, int ] ] (int, int) ] 928 919 \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.920 Like 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. 930 921 931 922 Examples of declarations using tuple types are: … … 963 954 tuple does not have structure like a record; a tuple is simply converted into a list of components. 964 955 \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.956 The 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. 966 957 Using a temporary variable to store the results of the inner routine and then passing this variable to the outer routine works, however. 967 958 \end{rationale} … … 992 983 \begin{rationale} 993 984 Unfortunately, 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.985 The C subscript list has the form ©[i][j]...© and not ©[i, j, ...]©. 986 Therefore, 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. 987 Fixing 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. 997 988 \end{rationale} 998 989 … … 1013 1004 [ a, b, c, d ] = w 1014 1005 \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. 1016 1007 1017 1008 A \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: … … 1021 1012 First the right-hand tuple is flattened and then the values are assigned individually. 1022 1013 Flattening 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 ]@.1014 For example, the type ©[ int, [ int, int ], int ]© can be coerced, using flattening, into the type ©[ int, int, int, int ]©. 1024 1015 1025 1016 A \newterm{structuring coercion} is the opposite of flattening; 1026 1017 a 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 ]@.1018 For 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 ]©. 1028 1019 In the following example, the last assignment illustrates all the tuple coercions: 1029 1020 \begin{lstlisting} … … 1033 1024 \end{lstlisting} 1034 1025 Starting 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).1026 therefore, the right-hand tuple is now the tuple ©[ [ 1, 2, 3, 4 ], 5 ]©. 1027 This 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. 1028 The tuple ©[ 2, 3, 4, 5 ]© is then closed to create a tuple value. 1029 Finally, ©x© is assigned ©1© and ©w© is assigned the tuple value using multiple assignment (see Section 14). 1039 1030 \begin{rationale} 1040 1031 A possible additional language extension is to use the structuring coercion for tuples to initialize a complex record with a tuple. … … 1047 1038 Mass assignment has the following form: 1048 1039 \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} 1042 The 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. 1053 1044 Clearly, the types of the entities being assigned must be type compatible with the value of the expression. 1054 1045 … … 1076 1067 *a1 = t; *a2 = t; *a3 = t; 1077 1068 \end{lstlisting} 1078 The temporary \lstinline@t@is necessary to store the value of the expression to eliminate conversion issues.1069 The temporary ©t© is necessary to store the value of the expression to eliminate conversion issues. 1079 1070 The 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.1071 In this case, ©y[i]© uses the previous value of ©i© and not the new value set at the beginning of the mass assignment. 1081 1072 1082 1073 … … 1086 1077 Multiple assignment has the following form: 1087 1078 \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} 1081 The left-hand side is a tuple of \emph{lvalues}, and the right-hand side is a tuple of \emph{expr}s. 1082 Each \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. 1092 1083 An example of multiple assignment is: 1093 1084 \begin{lstlisting} 1094 1085 [ x, y, z ] = [ 1, 2, 3 ]; 1095 1086 \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@.1087 Here, the values ©1©, ©2© and ©3© are assigned, respectively, to the variables ©x©, ©y© and ©z©. 1097 1088 A more complex example is: 1098 1089 \begin{lstlisting} 1099 1090 [ i, y[ i ], z ] = [ 1, i, a + b ]; 1100 1091 \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.1092 Here, the values ©1©, ©i© and ©a + b© are assigned to the variables ©i©, ©y[i]© and ©z©, respectively. 1102 1093 Note, the parallel semantics of 1103 1094 multiple assignment ensures: … … 1105 1096 [ x, y ] = [ y, x ]; 1106 1097 \end{lstlisting} 1107 correctly interchanges (swaps) the values stored in \lstinline@x@ and \lstinline@y@.1098 correctly interchanges (swaps) the values stored in ©x© and ©y©. 1108 1099 The following cases are errors: 1109 1100 \begin{lstlisting} … … 1126 1117 Cascade assignment has the following form: 1127 1118 \begin{lstlisting} 1128 @\emph{tuple}@ = @\emph{tuple}@ = ... = @\emph{tuple}@;1119 §\emph{tuple}§ = §\emph{tuple}§ = ... = §\emph{tuple}§; 1129 1120 \end{lstlisting} 1130 1121 and it has the same parallel semantics as for mass and multiple assignment. … … 1144 1135 Its general form is: 1145 1136 \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©. 1141 Each element of \emph{ fieldlist} is an element of the record specified by \emph{expr}. 1151 1142 A record-field tuple may be used anywhere a tuple can be used. An example of the use of a record-field tuple is 1152 1143 the following: … … 1163 1154 also, it is unnecessary to specify all the fields of a struct in a multiple record-field tuple. 1164 1155 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:1156 If 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: 1166 1157 \begin{lstlisting} 1167 1158 struct inner { … … 1180 1171 \section{Labelled Break/Continue} 1181 1172 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:1173 While C provides ©break© and ©continue© statements for altering control flow, both are restricted to one level of nesting for a particular control structure. 1174 Unfortunately, this restriction forces programmers to use ©goto© to achieve the equivalent for more than one level of nesting. 1175 To 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}. 1176 For the labelled ©break©, it is possible to specify which control structure is the target for exit, as in: 1186 1177 \begin{quote2} 1187 1178 \begin{tabular}{@{}l@{\hspace{30pt}}l@{}} 1188 1179 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1189 1180 \begin{lstlisting} 1190 `L1:`for ( ... ) {1191 `L2:`for ( ... ) {1192 `L3:`for ( ... ) {1193 ... break `L1`; ...1194 ... break `L2`; ...1195 ... break `L3`; // or break1181 ®L1:® for ( ... ) { 1182 ®L2:® for ( ... ) { 1183 ®L3:® for ( ... ) { 1184 ... break ®L1®; ... 1185 ... break ®L2®; ... 1186 ... break ®L3®; // or break 1196 1187 } 1197 1188 } … … 1213 1204 \end{quote2} 1214 1205 The 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:1206 For the labelled ©continue©, it is possible to specify which control structure is the target for the next loop iteration, as in: 1216 1207 \begin{quote2} 1217 1208 \begin{tabular}{@{}l@{\hspace{30pt}}l@{}} 1218 1209 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1219 1210 \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®; ... 1226 1217 1227 1218 } … … 1249 1240 \end{quote2} 1250 1241 The 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:1242 For both ©break© and ©continue©, the target label must be directly associated with a ©for©, ©while© or ©do© statement; 1243 for ©break©, the target label can also be associated with a ©switch© statement. 1244 Both ©break© and ©continue© with target labels are simply a ©goto© restricted in the following ways: 1254 1245 \begin{itemize} 1255 1246 \item … … 1260 1251 Since they always transfers out of containing control structures, they cannot be used to branch into a control structure. 1261 1252 \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.1253 The 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. 1263 1254 Furthermore, 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.1255 With ©goto©, the label at the end of the control structure fails to convey this important clue early enough to the reader. 1265 1256 Finally, 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.1257 The implicit targets of the current ©break© and ©continue©, i.e., the closest enclosing loop or ©switch©, change as certain constructs are added or removed. 1267 1258 1268 1259 1269 1260 \section{Switch Statement} 1270 1261 1271 C allows a number of questionable forms for the \lstinline@switch@statement:1262 C allows a number of questionable forms for the ©switch© statement: 1272 1263 \begin{enumerate} 1273 1264 \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:1265 By default, the end of a ©case© clause\footnote{ 1266 In 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; 1268 to exit a ©switch© statement from a ©case© clause requires explicitly terminating the clause with a transfer statement, most commonly ©break©, as in: 1278 1269 \begin{lstlisting} 1279 1270 switch ( i ) { … … 1300 1291 \end{lstlisting} 1301 1292 In 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.1293 This 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. 1303 1294 C also uses fall-through to handle multiple case-values resulting in the same action, as in: 1304 1295 \begin{lstlisting} … … 1313 1304 \end{lstlisting} 1314 1305 However, 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:1306 While 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. 1307 Hence, ©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 1310 It is possible to place ©case© clauses on statements nested \emph{within} the body of the ©switch© statement, as in: 1320 1311 \begin{lstlisting} 1321 1312 switch ( i ) { … … 1358 1349 } 1359 1350 \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.1351 which unrolls a loop N times (N = 8 above) and uses the ©switch© statement to deal with any iterations not a multiple of N. 1361 1352 While efficient, this sort of special purpose usage is questionable: 1362 1353 \begin{quote} … … 1365 1356 \end{quote} 1366 1357 \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:1358 It is possible to place the ©default© clause anywhere in the list of labelled clauses for a ©switch© statement, rather than only at the end. 1359 Virtually all programming languages with a ©switch© statement require the ©default© clause to appear last in the case-clause list. 1360 The logic for this semantics is that after checking all the ©case© clauses without success, the ©default© clause is selected; 1361 hence, physically placing the ©default© clause at the end of the ©case© clause list matches with this semantics. 1362 This 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 1365 It is possible to place unreachable code at the start of a ©switch© statement, as in: 1375 1366 \begin{lstlisting} 1376 1367 switch ( x ) { … … 1382 1373 } 1383 1374 \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@.1375 While 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. 1376 Furthermore, 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©. 1386 1377 As mentioned, transfer into control structures should be forbidden. 1387 Transfers from within the \lstinline@switch@ body using a \lstinline@goto@are equally unpalatable.1378 Transfers from within the ©switch© body using a ©goto© are equally unpalatable. 1388 1379 \end{enumerate} 1389 1380 Before discussing potential language changes to deal with these problems, it is worth observing that in a typical C program: 1390 1381 \begin{itemize} 1391 1382 \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.1383 the number of ©switch© statements is small, 1384 \item 1385 most ©switch© statements are well formed (i.e., no Duff's device), 1386 \item 1387 the ©default© clause is usually written as the last case-clause, 1388 \item 1389 and 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. 1399 1390 \end{itemize} 1400 1391 These observations should help to put the effects of suggested changes into perspective. … … 1402 1393 \begin{enumerate} 1403 1394 \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.:1395 Eliminating the ©default© fall-through problem has the greatest potential for affecting existing code. 1396 However, 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. 1397 In 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.: 1407 1398 \begin{lstlisting} 1408 1399 case 1: case 2: case 3: ... 1409 1400 \end{lstlisting} 1410 1401 Nevertheless, 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).1402 Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called ©choose©, with no fall-through semantics. 1403 The ©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). 1413 1404 It is still possible to fall-through if a case-clause ends with the new keyword fallthru, e.g.: 1414 1405 \begin{lstlisting} … … 1426 1417 \item 1427 1418 Eliminating 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.1419 The 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 1421 The 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. 1431 1422 Therefore, no language change is made for this issue. 1432 1423 \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.1424 Dealing 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. 1434 1425 This 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.1426 As well, this grammar does not allow statements to appear before the first ©case© clause. 1436 1427 The change is compatible for declarations with initialization in this context because existing code cannot assume the initialization has occurred. 1437 1428 The change is incompatible for statements, but any existing code using it is highly questionable, as in: … … 1443 1434 } 1444 1435 \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.1436 The statement after the ©switch© can never be executed unless it is labelled. 1437 If it is labelled, it must be transfered to from outside or inside the ©switch© statement, neither of which is acceptable control flow. 1447 1438 \end{enumerate} 1448 1439 … … 1450 1441 \section{Case Clause} 1451 1442 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:1443 C restricts the ©case© clause of a ©switch© statement to a single value. 1444 For multiple ©case© clauses associated with the same statement, it is necessary to have multiple ©case© clauses rather than multiple values. 1445 Requiring a ©case© clause for each value does not seem to be in the spirit of brevity normally associated with C. 1446 Therefore, the ©case© clause is extended with a list of values, as in: 1456 1447 \begin{quote2} 1457 1448 \begin{tabular}{@{}l@{\hspace{30pt}}l@{\hspace{20pt}}l@{}} … … 1459 1450 \begin{lstlisting} 1460 1451 switch ( i ) { 1461 `case 1, 3, 5`:1452 ®case 1, 3, 5®: 1462 1453 ... 1463 `case 2, 4, 6`:1454 ®case 2, 4, 6®: 1464 1455 ... 1465 1456 } … … 1491 1482 \begin{lstlisting} 1492 1483 switch ( i ) { 1493 `case 1~5:`1484 ®case 1~5:® 1494 1485 ... 1495 `case 10~15:`1486 ®case 10~15:® 1496 1487 ... 1497 1488 } … … 1748 1739 1749 1740 The 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).1741 Use ©&© to specify a reference, and access references just like regular objects, not like pointers (use dot notation to access fields). 1751 1742 When 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.1743 The ©&© 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. 1753 1744 1754 1745 \begin{figure} … … 1823 1814 In \CFA, as in C, all scalar types can be incremented and 1824 1815 decremented, 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)@).1816 The 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)©). 1826 1817 1827 1818 In C, the integer constants 0 and 1 suffice because the integer promotion rules can convert them to any … … 1832 1823 polymorphic parameters, and user-defined pointer-like types may need a null value. 1833 1824 Defining special 1834 constants for a user-defined type is more efficient than defining a conversion to the type from \lstinline@_Bool@.1825 constants for a user-defined type is more efficient than defining a conversion to the type from ©_Bool©. 1835 1826 1836 1827 Why just 0 and 1? Why not other integers? No other integers have special status in C. … … 1915 1906 \begin{tabular}[t]{ll} 1916 1907 %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{?/?}\\ 1930 1921 \end{tabular}\hfil 1931 1922 \begin{tabular}[t]{ll} 1932 1923 %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{?&?}\\ 1945 1936 \end{tabular}\hfil 1946 1937 \begin{tabular}[t]{ll} 1947 1938 %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{?"|=?}\\ 1961 1952 \end{tabular} 1962 1953 \hfil … … 1967 1958 These identifiers are defined such that the question marks in the name identify the location of the operands. 1968 1959 These 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)@.1960 For example, ©a + b© becomes ©?+?(a, b)©. 1970 1961 1971 1962 In the example below, a new type, myComplex, is defined with an overloaded constructor, + operator, and string operator. … … 2010 2001 \begin{quote2} 2011 2002 \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} \\ 2013 2004 \begin{lstlisting} 2014 2005 … … 2041 2032 \end{itemize} 2042 2033 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.2034 In \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. 2045 2036 \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. 2046 2037 Only 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.2038 Finally, ©auto© presents the programming problem of tracking down a type when the type is actually needed. 2048 2039 For example, given 2049 2040 \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 );2041 auto j = ®...® 2042 \end{lstlisting} 2043 and the need to write a routine to compute using ©j© 2044 \begin{lstlisting} 2045 void rtn( ®...® parm ); 2055 2046 rtn( j ); 2056 2047 \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.2048 A programmer must work backwards to determine the type of ©j©'s initialization expression, reconstructing the possibly long generic type-name. 2058 2049 In this situation, having the type name or a short alias is very useful. 2059 2050 … … 2063 2054 At some point, a programmer wants the type of the variable to remain constant and the expression to be in error when it changes. 2064 2055 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.2056 Given ©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. 2066 2057 Should a significant need arise, this feature can be revisited. 2067 2058 … … 2365 2356 } s; 2366 2357 \end{lstlisting} 2367 The problem occurs in accesing these fields using the selection operation `` \lstinline@.@'':2358 The problem occurs in accesing these fields using the selection operation ``©.©'': 2368 2359 \begin{lstlisting} 2369 2360 s.0 = 0; // ambiguity with floating constant .0 … … 2372 2363 To make this work, a space is required after the field selection: 2373 2364 \begin{lstlisting} 2374 `s.@\textvisiblespace@0`= 0;2375 `s.@\textvisiblespace@1`= 1;2365 ®s.§\textvisiblespace§0® = 0; 2366 ®s.§\textvisiblespace§1® = 1; 2376 2367 \end{lstlisting} 2377 2368 While 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.2369 Like 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 2371 There are several ambiguous cases with operator identifiers, e.g., ©int *?*?()©, where the string ©*?*?© can be lexed as ©*©/©?*?© or ©*?©/©*?©. 2372 Since 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. 2382 2373 Even 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.2374 The first case is for the function-call identifier ©?()©: 2375 \begin{lstlisting} 2376 int *§\textvisiblespace§?()(); // declaration: space required after '*' 2377 *§\textvisiblespace§?()(); // expression: space required after '*' 2378 \end{lstlisting} 2379 Without the space, the string ©*?()© is ambiguous without N character look ahead; 2380 it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument/parameter list. 2390 2381 2391 2382 The 4 remaining cases occur in expressions: 2392 2383 \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.2384 i++§\textvisiblespace§?i:0; // space required before '?' 2385 i--§\textvisiblespace§?i:0; // space required before '?' 2386 i§\textvisiblespace§?++i:0; // space required after '?' 2387 i§\textvisiblespace§?--i:0; // space required after '?' 2388 \end{lstlisting} 2389 In the first two cases, the string ©i++?© is ambiguous, where this string can be lexed as ©i© / ©++?© or ©i++© / ©?©; 2390 it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument list. 2391 In the second two cases, the string ©?++x© is ambiguous, where this string can be lexed as ©?++© / ©x© or ©?© / y©++x©; 2392 it requires scanning ahead to determine if there is a ©'('©, which is the start of an argument list. 2402 2393 2403 2394 … … 3325 3316 3326 3317 3327 \subsection {Comparing Key Features of \CFA}3318 \subsection[Comparing Key Features of CFA]{Comparing Key Features of \CFA} 3328 3319 3329 3320 … … 3699 3690 3700 3691 \begin{comment} 3701 \subsubsection{Modules /Packages}3692 \subsubsection{Modules / Packages} 3702 3693 3703 3694 \begin{lstlisting} … … 3941 3932 3942 3933 3943 \subsubsection {\CC}3934 \subsubsection[C++]{\CC} 3944 3935 3945 3936 \CC is a general-purpose programming language. … … 4015 4006 \begin{enumerate} 4016 4007 \item 4017 Change type of character literal \lstinline@int@ to \lstinline@char@.4008 Change type of character literal ©int© to ©char©. 4018 4009 This change allows overloading differentiation argument type matching, e.g.: 4019 4010 \begin{lstlisting} … … 4032 4023 4033 4024 \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@. \\4025 Change: String literals made ©const© \\ 4026 The type of a string literal is changed from ©array of char© to ©array of const char©. 4027 The type of a wide string literal is changed from ©array of wchar_t© to ©array of const wchar_t©. \\ 4037 4028 Rationale: This avoids calling an inappropriate overloaded function, which might expect to be able to modify its argument. 4038 4029 Effect 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).4030 Difficulty of converting: Simple syntactic transformation, because string literals can be converted to ©char*;© (4.2). 4040 4031 The most common cases are handled by a new but deprecated standard conversion: 4041 4032 \begin{lstlisting} … … 4076 4067 4077 4068 \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@::@''.4069 Nested types are not hoisted and can be referenced using the field selection operator ``©.©'', unlike the \CC scope-resolution operator ``©::©''. 4079 4070 Given 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 4081 4071 4082 4072 \item … … 4090 4080 struct Y yy; // valid C, invalid C++ 4091 4081 \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: 4082 Rationale: C++ classes have member functions which require that classes establish scopes. 4083 The 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. 4084 Effect on original feature: Change of semantics of welldefined feature. 4085 Difficulty 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: 4102 4086 \begin{lstlisting} 4103 4087 struct Y; // struct Y and struct X are at the same scope … … 4106 4090 }; 4107 4091 \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. 4092 All 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. 4093 Note: this is a consequence of the difference in scope rules, which is documented in 3.3. 4111 4094 How widely used: Seldom. 4112 4095 \end{enumerate} … … 4124 4107 \begin{lstlisting} 4125 4108 int x = 0, y = 1, z = 2; 4126 `sout` `|` x `|` y `|` z `| endl`;4109 ®sout® ®|® x ®|® y ®|® z ®| endl®; 4127 4110 \end{lstlisting} 4128 4111 & … … 4133 4116 \end{tabular} 4134 4117 \end{quote2} 4135 The \CFA form is half as many characters, and is similar to PythonI/O with respect to implicit separators.4118 The \CFA form is half as many characters, and is similar to \Index{Python} I/O with respect to implicit separators. 4136 4119 4137 4120 The logical-or operator is used because it is the lowest-priority overloadable operator, other than assignment. … … 4160 4143 A seperator does not appear at the start or end of a line. 4161 4144 \begin{lstlisting}[belowskip=0pt] 4162 sout 1 | 2 | 3 | endl;4145 sout | 1 | 2 | 3 | endl; 4163 4146 \end{lstlisting} 4164 4147 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] … … 4179 4162 which is a local mechanism to disable insertion of the separator character. 4180 4163 \item 4181 A seperator does not appear before a C string starting with the \Index{extended ASCII}\index{ASCII} characters: \lstinline[mathescape=off]@([{$£¥¿«@4164 A seperator does not appear before a C string starting with the (extended) \Index{ASCII}\index{ASCII!extended} characters: \lstinline[mathescape=off]@([{$£¥¡¿«@ 4182 4165 %$ 4183 4166 \begin{lstlisting}[mathescape=off] 4184 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x $" | 4 | "x £" | 5 | "x ¥" | 6 | "x ¿" | 7 | "x «" | 8| endl;4167 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x $" | 4 | "x £" | 5 | "x ¥" | 6 | "x ¡" | 7 | "x ¿" | 8 | "x «" | 9 | endl; 4185 4168 \end{lstlisting} 4186 4169 %$ 4187 4170 \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 «84171 x (1 x [2 x {3 x $4 x £5 x ¥6 x ¡7 x ¿8 x «9 4189 4172 \end{lstlisting} 4190 4173 %$ 4191 4174 \item 4192 A seperator does not appear after a C string ending with the extended ASCII characters: \lstinline@,.:;!?)]}%¢»@4175 A seperator does not appear after a C string ending with the (extended) \Index{ASCII}\index{ASCII!extended} characters: ©,.:;!?)]}%¢»© 4193 4176 \begin{lstlisting}[belowskip=0pt] 4194 4177 sout | 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; 4196 4179 \end{lstlisting} 4197 4180 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] … … 4199 4182 \end{lstlisting} 4200 4183 \item 4201 A seperator does not appear before or after a C string begining/ending with the characters: \lstinline@\f\n\r\t\v\`'"@4184 A 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@ 4202 4185 \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 4186 sout | "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] 4189 x`1`x'2'x"3"x x 4 x x 1 x 4211 4190 \end{lstlisting} 4212 4191 \end{enumerate} … … 4240 4219 \end{lstlisting} 4241 4220 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4242 1 2 34221 1 2 3 4243 4222 \end{lstlisting} 4244 4223 \begin{lstlisting}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt] … … 4251 4230 \end{lstlisting} 4252 4231 %$ 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} 4257 4233 #include <fstream> 4258 4234 4259 4235 int 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 %$ 4322 4260 4323 4261 … … 4331 4269 4332 4270 \begin{lstlisting} 4333 forall( otype T ) T * malloc( void ); 4271 forall( otype T ) T * malloc( void );§\indexc{malloc}§ 4334 4272 forall( otype T ) T * malloc( char fill ); 4335 4273 forall( otype T ) T * malloc( T * ptr, size_t size ); 4336 4274 forall( 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 ); 4275 forall( otype T ) T * calloc( size_t nmemb );§\indexc{calloc}§ 4276 forall( otype T ) T * realloc( T * ptr, size_t size );§\indexc{ato}§ 4339 4277 forall( otype T ) T * realloc( T * ptr, size_t size, unsigned char fill ); 4340 4278 4341 forall( otype T ) T * aligned_alloc( size_t alignment ); 4279 forall( otype T ) T * aligned_alloc( size_t alignment );§\indexc{ato}§ 4342 4280 forall( otype T ) T * memalign( size_t alignment ); // deprecated 4343 4281 forall( otype T ) int posix_memalign( T ** ptr, size_t alignment ); … … 4348 4286 4349 4287 4350 \subsection{ato /strto}4351 4352 \begin{lstlisting} 4353 int ato( const char * ptr ); 4288 \subsection{ato / strto} 4289 4290 \begin{lstlisting} 4291 int ato( const char * ptr );§\indexc{ato}§ 4354 4292 unsigned int ato( const char * ptr ); 4355 4293 long int ato( const char * ptr ); … … 4379 4317 4380 4318 4381 \subsection{bsearch /qsort}4319 \subsection{bsearch / qsort} 4382 4320 4383 4321 \begin{lstlisting} 4384 4322 forall( otype T | { int ?<?( T, T ); } ) 4385 T * bsearch( const T key, const T * arr, size_t dimension ); 4323 T * bsearch( const T key, const T * arr, size_t dimension );§\indexc{bsearch}§ 4386 4324 4387 4325 forall( otype T | { int ?<?( T, T ); } ) 4388 void qsort( const T * arr, size_t dimension ); 4326 void qsort( const T * arr, size_t dimension );§\indexc{qsort}§ 4389 4327 \end{lstlisting} 4390 4328 … … 4393 4331 4394 4332 \begin{lstlisting} 4395 char abs( char ); 4396 extern "C" { 4397 int abs( int ); // use default C routine for int 4398 } // extern "C" 4333 char abs( char );§\indexc{abs}§ 4334 int abs( int ); 4399 4335 long int abs( long int ); 4400 4336 long long int abs( long long int ); … … 4402 4338 double abs( double ); 4403 4339 long 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 ); 4340 float abs( float _Complex ); 4341 double abs( double _Complex ); 4342 long double abs( long double _Complex ); 4424 4343 \end{lstlisting} 4425 4344 … … 4428 4347 4429 4348 \begin{lstlisting} 4430 void rand48seed( long int s ); 4431 char rand48(); 4349 void rand48seed( long int s );§\indexc{rand48seed}§ 4350 char rand48();§\indexc{rand48}§ 4432 4351 int rand48(); 4433 4352 unsigned int rand48(); … … 4442 4361 4443 4362 4444 \subsection{min /max/swap}4363 \subsection{min / max / swap} 4445 4364 4446 4365 \begin{lstlisting} 4447 4366 forall( otype T | { int ?<?( T, T ); } ) 4448 T min( const T t1, const T t2 ); 4367 T min( const T t1, const T t2 );§\indexc{min}§ 4449 4368 4450 4369 forall( otype T | { int ?>?( T, T ); } ) 4451 T max( const T t1, const T t2 ); 4370 T max( const T t1, const T t2 );§\indexc{max}§ 4452 4371 4453 4372 forall( otype T ) 4454 void swap( T * t1, T * t2 ); 4373 void swap( T * t1, T * t2 );§\indexc{swap}§ 4374 \end{lstlisting} 4375 4376 4377 \section{Math Library} 4378 \label{s:Math Library} 4379 4380 The 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} 4386 float fabs( float );§\indexc{fabs}§ 4387 double fabs( double ); 4388 long double fabs( long double ); 4389 float cabs( float _Complex ); 4390 double cabs( double _Complex ); 4391 long double cabs( long double _Complex ); 4392 4393 float ?%?( float, float );§\indexc{fmod}§ 4394 float fmod( float, float ); 4395 double ?%?( double, double ); 4396 double fmod( double, double ); 4397 long double ?%?( long double, long double ); 4398 long double fmod( long double, long double ); 4399 4400 float remainder( float, float );§\indexc{remainder}§ 4401 double remainder( double, double ); 4402 long double remainder( long double, long double ); 4403 4404 [ int, float ] remquo( float, float );§\indexc{remquo}§ 4405 float remquo( float, float, int * ); 4406 [ int, double ] remquo( double, double ); 4407 double remquo( double, double, int * ); 4408 [ int, long double ] remquo( long double, long double ); 4409 long double remquo( long double, long double, int * ); 4410 4411 [ int, float ] div( float, float ); // alternative name for remquo 4412 float div( float, float, int * );§\indexc{div}§ 4413 [ int, double ] div( double, double ); 4414 double div( double, double, int * ); 4415 [ int, long double ] div( long double, long double ); 4416 long double div( long double, long double, int * ); 4417 4418 float fma( float, float, float );§\indexc{fma}§ 4419 double fma( double, double, double ); 4420 long double fma( long double, long double, long double ); 4421 4422 float fdim( float, float );§\indexc{fdim}§ 4423 double fdim( double, double ); 4424 long double fdim( long double, long double ); 4425 4426 float nan( const char * );§\indexc{nan}§ 4427 double nan( const char * ); 4428 long double nan( const char * ); 4429 \end{lstlisting} 4430 4431 4432 \subsection{Exponential} 4433 4434 \begin{lstlisting} 4435 float exp( float );§\indexc{exp}§ 4436 double exp( double ); 4437 long double exp( long double ); 4438 float _Complex exp( float _Complex ); 4439 double _Complex exp( double _Complex ); 4440 long double _Complex exp( long double _Complex ); 4441 4442 float exp2( float );§\indexc{exp2}§ 4443 double exp2( double ); 4444 long double exp2( long double ); 4445 float _Complex exp2( float _Complex ); 4446 double _Complex exp2( double _Complex ); 4447 long double _Complex exp2( long double _Complex ); 4448 4449 float expm1( float );§\indexc{expm1}§ 4450 double expm1( double ); 4451 long double expm1( long double ); 4452 4453 float log( float );§\indexc{log}§ 4454 double log( double ); 4455 long double log( long double ); 4456 float _Complex log( float _Complex ); 4457 double _Complex log( double _Complex ); 4458 long double _Complex log( long double _Complex ); 4459 4460 float log2( float );§\indexc{log2}§ 4461 double log2( double ); 4462 long double log2( long double ); 4463 float _Complex log2( float _Complex ); 4464 double _Complex log2( double _Complex ); 4465 long double _Complex log2( long double _Complex ); 4466 4467 float log10( float );§\indexc{log10}§ 4468 double log10( double ); 4469 long double log10( long double ); 4470 float _Complex log10( float _Complex ); 4471 double _Complex log10( double _Complex ); 4472 long double _Complex log10( long double _Complex ); 4473 4474 float log1p( float );§\indexc{log1p}§ 4475 double log1p( double ); 4476 long double log1p( long double ); 4477 4478 int ilogb( float );§\indexc{ilogb}§ 4479 int ilogb( double ); 4480 int ilogb( long double ); 4481 4482 float logb( float );§\indexc{logb}§ 4483 double logb( double ); 4484 long double logb( long double ); 4485 \end{lstlisting} 4486 4487 4488 \subsection{Power} 4489 4490 \begin{lstlisting} 4491 float sqrt( float );§\indexc{sqrt}§ 4492 double sqrt( double ); 4493 long double sqrt( long double ); 4494 float _Complex sqrt( float _Complex ); 4495 double _Complex sqrt( double _Complex ); 4496 long double _Complex sqrt( long double _Complex ); 4497 4498 float cbrt( float );§\indexc{cbrt}§ 4499 double cbrt( double ); 4500 long double cbrt( long double ); 4501 4502 float hypot( float, float );§\indexc{hypot}§ 4503 double hypot( double, double ); 4504 long double hypot( long double, long double ); 4505 4506 float pow( float, float );§\indexc{pow}§ 4507 double pow( double, double ); 4508 long double pow( long double, long double ); 4509 float _Complex pow( float _Complex, float _Complex ); 4510 double _Complex pow( double _Complex, double _Complex ); 4511 long double _Complex pow( long double _Complex, long double _Complex ); 4512 \end{lstlisting} 4513 4514 4515 \subsection{Trigonometric} 4516 4517 \begin{lstlisting} 4518 float sin( float );§\indexc{sin}§ 4519 double sin( double ); 4520 long double sin( long double ); 4521 float _Complex sin( float _Complex ); 4522 double _Complex sin( double _Complex ); 4523 long double _Complex sin( long double _Complex ); 4524 4525 float cos( float );§\indexc{cos}§ 4526 double cos( double ); 4527 long double cos( long double ); 4528 float _Complex cos( float _Complex ); 4529 double _Complex cos( double _Complex ); 4530 long double _Complex cos( long double _Complex ); 4531 4532 float tan( float );§\indexc{tan}§ 4533 double tan( double ); 4534 long double tan( long double ); 4535 float _Complex tan( float _Complex ); 4536 double _Complex tan( double _Complex ); 4537 long double _Complex tan( long double _Complex ); 4538 4539 float asin( float );§\indexc{asin}§ 4540 double asin( double ); 4541 long double asin( long double ); 4542 float _Complex asin( float _Complex ); 4543 double _Complex asin( double _Complex ); 4544 long double _Complex asin( long double _Complex ); 4545 4546 float acos( float );§\indexc{acos}§ 4547 double acos( double ); 4548 long double acos( long double ); 4549 float _Complex acos( float _Complex ); 4550 double _Complex acos( double _Complex ); 4551 long double _Complex acos( long double _Complex ); 4552 4553 float atan( float );§\indexc{atan}§ 4554 double atan( double ); 4555 long double atan( long double ); 4556 float _Complex atan( float _Complex ); 4557 double _Complex atan( double _Complex ); 4558 long double _Complex atan( long double _Complex ); 4559 4560 float atan2( float, float );§\indexc{atan2}§ 4561 double atan2( double, double ); 4562 long double atan2( long double, long double ); 4563 4564 float atan( float, float ); // alternative name for atan2 4565 double atan( double, double );§\indexc{atan}§ 4566 long double atan( long double, long double ); 4567 \end{lstlisting} 4568 4569 4570 \subsection{Hyperbolic} 4571 4572 \begin{lstlisting} 4573 float sinh( float );§\indexc{sinh}§ 4574 double sinh( double ); 4575 long double sinh( long double ); 4576 float _Complex sinh( float _Complex ); 4577 double _Complex sinh( double _Complex ); 4578 long double _Complex sinh( long double _Complex ); 4579 4580 float cosh( float );§\indexc{cosh}§ 4581 double cosh( double ); 4582 long double cosh( long double ); 4583 float _Complex cosh( float _Complex ); 4584 double _Complex cosh( double _Complex ); 4585 long double _Complex cosh( long double _Complex ); 4586 4587 float tanh( float );§\indexc{tanh}§ 4588 double tanh( double ); 4589 long double tanh( long double ); 4590 float _Complex tanh( float _Complex ); 4591 double _Complex tanh( double _Complex ); 4592 long double _Complex tanh( long double _Complex ); 4593 4594 float asinh( float );§\indexc{asinh}§ 4595 double asinh( double ); 4596 long double asinh( long double ); 4597 float _Complex asinh( float _Complex ); 4598 double _Complex asinh( double _Complex ); 4599 long double _Complex asinh( long double _Complex ); 4600 4601 float acosh( float );§\indexc{acosh}§ 4602 double acosh( double ); 4603 long double acosh( long double ); 4604 float _Complex acosh( float _Complex ); 4605 double _Complex acosh( double _Complex ); 4606 long double _Complex acosh( long double _Complex ); 4607 4608 float atanh( float );§\indexc{atanh}§ 4609 double atanh( double ); 4610 long double atanh( long double ); 4611 float _Complex atanh( float _Complex ); 4612 double _Complex atanh( double _Complex ); 4613 long double _Complex atanh( long double _Complex ); 4614 \end{lstlisting} 4615 4616 4617 \subsection{Error / Gamma} 4618 4619 \begin{lstlisting} 4620 float erf( float );§\indexc{erf}§ 4621 double erf( double ); 4622 long double erf( long double ); 4623 float _Complex erf( float _Complex ); 4624 double _Complex erf( double _Complex ); 4625 long double _Complex erf( long double _Complex ); 4626 4627 float erfc( float );§\indexc{erfc}§ 4628 double erfc( double ); 4629 long double erfc( long double ); 4630 float _Complex erfc( float _Complex ); 4631 double _Complex erfc( double _Complex ); 4632 long double _Complex erfc( long double _Complex ); 4633 4634 float lgamma( float );§\indexc{lgamma}§ 4635 double lgamma( double ); 4636 long double lgamma( long double ); 4637 float lgamma( float, int * ); 4638 double lgamma( double, int * ); 4639 long double lgamma( long double, int * ); 4640 4641 float tgamma( float );§\indexc{tgamma}§ 4642 double tgamma( double ); 4643 long double tgamma( long double ); 4644 \end{lstlisting} 4645 4646 4647 \subsection{Nearest Integer} 4648 4649 \begin{lstlisting} 4650 float floor( float );§\indexc{floor}§ 4651 double floor( double ); 4652 long double floor( long double ); 4653 4654 float ceil( float );§\indexc{ceil}§ 4655 double ceil( double ); 4656 long double ceil( long double ); 4657 4658 float trunc( float );§\indexc{trunc}§ 4659 double trunc( double ); 4660 long double trunc( long double ); 4661 4662 float rint( float );§\indexc{rint}§ 4663 long double rint( long double ); 4664 long int rint( float ); 4665 long int rint( double ); 4666 long int rint( long double ); 4667 long long int rint( float ); 4668 long long int rint( double ); 4669 long long int rint( long double ); 4670 4671 long int lrint( float );§\indexc{lrint}§ 4672 long int lrint( double ); 4673 long int lrint( long double ); 4674 long long int llrint( float ); 4675 long long int llrint( double ); 4676 long long int llrint( long double ); 4677 4678 float nearbyint( float );§\indexc{nearbyint}§ 4679 double nearbyint( double ); 4680 long double nearbyint( long double ); 4681 4682 float round( float );§\indexc{round}§ 4683 long double round( long double ); 4684 long int round( float ); 4685 long int round( double ); 4686 long int round( long double ); 4687 long long int round( float ); 4688 long long int round( double ); 4689 long long int round( long double ); 4690 4691 long int lround( float );§\indexc{lround}§ 4692 long int lround( double ); 4693 long int lround( long double ); 4694 long long int llround( float ); 4695 long long int llround( double ); 4696 long long int llround( long double ); 4697 \end{lstlisting} 4698 4699 4700 \subsection{Manipulation} 4701 4702 \begin{lstlisting} 4703 float copysign( float, float );§\indexc{copysign}§ 4704 double copysign( double, double ); 4705 long double copysign( long double, long double ); 4706 4707 float frexp( float, int * );§\indexc{frexp}§ 4708 double frexp( double, int * ); 4709 long double frexp( long double, int * ); 4710 4711 float ldexp( float, int );§\indexc{ldexp}§ 4712 double ldexp( double, int ); 4713 long double ldexp( long double, int ); 4714 4715 [ float, float ] modf( float );§\indexc{modf}§ 4716 float modf( float, float * ); 4717 [ double, double ] modf( double ); 4718 double modf( double, double * ); 4719 [ long double, long double ] modf( long double ); 4720 long double modf( long double, long double * ); 4721 4722 float nextafter( float, float );§\indexc{nextafter}§ 4723 double nextafter( double, double ); 4724 long double nextafter( long double, long double ); 4725 4726 float nexttoward( float, long double );§\indexc{nexttoward}§ 4727 double nexttoward( double, long double ); 4728 long double nexttoward( long double, long double ); 4729 4730 float scalbn( float, int );§\indexc{scalbn}§ 4731 double scalbn( double, int ); 4732 long double scalbn( long double, int ); 4733 4734 float scalbln( float, long int );§\indexc{scalbln}§ 4735 double scalbln( double, long int ); 4736 long double scalbln( long double, long int ); 4455 4737 \end{lstlisting} 4456 4738 … … 4464 4746 \begin{lstlisting} 4465 4747 // implementation 4466 struct Rational { 4748 struct Rational {§\indexc{Rational}§ 4467 4749 long int numerator, denominator; // invariant: denominator > 0 4468 4750 }; // Rational -
src/CodeGen/CodeGenerator.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // CodeGenerator.cc -- 7 // CodeGenerator.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Mar 2 17:32:16201613 // Update Count : 2 4311 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 06 16:01:00 2016 13 // Update Count : 255 14 14 // 15 15 … … 67 67 string mangleName( DeclarationWithType *decl ) { 68 68 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(); 70 71 } else { 71 72 return decl->get_name(); … … 75 76 //*** Declarations 76 77 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 } 77 98 handleStorageClass( functionDecl ); 78 99 if ( functionDecl->get_isInline() ) { … … 99 120 handleStorageClass( objectDecl ); 100 121 output << genType( objectDecl->get_type(), mangleName( objectDecl ) ); 101 122 102 123 if ( objectDecl->get_init() ) { 103 124 output << " = "; … … 113 134 if ( aggDecl->get_name() != "" ) 114 135 output << aggDecl->get_name(); 115 136 116 137 std::list< Declaration * > &memb = aggDecl->get_members(); 117 138 … … 119 140 output << " {" << endl; 120 141 121 cur_indent += CodeGenerator::tabsize; 142 cur_indent += CodeGenerator::tabsize; 122 143 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 123 output << indent; 144 output << indent; 124 145 (*i)->accept( *this ); 125 146 output << ";" << endl; 126 147 } 127 148 128 cur_indent -= CodeGenerator::tabsize; 149 cur_indent -= CodeGenerator::tabsize; 129 150 130 151 output << indent << "}"; … … 141 162 handleAggregate( aggregateDecl ); 142 163 } 143 164 144 165 void CodeGenerator::visit( EnumDecl *aggDecl ) { 145 166 output << "enum "; … … 147 168 if ( aggDecl->get_name() != "" ) 148 169 output << aggDecl->get_name(); 149 170 150 171 std::list< Declaration* > &memb = aggDecl->get_members(); 151 172 … … 153 174 output << " {" << endl; 154 175 155 cur_indent += CodeGenerator::tabsize; 176 cur_indent += CodeGenerator::tabsize; 156 177 for ( std::list< Declaration* >::iterator i = memb.begin(); i != memb.end(); i++) { 157 178 ObjectDecl *obj = dynamic_cast< ObjectDecl* >( *i ); 158 179 assert( obj ); 159 output << indent << mangleName( obj ); 180 output << indent << mangleName( obj ); 160 181 if ( obj->get_init() ) { 161 182 output << " = "; … … 165 186 } // for 166 187 167 cur_indent -= CodeGenerator::tabsize; 188 cur_indent -= CodeGenerator::tabsize; 168 189 169 190 output << indent << "}"; 170 191 } // if 171 192 } 172 193 173 194 void CodeGenerator::visit( TraitDecl *aggregateDecl ) {} 174 195 175 196 void CodeGenerator::visit( TypedefDecl *typeDecl ) { 176 197 output << "typedef "; 177 198 output << genType( typeDecl->get_base(), typeDecl->get_name() ); 178 199 } 179 200 180 201 void CodeGenerator::visit( TypeDecl *typeDecl ) { 181 202 // really, we should mutate this into something that isn't a TypeDecl but that requires large-scale changes, … … 213 234 printDesignators( init->get_designators() ); 214 235 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 } 216 243 output << " }"; 217 244 } 218 245 219 void CodeGenerator::visit( Constant *constant ) { 246 void CodeGenerator::visit( Constant *constant ) { 220 247 output << constant->get_value() ; 221 248 } … … 231 258 case OT_POSTFIXASSIGN: 232 259 case OT_INFIXASSIGN: 260 case OT_CTOR: 261 case OT_DTOR: 233 262 { 234 263 assert( arg != applicationExpr->get_args().end() ); 235 264 if ( AddressExpr *addrExpr = dynamic_cast< AddressExpr * >( *arg ) ) { 236 265 // remove & from first assignment/ctor argument 237 266 *arg = addrExpr->get_arg(); 238 267 } else { 268 // no address-of operator, so must be a pointer - add dereference 239 269 UntypedExpr *newExpr = new UntypedExpr( new NameExpr( "*?" ) ); 240 270 newExpr->get_args().push_back( *arg ); … … 243 273 break; 244 274 } 245 275 246 276 default: 247 277 // do nothing 248 278 ; 249 279 } 250 280 251 281 switch ( opInfo.type ) { 252 282 case OT_INDEX: … … 257 287 output << "]"; 258 288 break; 259 289 260 290 case OT_CALL: 261 291 // there are no intrinsic definitions of the function call operator 262 292 assert( false ); 263 293 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 265 316 case OT_PREFIX: 266 317 case OT_PREFIXASSIGN: … … 271 322 output << ")"; 272 323 break; 273 324 274 325 case OT_POSTFIX: 275 326 case OT_POSTFIXASSIGN: … … 278 329 output << opInfo.symbol; 279 330 break; 331 280 332 281 333 case OT_INFIX: … … 288 340 output << ")"; 289 341 break; 290 342 291 343 case OT_CONSTANT: 292 344 case OT_LABELADDRESS: … … 307 359 } // if 308 360 } 309 361 310 362 void CodeGenerator::visit( UntypedExpr *untypedExpr ) { 311 363 if ( NameExpr *nameExpr = dynamic_cast< NameExpr* >( untypedExpr->get_function() ) ) { … … 321 373 output << "]"; 322 374 break; 323 375 324 376 case OT_CALL: 325 377 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 328 401 case OT_PREFIX: 329 402 case OT_PREFIXASSIGN: … … 335 408 output << ")"; 336 409 break; 337 410 338 411 case OT_POSTFIX: 339 412 case OT_POSTFIXASSIGN: … … 342 415 output << opInfo.symbol; 343 416 break; 344 417 345 418 case OT_INFIX: 346 419 case OT_INFIXASSIGN: … … 352 425 output << ")"; 353 426 break; 354 427 355 428 case OT_CONSTANT: 356 429 // there are no intrinsic definitions of 0 or 1 as functions … … 370 443 } // if 371 444 } 372 445 373 446 void CodeGenerator::visit( NameExpr *nameExpr ) { 374 447 OperatorInfo opInfo; … … 380 453 } // if 381 454 } 382 455 383 456 void CodeGenerator::visit( AddressExpr *addressExpr ) { 384 457 output << "(&"; … … 409 482 output << ")"; 410 483 } 411 484 412 485 void CodeGenerator::visit( UntypedMemberExpr *memberExpr ) { 413 486 assert( false ); 414 487 } 415 488 416 489 void CodeGenerator::visit( MemberExpr *memberExpr ) { 417 490 memberExpr->get_aggregate()->accept( *this ); 418 491 output << "." << mangleName( memberExpr->get_member() ); 419 492 } 420 493 421 494 void CodeGenerator::visit( VariableExpr *variableExpr ) { 422 495 OperatorInfo opInfo; … … 427 500 } // if 428 501 } 429 502 430 503 void CodeGenerator::visit( ConstantExpr *constantExpr ) { 431 504 assert( constantExpr->get_constant() ); 432 505 constantExpr->get_constant()->accept( *this ); 433 506 } 434 507 435 508 void CodeGenerator::visit( SizeofExpr *sizeofExpr ) { 436 509 output << "sizeof("; … … 469 542 assert( false && "OffsetPackExpr should not reach code generation" ); 470 543 } 471 544 472 545 void CodeGenerator::visit( LogicalExpr *logicalExpr ) { 473 546 output << "("; … … 481 554 output << ")"; 482 555 } 483 556 484 557 void CodeGenerator::visit( ConditionalExpr *conditionalExpr ) { 485 558 output << "("; … … 491 564 output << ")"; 492 565 } 493 566 494 567 void CodeGenerator::visit( CommaExpr *commaExpr ) { 495 568 output << "("; … … 499 572 output << ")"; 500 573 } 501 574 502 575 void CodeGenerator::visit( TupleExpr *tupleExpr ) {} 503 576 504 577 void CodeGenerator::visit( TypeExpr *typeExpr ) {} 505 578 … … 532 605 } 533 606 } 534 cur_indent -= CodeGenerator::tabsize; 607 cur_indent -= CodeGenerator::tabsize; 535 608 536 609 output << indent << "}"; … … 538 611 539 612 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, 542 615 // with an explanation 543 616 assert( exprStmt ); … … 589 662 switchStmt->get_condition()->accept( *this ); 590 663 output << " ) "; 591 664 592 665 output << "{" << std::endl; 593 666 cur_indent += CodeGenerator::tabsize; … … 609 682 } // if 610 683 output << ":\n"; 611 684 612 685 std::list<Statement *> sts = caseStmt->get_statements(); 613 686 … … 626 699 if ( ! branchStmt->get_target().empty() ) 627 700 output << "goto " << branchStmt->get_target(); 628 else { 701 else { 629 702 if ( branchStmt->get_computedTarget() != 0 ) { 630 703 output << "goto *"; … … 677 750 678 751 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 681 754 output << "for (;"; 682 755 … … 702 775 void CodeGenerator::visit( DeclStmt *declStmt ) { 703 776 declStmt->get_decl()->accept( *this ); 704 777 705 778 if ( doSemicolon( declStmt->get_decl() ) ) { 706 779 output << ";"; -
src/CodeGen/FixNames.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // FixNames.cc -- 7 // FixNames.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon May 18 23:36:42 201511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon Apr 11 15:38:10 2016 13 13 // Update Count : 1 14 14 // … … 26 26 virtual void visit( ObjectDecl *objectDecl ); 27 27 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 ); 28 35 }; 29 36 … … 33 40 } 34 41 35 void fixDWT( DeclarationWithType *dwt ) {42 void FixNames::fixDWT( DeclarationWithType *dwt ) { 36 43 if ( dwt->get_name() != "" ) { 37 44 if ( LinkageSpec::isDecoratable( dwt->get_linkage() ) ) { 38 45 dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) ); 46 dwt->set_scopeLevel( scopeLevel ); 39 47 } // if 40 48 } // if … … 50 58 fixDWT( functionDecl ); 51 59 } 60 61 void FixNames::visit( CompoundStmt *compoundStmt ) { 62 scopeLevel++; 63 Visitor::visit( compoundStmt ); 64 scopeLevel--; 65 } 52 66 } // namespace CodeGen 53 67 -
src/CodeGen/OperatorTable.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // OperatorTable.cc -- 7 // OperatorTable.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T ue Jun 23 17:41:14 201513 // Update Count : 511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Apr 14 16:48:27 2016 13 // Update Count : 9 14 14 // 15 15 … … 21 21 const OperatorInfo tableValues[] = { 22 22 { "?[?]", "", "_operator_index", OT_INDEX }, 23 { "?{}", "=", "_constructor", OT_CTOR }, 24 { "^?{}", "", "_destructor", OT_DTOR }, 23 25 { "?()", "", "_operator_call", OT_CALL }, 24 26 { "?++", "++", "_operator_postincr", OT_POSTFIXASSIGN }, -
src/CodeGen/OperatorTable.h
rbb8ea30 rd668182 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Tue Jun 23 16:09:27 201513 // Update Count : 311 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Jun 24 16:17:57 2015 13 // Update Count : 5 14 14 // 15 15 … … 22 22 enum OperatorType { 23 23 OT_INDEX, 24 OT_CTOR, 25 OT_DTOR, 24 26 OT_CALL, 25 27 OT_PREFIX, -
src/GenPoly/Box.cc
rbb8ea30 rd668182 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Feb 5 16:45:07 201613 // Update Count : 2 8611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Tue May 03 16:44:47 2016 13 // Update Count : 295 14 14 // 15 15 … … 133 133 Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const { 134 134 TypeList typeList( params ); 135 135 136 136 // scan scopes for matches to the key 137 137 for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) { … … 160 160 virtual Declaration *mutate( UnionDecl *unionDecl ); 161 161 }; 162 162 163 163 /// 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 164 164 class Pass1 : public PolyMutator { … … 208 208 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; ///< Currently known assignment operators 209 209 ScopedMap< std::string, DeclarationWithType* > adapters; ///< Set of adapter functions in the current scope 210 210 211 211 DeclarationWithType *retval; 212 212 bool useRetval; … … 226 226 virtual Type *mutate( PointerType *pointerType ); 227 227 virtual Type *mutate( FunctionType *funcType ); 228 228 229 229 private: 230 230 void addAdapters( FunctionType *functionType ); … … 297 297 /// Exits the type-variable scope 298 298 void endTypeScope(); 299 299 300 300 ScopedSet< std::string > knownLayouts; ///< Set of generic type layouts known in the current scope, indexed by sizeofName 301 301 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName … … 351 351 PolyGenericCalculator polyCalculator; 352 352 Pass3 pass3; 353 353 354 354 layoutBuilder.mutateDeclarationList( translationUnit ); 355 355 mutateTranslationUnit/*All*/( translationUnit, pass1 ); … … 370 370 return functionDecl; 371 371 } 372 372 373 373 /// Get a list of type declarations that will affect a layout function 374 374 std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) { … … 380 380 } 381 381 } 382 382 383 383 return otypeDecls; 384 384 } … … 387 387 void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) { 388 388 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 389 389 390 390 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 391 391 TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param ); … … 444 444 return makeCond( ifCond, ifExpr ); 445 445 } 446 446 447 447 /// adds an expression to a compound statement 448 448 void addExpr( CompoundStmt *stmts, Expression *expr ) { … … 454 454 stmts->get_kids().push_back( stmt ); 455 455 } 456 456 457 457 Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) { 458 458 // do not generate layout function for "empty" tag structs … … 467 467 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 468 468 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 469 469 470 470 ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 471 471 layoutFnType->get_parameters().push_back( sizeParam ); … … 497 497 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) ); 498 498 } 499 499 500 500 // 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 ) ) ), 502 502 derefVar( sizeParam ) ) ); 503 503 ++n_members; … … 505 505 // add member size to current size 506 506 addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) ); 507 507 508 508 // take max of member alignment and global alignment 509 509 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) ); … … 515 515 return structDecl; 516 516 } 517 517 518 518 Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) { 519 519 // do not generate layout function for "empty" tag unions 520 520 if ( unionDecl->get_members().empty() ) return unionDecl; 521 521 522 522 // get parameters that can change layout, exiting early if none 523 523 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() ); … … 528 528 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 529 529 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 530 530 531 531 ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 532 532 layoutFnType->get_parameters().push_back( sizeParam ); … … 545 545 assert( dwt ); 546 546 Type *memberType = dwt->get_type(); 547 547 548 548 // take max member size and global size 549 549 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) ); 550 550 551 551 // take max of member alignment and global alignment 552 552 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) ); … … 558 558 return unionDecl; 559 559 } 560 560 561 561 ////////////////////////////////////////// Pass1 //////////////////////////////////////////////////// 562 562 … … 619 619 return 0; 620 620 } 621 621 622 622 /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise 623 623 /// Only picks assignments where neither parameter is cv-qualified … … 631 631 Type *paramType2 = funType->get_parameters().back()->get_type(); 632 632 if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0; 633 633 634 634 if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) { 635 635 Type *baseType1 = pointerType->get_base(); … … 784 784 arg++; 785 785 } 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 ); 787 788 } // if 788 789 } // if … … 803 804 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 804 805 } 805 806 806 807 // add type information args for presently unseen types in parameter list 807 808 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { … … 882 883 assert( env ); 883 884 Type *concrete = replaceWithConcrete( appExpr, polyType ); 884 // add out-parameter for return value 885 // add out-parameter for return value 885 886 return addRetParam( appExpr, function, concrete, arg ); 886 887 } … … 910 911 } else if ( arg->get_results().front()->get_isLvalue() ) { 911 912 // 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 912 914 if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) { 913 915 commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) ); … … 1291 1293 } else if ( needsAdapter( function, scopeTyVars ) ) { 1292 1294 // 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; 1297 1297 // change the application so it calls the adapter rather than the passed function 1298 1298 ret = applyAdapter( appExpr, function, arg, scopeTyVars ); … … 1345 1345 } // if 1346 1346 } // 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 ); 1347 1350 addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) ); 1348 if ( isPolyType( addrExpr->get_arg()->get_results().front(), scopeTyVars, env )|| needs ) {1351 if ( polytype || needs ) { 1349 1352 Expression *ret = addrExpr->get_arg(); 1350 1353 delete ret->get_results().front(); … … 1366 1369 return new VariableExpr( functionObj ); 1367 1370 } 1368 1371 1369 1372 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 1370 1373 if ( retval && returnStmt->get_expr() ) { … … 1886 1889 } 1887 1890 } 1888 1891 1889 1892 Type *ret = Mutator::mutate( funcType ); 1890 1893 … … 1905 1908 1906 1909 std::list<Expression*> designators; 1907 objectDecl->set_init( new SingleInit( alloc, designators ) );1910 objectDecl->set_init( new SingleInit( alloc, designators, false ) ); // not constructed 1908 1911 } 1909 1912 } … … 1946 1949 return derefdVar; 1947 1950 } 1948 1951 1949 1952 Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) { 1950 1953 // mutate, exiting early if no longer MemberExpr … … 2066 2069 if ( n_members == 0 ) { 2067 2070 // 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 ) ) ) ); 2070 2073 // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array 2071 2074 } else { 2072 2075 ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType ); 2073 2076 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 ) ); 2075 2078 2076 2079 // generate call to layout function … … 2144 2147 Type *ty = offsetofExpr->get_type(); 2145 2148 if ( ! findGeneric( ty ) ) return offsetofExpr; 2146 2149 2147 2150 if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) { 2148 2151 // replace offsetof expression by index into offset array … … 2191 2194 2192 2195 // 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 ), 2194 2197 new ListInit( inits ) ); 2195 2198 ret = new VariableExpr( offsetArray ); -
src/GenPoly/CopyParams.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // CopyParams.cc -- 7 // CopyParams.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr11 // Last Modified By : Rob Schluntz 12 12 // Last Modified On : Tue May 19 07:33:31 2015 13 13 // Update Count : 1 … … 29 29 public: 30 30 CopyParams(); 31 31 32 32 virtual void visit( FunctionDecl *funcDecl ); 33 33 virtual void visit( AddressExpr *addrExpr ); … … 50 50 if ( funcDecl->get_statements() ) { 51 51 funcDecl->get_statements()->accept( *this ); 52 52 53 53 if ( ! modVars.empty() ) { 54 54 std::map< std::string, DeclarationWithType* > assignOps; … … 57 57 if ( (*tyVar)->get_kind() == TypeDecl::Any ) { 58 58 assert( !(*tyVar)->get_assertions().empty() ); 59 assert( (*tyVar)->get_assertions().front()->get_name() == "?=?" ); 59 60 assignOps[ (*tyVar)->get_name() ] = (*tyVar)->get_assertions().front(); 60 61 } // if -
src/GenPoly/GenPoly.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // GenPoly.cc -- 7 // GenPoly.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Tue Dec 15 16:11:18 201511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon May 02 14:53:33 2016 13 13 // Update Count : 13 14 14 // … … 81 81 return 0; 82 82 } 83 83 84 84 Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) { 85 85 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( type ) ) { … … 112 112 return 0; 113 113 } 114 114 115 115 Type *isPolyPtr( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) { 116 116 if ( PointerType *ptr = dynamic_cast< PointerType *>( type ) ) { … … 146 146 return isPolyType( type, env ); 147 147 } 148 148 149 149 Type * hasPolyBase( Type *type, const TyVarMap &tyVars, int *levels, const TypeSubstitution *env ) { 150 150 int dummy; … … 192 192 if ( ! fn || fn->get_name() != std::string("*?") ) return 0; 193 193 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; 194 198 } else break; 195 199 … … 209 213 } 210 214 } 211 215 212 216 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ) { 213 217 for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) { -
src/GenPoly/PolyMutator.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // PolyMutator.cc -- 7 // PolyMutator.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri Aug 14 15:28:50 201512 // Last Modified On : Mon May 02 14:50:58 2016 13 13 // Update Count : 11 14 14 // … … 63 63 env = expr->get_env(); 64 64 } 65 // xxx - should env be cloned (or moved) onto the result of the mutate? 65 66 return expr->acceptMutator( *this ); 66 67 } else { … … 144 145 return untypedExpr; 145 146 } 146 147 147 148 148 149 Initializer *PolyMutator::mutate( SingleInit *singleInit ) { 149 150 singleInit->set_value( mutateExpression( singleInit->get_value() ) ); -
src/GenPoly/Specialize.cc
rbb8ea30 rd668182 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Jan 20 12:40:33201613 // Update Count : 1812 // Last Modified On : Thu Apr 28 15:17:45 2016 13 // Update Count : 24 14 14 // 15 15 … … 41 41 virtual Expression * mutate( AddressExpr *castExpr ); 42 42 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 ); 46 46 47 47 private: … … 142 142 143 143 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 145 145 if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) { 146 146 FunctionType *funType; … … 212 212 } 213 213 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 // } 225 229 } // namespace GenPoly 226 230 -
src/InitTweak/InitModel.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // InitModel.cc -- 7 // InitModel.cc -- 8 8 // 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T ue May 19 16:37:08 201513 // Update Count : 111 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Jan 07 13:38:46 2016 13 // Update Count : 5 14 14 // 15 15 … … 198 198 assert(init == 0 && single != 0); 199 199 std::list< Expression * > empty; 200 init = new SingleInit( single->get_expr(), empty );200 init = new SingleInit( single->get_expr(), empty, false ); // cannot be constructed 201 201 return; 202 202 } … … 214 214 } // if 215 215 216 init = new ListInit( contents ); 216 std::list< Expression * > desig; 217 init = new ListInit( contents, desig, false ); // cannot be constructed 217 218 return; 218 219 } -
src/InitTweak/module.mk
rbb8ea30 rd668182 11 11 ## Created On : Mon Jun 1 17:49:17 2015 12 12 ## Last Modified By : Rob Schluntz 13 ## Last Modified On : Mon Jan 11 14:40:16201614 ## Update Count : 213 ## Last Modified On : Fri May 13 11:36:24 2016 14 ## Update Count : 3 15 15 ############################################################################### 16 16 17 SRC += InitTweak/RemoveInit.cc 17 SRC += InitTweak/GenInit.cc \ 18 InitTweak/FixInit.cc \ 19 InitTweak/FixGlobalInit.cc \ 20 InitTweak/InitTweak.cc 18 21 -
src/MakeLibCfa.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // MakeLibCfa.cc -- 7 // MakeLibCfa.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 10:33:33 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Jun 26 16:52:59 201513 // Update Count : 1414 // 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri Apr 22 13:54:15 2016 13 // Update Count : 40 14 // 15 15 16 16 #include "MakeLibCfa.h" … … 29 29 void visit( FunctionDecl* funcDecl ); 30 30 void visit( ObjectDecl* objDecl ); 31 31 32 32 std::list< Declaration* > &get_newDecls() { return newDecls; } 33 33 private: … … 43 43 void MakeLibCfa::visit( FunctionDecl* origFuncDecl ) { 44 44 if ( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return; 45 45 if ( origFuncDecl->get_statements() ) return; 46 46 47 FunctionDecl *funcDecl = origFuncDecl->clone(); 47 48 CodeGen::OperatorInfo opInfo; … … 54 55 assert( param != funcDecl->get_functionType()->get_parameters().end() ); 55 56 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 ); 60 67 61 68 switch ( opInfo.type ) { … … 65 72 case CodeGen::OT_POSTFIX: 66 73 case CodeGen::OT_INFIX: 67 newExpr->get_args().push_back( new VariableExpr( *param ) );68 break;69 74 case CodeGen::OT_PREFIXASSIGN: 70 75 case CodeGen::OT_POSTFIXASSIGN: 71 76 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 ) ); 77 78 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; 79 98 case CodeGen::OT_CONSTANT: 80 99 case CodeGen::OT_LABELADDRESS: … … 82 101 assert( false ); 83 102 } // 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 } // for92 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 );95 103 } 96 104 97 105 void MakeLibCfa::visit( ObjectDecl* origObjDecl ) { 98 106 if ( origObjDecl->get_linkage() != LinkageSpec::Intrinsic ) return; 99 107 100 108 ObjectDecl *objDecl = origObjDecl->clone(); 101 109 assert( ! objDecl->get_init() ); 102 110 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 104 112 newDecls.push_back( objDecl ); 105 113 } 106 114 } // 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 123 123 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \ 124 124 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) \ 126 129 Parser/driver_cfa_cpp-parser.$(OBJEXT) \ 127 130 Parser/driver_cfa_cpp-lex.$(OBJEXT) \ … … 159 162 SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT) \ 160 163 SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT) \ 164 SymTab/driver_cfa_cpp-Autogen.$(OBJEXT) \ 161 165 SynTree/driver_cfa_cpp-Type.$(OBJEXT) \ 162 166 SynTree/driver_cfa_cpp-VoidType.$(OBJEXT) \ … … 345 349 GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \ 346 350 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 \ 353 359 ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \ 354 360 ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \ … … 362 368 SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \ 363 369 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 \ 368 375 SynTree/VarArgsType.cc SynTree/Constant.cc \ 369 376 SynTree/Expression.cc SynTree/TupleExpr.cc \ … … 561 568 @$(MKDIR_P) InitTweak/$(DEPDIR) 562 569 @: > InitTweak/$(DEPDIR)/$(am__dirstamp) 563 InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT): \ 570 InitTweak/driver_cfa_cpp-GenInit.$(OBJEXT): InitTweak/$(am__dirstamp) \ 571 InitTweak/$(DEPDIR)/$(am__dirstamp) 572 InitTweak/driver_cfa_cpp-FixInit.$(OBJEXT): InitTweak/$(am__dirstamp) \ 573 InitTweak/$(DEPDIR)/$(am__dirstamp) 574 InitTweak/driver_cfa_cpp-FixGlobalInit.$(OBJEXT): \ 575 InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp) 576 InitTweak/driver_cfa_cpp-InitTweak.$(OBJEXT): \ 564 577 InitTweak/$(am__dirstamp) InitTweak/$(DEPDIR)/$(am__dirstamp) 565 578 Parser/parser.h: Parser/parser.cc … … 670 683 SymTab/driver_cfa_cpp-TypeEquality.$(OBJEXT): SymTab/$(am__dirstamp) \ 671 684 SymTab/$(DEPDIR)/$(am__dirstamp) 685 SymTab/driver_cfa_cpp-Autogen.$(OBJEXT): SymTab/$(am__dirstamp) \ 686 SymTab/$(DEPDIR)/$(am__dirstamp) 672 687 SynTree/$(am__dirstamp): 673 688 @$(MKDIR_P) SynTree … … 792 807 -rm -f GenPoly/driver_cfa_cpp-ScrubTyVars.$(OBJEXT) 793 808 -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) 795 813 -rm -f Parser/driver_cfa_cpp-DeclarationNode.$(OBJEXT) 796 814 -rm -f Parser/driver_cfa_cpp-ExpressionNode.$(OBJEXT) … … 822 840 -rm -f ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) 823 841 -rm -f ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT) 842 -rm -f SymTab/driver_cfa_cpp-Autogen.$(OBJEXT) 824 843 -rm -f SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT) 825 844 -rm -f SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT) … … 897 916 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-ScrubTyVars.Po@am__quote@ 898 917 @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@ 900 922 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-DeclarationNode.Po@am__quote@ 901 923 @AMDEP_TRUE@@am__include@ @am__quote@Parser/$(DEPDIR)/driver_cfa_cpp-ExpressionNode.Po@am__quote@ … … 927 949 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-TypeEnvironment.Po@am__quote@ 928 950 @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@ 929 952 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po@am__quote@ 930 953 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po@am__quote@ … … 1366 1389 @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` 1367 1390 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` 1391 InitTweak/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 1398 InitTweak/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 1405 InitTweak/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 1412 InitTweak/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 1419 InitTweak/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 1426 InitTweak/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 1433 InitTweak/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 1440 InitTweak/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` 1381 1446 1382 1447 Parser/driver_cfa_cpp-parser.o: Parser/parser.cc … … 1869 1934 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1870 1935 @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 1937 SymTab/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 1944 SymTab/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` 1871 1950 1872 1951 SynTree/driver_cfa_cpp-Type.o: SynTree/Type.cc -
src/Parser/DeclarationNode.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // DeclarationNode.cc -- 7 // DeclarationNode.cc -- 8 8 // 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 12:34:05 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Apr 13 16:53:17201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Apr 14 15:38:09 2016 13 13 // Update Count : 161 14 14 // … … 97 97 os << endl << string( indent + 2, ' ' ) << "with initializer "; 98 98 initializer->printOneLine( os ); 99 os << " maybe constructed? " << initializer->get_maybeConstructed(); 100 99 101 } // if 100 102 … … 353 355 } // if 354 356 } 355 357 356 358 DeclarationNode *DeclarationNode::addQualifiers( DeclarationNode *q ) { 357 359 if ( q ) { … … 504 506 assert( false ); 505 507 } // switch 506 508 507 509 return this; 508 510 } … … 615 617 assert( a->type->kind == TypeData::Array ); 616 618 TypeData *lastArray = findLast( a->type ); 617 if ( type ) { 619 if ( type ) { 618 620 switch ( type->kind ) { 619 621 case TypeData::Aggregate: … … 659 661 } // if 660 662 } 661 663 662 664 DeclarationNode *DeclarationNode::addIdList( DeclarationNode *ids ) { 663 665 type = addIdListToType( type, ids ); … … 864 866 Type *DeclarationNode::buildType() const { 865 867 assert( type ); 866 868 867 869 switch ( type->kind ) { 868 870 case TypeData::Enum: -
src/Parser/InitializerNode.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // InitializerNode.cc -- 8 // 7 // InitializerNode.cc -- 8 // 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:20:24 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Oct 8 17:18:55 201513 // Update Count : 414 // 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Jan 07 13:32:57 2016 13 // Update Count : 13 14 // 15 15 16 16 #include <cassert> … … 23 23 24 24 InitializerNode::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 ) { 26 26 if ( aggrp ) 27 27 kids = dynamic_cast< InitializerNode *>( get_link() ); … … 32 32 33 33 InitializerNode::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 ) { 35 35 if ( init != 0 ) 36 36 set_link(init); … … 91 91 } // if 92 92 93 return new ListInit( initlist, designlist );93 return new ListInit( initlist, designlist, maybeConstructed ); 94 94 } else { 95 95 std::list< Expression *> designators; … … 99 99 100 100 if ( get_expression() != 0) 101 return new SingleInit( get_expression()->build(), designators );101 return new SingleInit( get_expression()->build(), designators, maybeConstructed ); 102 102 } // if 103 103 -
src/Parser/ParseNode.h
rbb8ea30 rd668182 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon Apr 11 11:50:52 201612 // Last Modified On : Thu Apr 14 15:37:52 2016 13 13 // Update Count : 205 14 14 // … … 185 185 // monadic 186 186 UnPlus, UnMinus, AddressOf, PointTo, Neg, BitNeg, Incr, IncrPost, Decr, DecrPost, LabelAddress, 187 Ctor, Dtor, 187 188 }; 188 189 … … 525 526 ExpressionNode *get_designators() const { return designator; } 526 527 528 InitializerNode *set_maybeConstructed( bool value ) { maybeConstructed = value; return this; } 529 bool get_maybeConstructed() const { return maybeConstructed; } 530 527 531 InitializerNode *next_init() const { return kids; } 528 532 … … 536 540 ExpressionNode *designator; // may be list 537 541 InitializerNode *kids; 542 bool maybeConstructed; 538 543 }; 539 544 -
src/Parser/TypeData.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // TypeData.cc -- 7 // TypeData.cc -- 8 8 // 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 15:12:51 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Mar 2 17:26:45201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Apr 06 16:57:53 2016 13 13 // Update Count : 49 14 14 // … … 449 449 for ( std::list< TypeDecl* >::iterator i = outputList.begin(); i != outputList.end(); ++i ) { 450 450 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) 451 469 FunctionType *assignType = new FunctionType( Type::Qualifiers(), false ); 452 470 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 ) ); … … 902 920 if ( cur->get_enumeratorValue() != NULL ) { 903 921 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 * >() ) ); 905 923 } // if 906 924 } // for -
src/Parser/parser.cc
rbb8ea30 rd668182 7468 7468 /* Line 1806 of yacc.c */ 7469 7469 #line 1704 "parser.yy" 7470 { (yyval.in) = (yyvsp[(2) - (2)].in) ; }7470 { (yyval.in) = (yyvsp[(2) - (2)].in)->set_maybeConstructed( false ); } 7471 7471 break; 7472 7472 -
src/Parser/parser.yy
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // cfa.y -- 8 // 7 // cfa.y -- 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 1 20:22:55 2001 … … 12 12 // Last Modified On : Wed Apr 13 16:58:43 2016 13 13 // Update Count : 1519 14 // 14 // 15 15 16 16 // This grammar is based on the ANSI99/11 C grammar, specifically parts of EXPRESSION and STATEMENTS, and on the C … … 1702 1702 { $$ = $2; } 1703 1703 | ATassign initializer 1704 { $$ = $2 ; }1704 { $$ = $2->set_maybeConstructed( false ); } 1705 1705 ; 1706 1706 -
src/ResolvExpr/AlternativeFinder.cc
rbb8ea30 rd668182 10 10 // Created On : Sat May 16 23:52:08 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Feb 10 17:00:04201612 // Last Modified On : Wed Apr 20 14:24:03 2016 13 13 // Update Count : 24 14 14 // … … 982 982 } // for 983 983 } 984 985 void AlternativeFinder::visit( ImplicitCopyCtorExpr * impCpCtorExpr ) { 986 alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) ); 987 } 984 988 } // namespace ResolvExpr 985 989 -
src/ResolvExpr/AlternativeFinder.h
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // AlternativeFinder.h -- 7 // AlternativeFinder.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 23:56:12 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat May 16 23:58:43 201511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Tue Apr 19 11:44:53 2016 13 13 // Update Count : 2 14 // 14 // 15 15 16 16 #ifndef ALTERNATIVEFINDER_H … … 54 54 virtual void visit( NameExpr *variableExpr ); 55 55 virtual void visit( VariableExpr *variableExpr ); 56 virtual void visit( ConstantExpr *constantExpr ); 56 virtual void visit( ConstantExpr *constantExpr ); 57 57 virtual void visit( SizeofExpr *sizeofExpr ); 58 58 virtual void visit( AlignofExpr *alignofExpr ); … … 65 65 virtual void visit( CommaExpr *commaExpr ); 66 66 virtual void visit( TupleExpr *tupleExpr ); 67 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ); 67 68 public: // xxx - temporary hack - should make Tuples::TupleAssignment a friend 68 69 template< typename InputIterator, typename OutputIterator > -
src/ResolvExpr/Resolver.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Resolver.cc -- 7 // Resolver.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:17:01 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Mar 24 16:43:11201613 // Update Count : 18111 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 13 11:36:40 2016 13 // Update Count : 203 14 14 // 15 15 … … 25 25 #include "SymTab/Indexer.h" 26 26 #include "Common/utility.h" 27 #include "InitTweak/InitTweak.h" 27 28 28 29 #include <iostream> … … 33 34 public: 34 35 Resolver() : SymTab::Indexer( false ), switchType( 0 ) {} 35 36 36 37 virtual void visit( FunctionDecl *functionDecl ); 37 38 virtual void visit( ObjectDecl *functionDecl ); … … 54 55 virtual void visit( SingleInit *singleInit ); 55 56 virtual void visit( ListInit *listInit ); 57 virtual void visit( ConstructorInit *ctorInit ); 56 58 private: 57 59 typedef std::list< Initializer * >::iterator InitIterator; … … 59 61 void resolveAggrInit( AggregateDecl *, InitIterator &, InitIterator & ); 60 62 void resolveSingleAggrInit( Declaration *, InitIterator &, InitIterator & ); 61 63 void fallbackInit( ConstructorInit * ctorInit ); 62 64 std::list< Type * > functionReturn; 63 65 Type *initContext; … … 82 84 } 83 85 86 84 87 namespace { 85 88 void finishExpr( Expression *expr, const TypeEnvironment &env ) { … … 87 90 env.makeSubstitution( *expr->get_env() ); 88 91 } 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 { 98 103 Expression *findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 99 104 TypeEnvironment env; … … 126 131 } // if 127 132 } 128 133 129 134 Expression *findIntegralExpression( Expression *untyped, const SymTab::Indexer &indexer ) { 130 135 TypeEnvironment env; … … 159 164 return newExpr; 160 165 } 161 162 } 163 166 167 } 168 164 169 void Resolver::visit( ObjectDecl *objectDecl ) { 165 170 Type *new_type = resolveTypeof( objectDecl->get_type(), *this ); … … 258 263 forStmt->set_condition( newExpr ); 259 264 } // if 260 265 261 266 if ( forStmt->get_increment() ) { 262 267 Expression * newExpr = findVoidExpression( forStmt->get_increment(), *this ); … … 272 277 delete switchStmt->get_condition(); 273 278 switchStmt->set_condition( newExpr ); 274 279 275 280 visitor.Visitor::visit( switchStmt ); 276 281 } … … 314 319 bool isCharType( T t ) { 315 320 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 || 317 322 bt->get_kind() == BasicType::UnsignedChar; 318 323 } … … 326 331 string n = ne->get_name(); 327 332 if (n == "0") { 328 initContext = new BasicType(Type::Qualifiers(), 333 initContext = new BasicType(Type::Qualifiers(), 329 334 BasicType::SignedInt); 330 335 } else { … … 332 337 initContext = decl->get_type(); 333 338 } 334 } else if (ConstantExpr * e = 339 } else if (ConstantExpr * e = 335 340 dynamic_cast<ConstantExpr*>(singleInit->get_value())) { 336 341 Constant *c = e->get_constant(); … … 355 360 singleInit->set_value( ce->get_arg() ); 356 361 ce->set_arg( NULL ); 357 delete ce; 362 delete ce; 358 363 } 359 364 } … … 471 476 #endif 472 477 } 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 } 473 515 } // namespace ResolvExpr 474 516 -
src/ResolvExpr/Resolver.h
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Resolver.h -- 7 // Resolver.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:18:34 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sun May 17 12:19:32 201511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Apr 14 15:06:53 2016 13 13 // Update Count : 2 14 14 // … … 24 24 void resolve( std::list< Declaration * > translationUnit ); 25 25 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ); 26 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ); 26 27 } // namespace ResolvExpr 27 28 -
src/SymTab/AddVisit.h
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // AddVisit.h -- 7 // AddVisit.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 16:14:32 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Thu Apr 7 14:42:21201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Apr 14 15:52:42 2016 13 13 // Update Count : 5 14 14 // … … 48 48 // maybeAccept( caseStmt->get_condition(), visitor ); 49 49 // } 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 50 65 } // namespace SymTab 51 66 -
src/SymTab/Validate.cc
rbb8ea30 rd668182 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 21:50:04 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Apr 13 16:39:30201613 // Update Count : 2 5111 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed May 11 13:17:52 2016 13 // Update Count : 297 14 14 // 15 15 … … 56 56 #include "MakeLibCfa.h" 57 57 #include "TypeEquality.h" 58 #include "Autogen.h" 58 59 #include "ResolvExpr/typeops.h" 59 60 … … 122 123 123 124 const Indexer *indexer; 124 };125 126 class AutogenerateRoutines : public Visitor {127 public:128 /// Generates assignment operators for aggregate types as required129 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 functions155 125 }; 156 126 … … 192 162 template<typename AggDecl> 193 163 void addImplicitTypedef( AggDecl * aggDecl ); 194 164 195 165 typedef std::map< std::string, std::pair< TypedefDecl *, int > > TypedefMap; 196 166 TypedefMap typedefNames; 197 167 int scopeLevel; 198 168 }; 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 }; 199 179 200 180 class CompoundLiteral : public GenPoly::DeclMutator { … … 217 197 ReturnChecker::checkFunctionReturns( translationUnit ); 218 198 mutateAll( translationUnit, compoundliteral ); 219 AutogenerateRoutines::autogenerateRoutines( translationUnit );199 autogenerateRoutines( translationUnit ); 220 200 acceptAll( translationUnit, pass3 ); 201 VerifyCtorDtor::verify( translationUnit ); 221 202 } 222 203 … … 228 209 type->accept( pass2 ); 229 210 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 } // if242 i = next;243 } // while244 211 } 245 212 … … 503 470 } 504 471 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 accessed516 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 members524 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 assignment538 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 types596 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 units615 // because each unit generates copies of the default routines for each aggregate.616 617 // since there is no definition, these should not be inline618 // make these intrinsic so that the code generator does not make use of them619 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 prelude625 // functions are, so build a list containing the prototypes626 // 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 routine634 for (int start = 0, end = assigns.size()/2; start < end; start++) {635 delete assigns.front();636 assigns.pop_front();637 } // for638 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 list643 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 assertion657 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 applicable676 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 types679 TypeSubstitution genericSubs; // Substitutions to make to member types of struct680 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 units699 // 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 members714 continue;715 }716 717 if ( isGeneric ) {718 // rewrite member type in terms of the type variables on this operator719 DeclarationWithType *fixedMember = dwt->clone();720 genericSubs.apply( fixedMember );721 722 // assign to both destination and return value723 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 } // if730 } else {731 // assign to destination732 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 } // if737 } // if738 } // if739 } // for740 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 applicable749 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 types752 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 units769 // 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 } // if797 }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 } // if805 }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 } // if820 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 } // for832 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 function837 }838 839 void AutogenerateRoutines::visit( PointerType *) {840 // ensure that we don't add assignment ops for types defined as part of the pointer841 }842 843 void AutogenerateRoutines::visit( TraitDecl *) {844 // ensure that we don't add assignment ops for types defined as part of the context845 }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 878 472 void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) { 879 473 ReturnChecker checker; … … 1033 627 return aggDecl; 1034 628 } 1035 629 1036 630 template<typename AggDecl> 1037 631 void EliminateTypedef::addImplicitTypedef( AggDecl * aggDecl ) { … … 1072 666 } 1073 667 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 * > ¶ms = 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 1074 701 DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) { 1075 702 storageclass = objectDecl->get_storageClass(); -
src/SymTab/module.mk
rbb8ea30 rd668182 6 6 ## file "LICENCE" distributed with Cforall. 7 7 ## 8 ## module.mk -- 8 ## module.mk -- 9 9 ## 10 10 ## Author : Richard C. Bilson … … 20 20 SymTab/FixFunction.cc \ 21 21 SymTab/ImplementationType.cc \ 22 SymTab/TypeEquality.cc 22 SymTab/TypeEquality.cc \ 23 SymTab/Autogen.cc -
src/SynTree/CommaExpr.cc
rbb8ea30 rd668182 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon May 02 15:1 1:29201612 // Last Modified On : Mon May 02 15:19:44 2016 13 13 // Update Count : 1 14 14 // -
src/SynTree/CompoundStmt.cc
rbb8ea30 rd668182 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon May 02 15:1 0:47 201612 // Last Modified On : Mon May 02 15:19:17 2016 13 13 // Update Count : 3 14 14 // … … 18 18 #include <algorithm> 19 19 #include <functional> 20 #include "Expression.h" 21 #include "Declaration.h" 20 22 21 23 using std::string; 22 24 using std::endl; 25 26 class VarExprReplacer : public Visitor { 27 public: 28 typedef std::map< DeclarationWithType *, DeclarationWithType * > DeclMap; 29 private: 30 const DeclMap & declMap; 31 public: 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 23 42 24 43 CompoundStmt::CompoundStmt( std::list<Label> labels ) : Statement( labels ) { … … 27 46 CompoundStmt::CompoundStmt( const CompoundStmt &other ) : Statement( other ) { 28 47 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 } 29 79 } 30 80 -
src/SynTree/Constant.cc
rbb8ea30 rd668182 30 30 Constant::~Constant() { delete type; } 31 31 32 Constant Constant::from ( int i ) {32 Constant Constant::from_int( int i ) { 33 33 return Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), std::to_string( i ) ); 34 34 } 35 35 36 Constant Constant::from ( unsigned long i ) {36 Constant Constant::from_ulong( unsigned long i ) { 37 37 return Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::to_string( i ) ); 38 38 } 39 39 40 Constant Constant::from ( double d ) {40 Constant Constant::from_double( double d ) { 41 41 return Constant( new BasicType( Type::Qualifiers(), BasicType::Double ), std::to_string( d ) ); 42 42 } -
src/SynTree/Constant.h
rbb8ea30 rd668182 33 33 34 34 /// generates an integer constant of the given int 35 static Constant from ( int i );35 static Constant from_int( int i ); 36 36 /// 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 ); 38 38 /// generates a floating point constant of the given double 39 static Constant from ( double d );39 static Constant from_double( double d ); 40 40 41 41 virtual Constant *clone() const; -
src/SynTree/Declaration.h
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Declaration.h -- 7 // Declaration.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Mar 2 17:28:11201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 06 16:26:12 2016 13 13 // Update Count : 33 14 14 // … … 22 22 #include "Parser/LinkageSpec.h" 23 23 #include "Parser/ParseNode.h" 24 #include <string> 24 25 25 26 class Declaration { … … 67 68 void set_mangleName( std::string newValue ) { mangleName = newValue; } 68 69 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 69 75 virtual DeclarationWithType *clone() const = 0; 70 76 virtual DeclarationWithType *acceptMutator( Mutator &m ) = 0; … … 75 81 // this represents the type with all types and typedefs expanded it is generated by SymTab::Validate::Pass2 76 82 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; 77 86 }; 78 87 … … 106 115 typedef DeclarationWithType Parent; 107 116 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() ); 109 130 FunctionDecl( const FunctionDecl &other ); 110 131 virtual ~FunctionDecl(); … … 119 140 std::list< std::string >& get_oldIdents() { return oldIdents; } 120 141 std::list< Declaration* >& get_oldDecls() { return oldDecls; } 142 Attribute get_attribute() const { return attribute; } 143 void set_attribute( Attribute newValue ) { attribute = newValue; } 121 144 122 145 virtual FunctionDecl *clone() const { return new FunctionDecl( *this ); } … … 130 153 std::list< std::string > oldIdents; 131 154 std::list< Declaration* > oldDecls; 155 Attribute attribute; 132 156 }; 133 157 -
src/SynTree/DeclarationWithType.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // DeclarationWithType.cc -- 7 // DeclarationWithType.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jun 13 08:08:07 201511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon Apr 11 15:35:27 2016 13 13 // Update Count : 3 14 14 // … … 23 23 24 24 DeclarationWithType::DeclarationWithType( const DeclarationWithType &other ) 25 : Declaration( other ), mangleName( other.mangleName ) {25 : Declaration( other ), mangleName( other.mangleName ), scopeLevel( other.scopeLevel ) { 26 26 } 27 27 -
src/SynTree/Expression.cc
rbb8ea30 rd668182 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 13 13: 19:09201612 // Last Modified On : Fri May 13 13:23:11 2016 13 13 // Update Count : 40 14 14 // … … 78 78 79 79 VariableExpr::VariableExpr( DeclarationWithType *_var, Expression *_aname ) : Expression( _aname ), var( _var ) { 80 assert( var ); 81 assert( var->get_type() ); 80 82 add_result( var->get_type()->clone() ); 81 83 for ( std::list< Type* >::iterator i = get_results().begin(); i != get_results().end(); ++i ) { … … 464 466 } 465 467 468 469 ImplicitCopyCtorExpr::ImplicitCopyCtorExpr( ApplicationExpr * callExpr ) : callExpr( callExpr ) { 470 assert( callExpr ); 471 cloneAll( callExpr->get_results(), results ); 472 } 473 474 ImplicitCopyCtorExpr::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 480 ImplicitCopyCtorExpr::~ImplicitCopyCtorExpr() { 481 delete callExpr; 482 deleteAll( tempDecls ); 483 deleteAll( returnDecls ); 484 deleteAll( dtors ); 485 } 486 487 void 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 466 498 UntypedValofExpr::UntypedValofExpr( const UntypedValofExpr & other ) : Expression( other ), body ( maybeClone( other.body ) ) {} 467 499 -
src/SynTree/Expression.h
rbb8ea30 rd668182 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Apr 8 17:18:06201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Apr 27 17:06:49 2016 13 13 // Update Count : 21 14 14 // … … 22 22 #include "Mutator.h" 23 23 #include "Constant.h" 24 #include "Common/UniqueName.h" 24 25 25 26 /// Expression is the root type for all expressions … … 559 560 }; 560 561 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. 564 class ImplicitCopyCtorExpr : public Expression { 565 public: 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 561 593 /// ValofExpr represents a GCC 'lambda expression' 562 594 class UntypedValofExpr : public Expression { -
src/SynTree/FunctionDecl.cc
rbb8ea30 rd668182 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Tue May 03 15:37:43201612 // Last Modified On : Fri May 06 15:59:48 2016 13 13 // Update Count : 19 14 14 // … … 21 21 #include "Common/utility.h" 22 22 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 ) {23 FunctionDecl::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 ) { 25 25 set_isInline( isInline ); 26 26 set_isNoreturn( isNoreturn ); … … 32 32 33 33 FunctionDecl::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 ) { 35 35 } 36 36 … … 65 65 os << "_Noreturn "; 66 66 } // 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 } 67 80 if ( get_storageClass() != DeclarationNode::NoStorageClass ) { 68 81 os << DeclarationNode::storageName[ get_storageClass() ] << ' '; … … 105 118 os << "_Noreturn "; 106 119 } // 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 } 107 133 if ( get_storageClass() != DeclarationNode::NoStorageClass ) { 108 134 os << DeclarationNode::storageName[ get_storageClass() ] << ' '; -
src/SynTree/Initializer.cc
rbb8ea30 rd668182 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 13 13: 19:30201612 // Last Modified On : Fri May 13 13:23:03 2016 13 13 // Update Count : 28 14 14 // … … 16 16 #include "Initializer.h" 17 17 #include "Expression.h" 18 #include "Statement.h" 18 19 #include "Common/utility.h" 19 20 20 Initializer::Initializer( ) {}21 Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {} 21 22 22 23 Initializer::~Initializer() {} … … 31 32 void Initializer::print( std::ostream &os, int indent ) {} 32 33 33 SingleInit::SingleInit( Expression *v, std::list< Expression *> &_designators ) :value ( v ), designators( _designators ) {34 SingleInit::SingleInit( Expression *v, const std::list< Expression *> &_designators, bool maybeConstructed ) : Initializer( maybeConstructed ), value ( v ), designators( _designators ) { 34 35 } 35 36 36 SingleInit::SingleInit( const SingleInit &other ) : value ( other.value) {37 SingleInit::SingleInit( const SingleInit &other ) : Initializer(other), value ( maybeClone( other.value ) ) { 37 38 cloneAll(other.designators, designators ); 38 39 } … … 56 57 } 57 58 58 ListInit::ListInit( std::list<Initializer*> &_initializers, std::list<Expression *> &_designators)59 : initializers( _initializers ), designators( _designators ) {59 ListInit::ListInit( const std::list<Initializer*> &_initializers, const std::list<Expression *> &_designators, bool maybeConstructed ) 60 : Initializer( maybeConstructed), initializers( _initializers ), designators( _designators ) { 60 61 } 61 62 … … 81 82 (*i)->print( os, indent + 2 ); 82 83 } 84 85 86 ConstructorInit::ConstructorInit( Statement * ctor, Statement * dtor, Initializer * init ) : Initializer( true ), ctor( ctor ), dtor( dtor ), init( init ) {} 87 ConstructorInit::~ConstructorInit() { 88 delete ctor; 89 delete init; 90 } 91 92 ConstructorInit *ConstructorInit::clone() const { 93 return new ConstructorInit( *this ); 94 } 95 96 void 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 117 std::ostream & operator<<( std::ostream & out, Initializer * init ) { 118 init->print( out ); 119 return out; 120 } 121 83 122 // Local Variables: // 84 123 // tab-width: 4 // -
src/SynTree/Initializer.h
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Initializer.h -- 7 // Initializer.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon May 18 09:03:48 201513 // Update Count : 1 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Tue Apr 12 13:49:13 2016 13 // Update Count : 19 14 14 // 15 15 … … 27 27 public: 28 28 // Initializer( std::string _name = std::string(""), int _pos = 0 ); 29 Initializer( );29 Initializer( bool maybeConstructed ); 30 30 virtual ~Initializer(); 31 31 … … 43 43 } 44 44 45 bool get_maybeConstructed() { return maybeConstructed; } 46 45 47 virtual Initializer *clone() const = 0; 46 48 virtual void accept( Visitor &v ) = 0; … … 50 52 // std::string name; 51 53 // int pos; 54 bool maybeConstructed; 52 55 }; 53 56 … … 55 58 class SingleInit : public Initializer { 56 59 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 ); 58 61 SingleInit( const SingleInit &other ); 59 62 virtual ~SingleInit(); 60 63 61 64 Expression *get_value() { return value; } 62 65 void set_value( Expression *newValue ) { value = newValue; } … … 79 82 class ListInit : public Initializer { 80 83 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 ); 83 86 virtual ~ListInit(); 84 87 … … 100 103 }; 101 104 105 // ConstructorInit represents an initializer that is either a constructor expression or 106 // a C-style initializer. 107 class 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 132 std::ostream & operator<<( std::ostream & out, Initializer * init ); 133 102 134 #endif // INITIALIZER_H 103 135 -
src/SynTree/Mutator.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Mutator.cc -- 7 // Mutator.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Apr 1 18:05:16201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Apr 27 17:07:29 2016 13 13 // Update Count : 16 14 14 // … … 337 337 } 338 338 339 Expression* 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 339 346 Expression *Mutator::mutate( UntypedValofExpr *valofExpr ) { 340 347 mutateAll( valofExpr->get_results(), *this ); … … 450 457 } 451 458 459 Initializer *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 452 465 Subrange *Mutator::mutate( Subrange *subrange ) { 453 466 return subrange; -
src/SynTree/Mutator.h
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Mutator.h -- 7 // Mutator.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Apr 1 17:26:56201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Apr 14 15:32:00 2016 13 13 // Update Count : 10 14 14 // … … 62 62 virtual Expression* mutate( MemberExpr *memberExpr ); 63 63 virtual Expression* mutate( VariableExpr *variableExpr ); 64 virtual Expression* mutate( ConstantExpr *constantExpr ); 64 virtual Expression* mutate( ConstantExpr *constantExpr ); 65 65 virtual Expression* mutate( SizeofExpr *sizeofExpr ); 66 66 virtual Expression* mutate( AlignofExpr *alignofExpr ); … … 76 76 virtual Expression* mutate( TypeExpr *typeExpr ); 77 77 virtual Expression* mutate( AsmExpr *asmExpr ); 78 virtual Expression* mutate( ImplicitCopyCtorExpr *impCpCtorExpr ); 78 79 virtual Expression* mutate( UntypedValofExpr *valofExpr ); 79 80 virtual Expression* mutate( CompoundLiteralExpr *compLitExpr ); … … 96 97 virtual Initializer* mutate( SingleInit *singleInit ); 97 98 virtual Initializer* mutate( ListInit *listInit ); 99 virtual Initializer* mutate( ConstructorInit *ctorInit ); 98 100 99 101 virtual Subrange *mutate( Subrange *subrange ); -
src/SynTree/ObjectDecl.cc
rbb8ea30 rd668182 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 13 13:2 0:17201612 // Last Modified On : Fri May 13 13:23:32 2016 13 13 // Update Count : 30 14 14 // … … 19 19 #include "Expression.h" 20 20 #include "Common/utility.h" 21 #include "Statement.h" 21 22 22 23 ObjectDecl::ObjectDecl( const std::string &name, DeclarationNode::StorageClass sc, LinkageSpec::Type linkage, Expression *bitfieldWidth, Type *type, Initializer *init, bool isInline, bool isNoreturn ) … … 58 59 os << " with initializer "; 59 60 init->print( os, indent ); 61 os << std::endl << std::string(indent, ' '); 62 os << "maybeConstructed? " << init->get_maybeConstructed(); 60 63 } // if 61 64 -
src/SynTree/SynTree.h
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // SynTree.h -- 7 // SynTree.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Apr 1 16:47:44201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Apr 14 15:31:36 2016 13 13 // Update Count : 5 14 14 // … … 81 81 class TypeExpr; 82 82 class AsmExpr; 83 class ImplicitCopyCtorExpr; 83 84 class UntypedValofExpr; 84 85 class CompoundLiteralExpr; … … 104 105 class SingleInit; 105 106 class ListInit; 107 class ConstructorInit; 106 108 107 109 class Subrange; -
src/SynTree/TypeSubstitution.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // TypeSubstitution.cc -- 7 // TypeSubstitution.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Mar 2 17:29:15201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Tue Apr 26 11:15:29 2016 13 13 // Update Count : 3 14 14 // … … 96 96 BoundVarsType::const_iterator bound = boundVars.find( inst->get_name() ); 97 97 if ( bound != boundVars.end() ) return inst; 98 98 99 99 TypeEnvType::const_iterator i = typeEnv.find( inst->get_name() ); 100 100 if ( i == typeEnv.end() ) { … … 217 217 } 218 218 219 std::ostream & operator<<( std::ostream & out, const TypeSubstitution & sub ) { 220 sub.print( out ); 221 return out; 222 } 223 224 219 225 // Local Variables: // 220 226 // tab-width: 4 // -
src/SynTree/TypeSubstitution.h
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // TypeSubstitution.h -- 7 // TypeSubstitution.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Mar 2 17:33:19201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri Apr 29 15:00:20 2016 13 13 // Update Count : 2 14 14 // … … 33 33 TypeSubstitution( const TypeSubstitution &other ); 34 34 virtual ~TypeSubstitution(); 35 35 36 36 TypeSubstitution &operator=( const TypeSubstitution &other ); 37 37 38 38 template< typename SynTreeClass > int apply( SynTreeClass *&input ); 39 39 template< typename SynTreeClass > int applyFree( SynTreeClass *&input ); 40 40 41 41 void add( std::string formalType, Type *actualType ); 42 42 void add( const TypeSubstitution &other ); … … 44 44 Type *lookup( std::string formalType ) const; 45 45 bool empty() const; 46 46 47 47 template< typename FormalIterator, typename ActualIterator > 48 48 void add( FormalIterator formalBegin, FormalIterator formalEnd, ActualIterator actualBegin ); 49 49 50 /// this function is unused... 50 51 template< typename TypeInstListIterator > 51 52 void extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result ); 52 53 53 54 void normalize(); 54 55 … … 63 64 /// Records type variable bindings from forall-statements and instantiations of generic types 64 65 template< typename TypeClass > Type *handleAggregateType( TypeClass *type ); 65 66 66 67 virtual Type* mutate(VoidType *basicType); 67 68 virtual Type* mutate(BasicType *basicType); … … 75 76 virtual Type* mutate(TupleType *tupleType); 76 77 virtual Type* mutate(VarArgsType *varArgsType); 77 78 78 79 // TODO: worry about traversing into a forall-qualified function type or type decl with assertions 79 80 80 81 void initialize( const TypeSubstitution &src, TypeSubstitution &dest ); 81 82 … … 136 137 return subCount; 137 138 } 138 139 139 140 template< typename SynTreeClass > 140 141 int TypeSubstitution::applyFree( SynTreeClass *&input ) { … … 149 150 return subCount; 150 151 } 151 152 152 153 template< typename TypeInstListIterator > 153 154 void TypeSubstitution::extract( TypeInstListIterator begin, TypeInstListIterator end, TypeSubstitution &result ) { 155 // xxx - this function doesn't extract varEnv - is this intentional? 154 156 while ( begin != end ) { 155 157 TypeEnvType::iterator cur = typeEnv.find( (*begin++)->get_name() ); … … 173 175 } 174 176 177 std::ostream & operator<<( std::ostream & out, const TypeSubstitution & sub ); 178 175 179 #endif // TYPESUBSTITUTION_H 176 180 -
src/SynTree/Visitor.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Visitor.cc -- 7 // Visitor.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Apr 1 18:05:13201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Apr 27 17:07:40 2016 13 13 // Update Count : 18 14 14 // … … 284 284 } 285 285 286 void Visitor::visit( ImplicitCopyCtorExpr *impCpCtorExpr ) { 287 maybeAccept( impCpCtorExpr->get_callExpr(), *this ); 288 acceptAll( impCpCtorExpr->get_tempDecls(), *this ); 289 acceptAll( impCpCtorExpr->get_returnDecls(), *this ); 290 } 291 286 292 void Visitor::visit( UntypedValofExpr *valofExpr ) { 287 293 acceptAll( valofExpr->get_results(), *this ); … … 379 385 } 380 386 387 void Visitor::visit( ConstructorInit *ctorInit ) { 388 maybeAccept( ctorInit->get_ctor(), *this ); 389 maybeAccept( ctorInit->get_init(), *this ); 390 } 391 381 392 void Visitor::visit( Subrange *subrange ) {} 382 393 -
src/SynTree/Visitor.h
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Visitor.h -- 7 // Visitor.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Apr 1 17:26:55201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Thu Apr 14 15:30:58 2016 13 13 // Update Count : 7 14 14 // … … 62 62 virtual void visit( MemberExpr *memberExpr ); 63 63 virtual void visit( VariableExpr *variableExpr ); 64 virtual void visit( ConstantExpr *constantExpr ); 64 virtual void visit( ConstantExpr *constantExpr ); 65 65 virtual void visit( SizeofExpr *sizeofExpr ); 66 66 virtual void visit( AlignofExpr *alignofExpr ); … … 76 76 virtual void visit( TypeExpr *typeExpr ); 77 77 virtual void visit( AsmExpr *asmExpr ); 78 virtual void visit( ImplicitCopyCtorExpr *impCpCtorExpr ); 78 79 virtual void visit( UntypedValofExpr *valofExpr ); 79 80 virtual void visit( CompoundLiteralExpr *compLitExpr ); … … 96 97 virtual void visit( SingleInit *singleInit ); 97 98 virtual void visit( ListInit *listInit ); 99 virtual void visit( ConstructorInit *ctorInit ); 98 100 99 101 virtual void visit( Subrange *subrange ); -
src/driver/cc1.cc
rbb8ea30 rd668182 10 10 // Created On : Fri Aug 26 14:23:51 2005 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Jan 25 16:05:15201613 // Update Count : 5612 // Last Modified On : Thu May 5 16:04:30 2016 13 // Update Count : 77 14 14 // 15 15 … … 108 108 const char *args[argc + 100]; // leave space for 100 additional cpp command line values 109 109 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 values111 int n uargs = 1; // 0 => command name110 const char *cargs[20]; // leave space for 20 additional cfa-cpp command line values 111 int ncargs = 1; // 0 => command name 112 112 113 113 signal( SIGINT, sigTermHandler ); 114 114 signal( SIGTERM, sigTermHandler ); 115 116 #ifdef __DEBUG_H__ 117 cerr << "Stage1" << endl; 118 #endif // __DEBUG_H__ 115 119 116 120 // process all the arguments … … 153 157 CFA_flag = true; 154 158 } else if ( prefix( arg, D__CFA_FLAGPREFIX__ ) ) { 155 uargs[nuargs] = ( *new string( arg.substr( D__CFA_FLAGPREFIX__.size() ) ) ).c_str();156 n uargs += 1;159 cargs[ncargs] = ( *new string( arg.substr( D__CFA_FLAGPREFIX__.size() ) ) ).c_str(); 160 ncargs += 1; 157 161 } 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 n uargs += 1;162 cargs[ncargs] = ( *new string( string( argv[i + 1] ).substr( D__CFA_FLAGPREFIX__.size() - 2 ) ) ).c_str(); 163 ncargs += 1; 160 164 i += 1; // and the argument 161 165 } else if ( prefix( arg, D__GCC_BPREFIX__ ) ) { … … 317 321 318 322 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; 323 333 if ( o_name != NULL ) { 324 uargs[nuargs] = o_name;325 n uargs += 1;334 cargs[ncargs] = o_name; 335 ncargs += 1; 326 336 } else if ( ! CFA_flag ) { // run cfa-cpp ? 327 uargs[nuargs] = cpp_out;328 n uargs += 1;337 cargs[ncargs] = cpp_out; 338 ncargs += 1; 329 339 } // if 330 uargs[nuargs] = NULL; // terminate argument list331 332 #ifdef __DEBUG_H__ 333 cerr << "cfa-cpp n uargs: " << 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] << " "; 336 346 } // for 337 347 cerr << endl; 338 348 #endif // __DEBUG_H__ 339 349 340 execvp( uargs[0], (char * const *)uargs ); // should not return350 execvp( cargs[0], (char * const *)cargs ); // should not return 341 351 perror( "CFA Translator error: cpp level, execvp" ); 342 352 exit( EXIT_FAILURE ); … … 370 380 const char *args[argc + 100]; // leave space for 100 additional cfa command line values 371 381 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__ 372 386 373 387 // process all the arguments … … 467 481 468 482 if ( arg == "-E" ) { 469 #ifdef __DEBUG_H__470 cerr << "Stage1" << endl;471 #endif // __DEBUG_H__472 483 Stage1( argc, argv ); 473 484 } else if ( arg == "-fpreprocessed" ) { 474 #ifdef __DEBUG_H__475 cerr << "Stage2" << endl;476 #endif // __DEBUG_H__477 485 Stage2( argc, argv ); 478 486 } else { -
src/examples/abstype.c
rbb8ea30 rd668182 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 27 18:10:01 201513 // Update Count : 412 // Last Modified On : Wed Apr 6 22:16:08 2016 13 // Update Count : 8 14 14 // 15 15 16 type T | { T x( T ); };16 otype T | { T x( T ); }; 17 17 18 18 T y( T t ) { … … 21 21 } 22 22 23 forall( type T) lvalue T*?( T* );24 int ?++( int * );25 int ?=?( int *, int );26 forall( dtype DT) DT* ?=?( DT **, DT* );23 forall( otype T ) lvalue T *?( T* ); 24 int ?++( int * ); 25 int ?=?( int *, int ); 26 forall( dtype DT ) DT * ?=?( DT **, DT* ); 27 27 28 type U = int*;28 otype U = int *; 29 29 30 30 U x( U u ) { -
src/examples/alloc.c
rbb8ea30 rd668182 11 11 // Created On : Wed Feb 3 07:56:22 2016 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Wed Feb 17 11:43:23201614 // Update Count : 4013 // Last Modified On : Fri Mar 11 17:42:08 2016 14 // Update Count : 59 15 15 // 16 16 17 forall( otype T ) T * malloc( char fill ); 18 forall( dtype T ) T *?=?( T **, void * ); 19 void *malloc( unsigned long int ); 20 #if 0 17 21 #include <fstream> 18 22 #include <stdlib> … … 25 29 int * bar( int * p, int c ) { return p; } 26 30 int * baz( int * p, int c ) { return p; } 31 #endif 27 32 28 33 int main( void ) { 34 #if 0 29 35 size_t size = 10; 30 36 int * p; 31 37 struct S { int x; double y; } * s; 38 #endif 32 39 40 #if 0 33 41 p = malloc( sizeof(*p) ); // C malloc, type unsafe 34 42 printf( "here1\n" ); … … 37 45 printf( "here2\n" ); 38 46 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 40 53 printf( "here3\n" ); 41 54 p = malloc( p, 1000 ); // CFA remalloc, type safe … … 60 73 printf( "here9\n" ); 61 74 free( p ); 62 #if 0 75 63 76 float * fp = malloc() + 1; 64 77 fprintf( stderr, "%p %p\n", fp, fp - 1 ); -
src/examples/array.c
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // array.c -- 7 // array.c -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Wed May 27 17:56:53 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Mar 2 18:13:52 201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Apr 27 17:21:52 2016 13 13 // Update Count : 3 14 14 // … … 26 26 // The first element is always at index 0. 27 27 forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) ) 28 elt_type * begin( array_type array ) {28 elt_type * begin( array_type * array ) { 29 29 return &array[ 0 ]; 30 30 } … … 32 32 // The end iterator should point one past the last element. 33 33 forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) ) 34 elt_type * end( array_type array ) {34 elt_type * end( array_type * array ) { 35 35 return &array[ last( array ) ] + 1; 36 36 } -
src/examples/array.h
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // array.h -- 7 // array.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Wed May 27 17:56:53 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Mar 2 18:13:35201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Apr 27 17:26:04 2016 13 13 // Update Count : 5 14 14 // … … 26 26 27 27 // 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 );28 trait bounded_array( otype array_type, otype elt_type | array( array_type *, elt_type ) ) { 29 int last( array_type * ); 30 30 }; 31 31 … … 41 41 // return iterators corresponding to the first element and the one-past-the-end element, STL-style. 42 42 forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) ) 43 elt_type * begin( array_type);43 elt_type * begin( array_type * array ); 44 44 45 // The end iterator should point one past the last element. 45 46 forall( otype array_type, otype elt_type | bounded_array( array_type, elt_type ) ) 46 elt_type * end( array_type);47 elt_type * end( array_type * array ); 47 48 48 49 #endif // ARRAY_H -
src/examples/fstream_test.c
rbb8ea30 rd668182 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Mar 6 20:58:29201613 // Update Count : 5412 // Last Modified On : Mon May 2 15:25:54 2016 13 // Update Count : 61 14 14 // 15 15 -
src/examples/includes.c
rbb8ea30 rd668182 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Mar 2 23:28:02 201613 // Update Count : 3 2812 // Last Modified On : Wed Apr 13 22:30:02 2016 13 // Update Count : 370 14 14 // 15 15 … … 24 24 #if 1 25 25 #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> 33 33 #include <argz.h> 34 #include <assert.h>34 //#include <assert.h> 35 35 #include <bfd.h> 36 #if 0 36 37 #include <bfdlink.h> 37 38 #include <byteswap.h> … … 56 57 #include <err.h> 57 58 #include <errno.h> 58 #if 059 59 #include <error.h> 60 #endif61 60 #include <eti.h> 62 61 #include <evdns.h> 63 62 #include <event.h> 64 63 #include <evhttp.h> 64 #endif 65 65 #if 0 66 66 #include <evrpc.h> … … 129 129 130 130 //#define _GNU_SOURCE 131 #include <error.h> 131 #include <bfd.h> 132 //#include <error.h> 132 133 133 134 #endif // 0 -
src/examples/io.c
rbb8ea30 rd668182 11 11 // Created On : Wed Mar 2 16:56:02 2016 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Wed Apr 13 23:03:14201614 // Update Count : 2 213 // Last Modified On : Sat Apr 30 08:34:13 2016 14 // Update Count : 27 15 15 // 16 16 … … 52 52 | sepDisable | fc | dc | ldc | sepEnable | endl // complex without separator 53 53 | sepOn | s1 | sepOff | s2 | endl // local separator removal 54 | s1 | "" | s2 | endl; // C string withou separator54 | s1 | "" | s2 | endl; // C string without separator 55 55 sout | endl; 56 56 … … 70 70 | "£" | 27 71 71 | "¥" | 27 72 | "¡" | 27 72 73 | "¿" | 27 73 74 | "«" | 27 -
src/examples/rational.c
rbb8ea30 rd668182 11 11 // Created On : Mon Mar 28 08:43:12 2016 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Fri Apr 8 11:27:48201614 // Update Count : 2 113 // Last Modified On : Wed May 4 14:19:36 2016 14 // Update Count : 24 15 15 // 16 16 … … 20 20 21 21 int main() { 22 Rational a, b, c;23 22 sout | "constructor" | endl; 24 a = rational( 3 ); 25 b = rational( 4 ); 26 c = rational(); 23 Rational a = { 3 }, b = { 4 }, c; 27 24 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 }; 30 27 sout | a | b | endl; 31 a = rational( -2, -3 );32 b = rational( 3, -2 );28 a = (Rational){ -2, -3 }; 29 b = (Rational){ 3, -2 }; 33 30 sout | a | b | endl; 34 a = rational( -2, 3 );35 b = rational( 3, 2 );31 a = (Rational){ -2, 3 }; 32 b = (Rational){ 3, 2 }; 36 33 sout | a | b | endl; 37 34 38 35 sout | "logical" | endl; 39 a = rational( -2 );40 b = rational( -3, 2 );36 a = (Rational){ -2 }; 37 b = (Rational){ -3, 2 }; 41 38 sout | a | b | endl; 42 39 sout | a == 1 | endl; … … 55 52 56 53 sout | "conversion" | endl; 57 a = rational( 3, 4 );54 a = (Rational){ 3, 4 }; 58 55 sout | widen( a ) | endl; 59 a = rational( 1, 7 );56 a = (Rational){ 1, 7 }; 60 57 sout | widen( a ) | endl; 61 a = rational( 355, 113 );58 a = (Rational){ 355, 113 }; 62 59 sout | widen( a ) | endl; 63 60 sout | narrow( 0.75, 4 ) | endl; … … 65 62 sout | narrow( 3.14159265358979, 256 ) | endl; 66 63 67 Rational x, y; 68 x = rational( 1, 2 ); 69 y = rational( 2 ); 64 Rational x = { 1, 2 }, y = { 2 }; 70 65 sout | x - y | endl; 71 66 sout | x > y | endl; … … 73 68 sout | y | denominator( y, -2 ) | y | endl; 74 69 75 Rational z; 76 z = rational( 0, 5 ); 70 Rational z = { 0, 5 }; 77 71 sout | z | endl; 78 72 79 73 sout | x | numerator( x, 0 ) | x | endl; 80 74 81 x = rational( 1, MAX ) + rational( 1, MAX );75 x = (Rational){ 1, MAX } + (Rational){ 1, MAX }; 82 76 sout | x | endl; 83 x = rational( 3, MAX ) + rational( 2, MAX );77 x = (Rational){ 3, MAX } + (Rational){ 2, MAX }; 84 78 sout | x | endl; 85 79 -
src/examples/sum.c
rbb8ea30 rd668182 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Mar 4 15:06:47 201613 // Update Count : 19 612 // Last Modified On : Mon May 2 15:07:57 2016 13 // Update Count : 198 14 14 // 15 15 … … 48 48 } // for 49 49 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; 51 51 52 52 int s = 0, a[size], v = low; … … 56 56 } // for 57 57 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; 59 59 60 60 float s = 0.0, a[size], v = low / 10.0; … … 64 64 } // for 65 65 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; 67 67 68 68 double s = 0, a[size], v = low / 10.0; … … 72 72 } // for 73 73 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; 75 75 76 76 struct S { int i, j; } 0 = { 0, 0 }, 1 = { 1, 1 }; … … 87 87 } // for 88 88 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; 90 90 } // main 91 91 -
src/examples/vector_int.c
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // vector_int.c -- 7 // vector_int.c -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Wed May 27 17:56:53 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed May 27 18:38:05 201511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Apr 27 17:27:12 2016 13 13 // Update Count : 3 14 14 // … … 22 22 #define DEFAULT_CAPACITY 20 23 23 24 v ector_int vector_int_allocate() {25 return vector_int_allocate( DEFAULT_CAPACITY );24 void ?{}( vector_int * vec ) { 25 vec { DEFAULT_CAPACITY }; 26 26 } 27 27 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; 28 void ?{}( vector_int * vec, int reserve ) { 29 vec->last = -1; 30 vec->capacity = reserve; 31 vec->data = malloc( sizeof( int ) * reserve ); 34 32 } 35 33 36 void vector_int_deallocate( vector_int vec ) { 37 free( vec.data ); 34 void ?{}( 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 43 void ^?{}( vector_int * vec ) { 44 free( vec->data ); 38 45 } 39 46 … … 56 63 // implement bounded_array 57 64 58 lvalue int ?[?]( vector_int vec, int index ) {59 return vec .data[ index ];65 lvalue int ?[?]( vector_int * vec, int index ) { 66 return vec->data[ index ]; 60 67 } 61 68 62 int last( vector_int vec ) {63 return vec .last;69 int last( vector_int * vec ) { 70 return vec->last; 64 71 } 65 72 -
src/examples/vector_int.h
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // vector_int.h -- 7 // vector_int.h -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Wed May 27 17:56:53 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed May 27 18:39:05 201511 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Apr 27 17:26:59 2016 13 13 // Update Count : 2 14 14 // … … 25 25 } vector_int; 26 26 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 27 void ?{}( vector_int * ); // allocate vector with default capacity 28 void ?{}( vector_int *, int reserve ); // allocate vector with specified capacity 29 void ?{}( vector_int * vec, vector_int other ); // copy constructor 30 void ^?{}( vector_int * ); // deallocate vector's storage 30 31 31 32 void reserve( vector_int *vec, int reserve ); // reserve more capacity … … 34 35 // implement bounded_array 35 36 36 lvalue int ?[?]( vector_int vec, int index ); // access to arbitrary element (does not resize)37 int last( vector_int vec ); // return last element37 lvalue int ?[?]( vector_int * vec, int index ); // access to arbitrary element (does not resize) 38 int last( vector_int * vec ); // return last element 38 39 39 40 #endif // VECTOR_INT_H -
src/examples/vector_test.c
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // vector_test.c -- 7 // vector_test.c -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Wed May 27 17:56:53 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Feb 17 12:23:55201611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Wed Apr 27 17:31:27 2016 13 13 // Update Count : 18 14 14 // … … 20 20 21 21 int main( void ) { 22 vector_int vec = vector_int_allocate();22 vector_int vec; 23 23 24 24 // read in numbers until EOF or error … … 34 34 35 35 sout | "Array elements:" | endl; 36 write( begin( vec ), end(vec ), sout );36 write( begin( &vec ), end( &vec ), sout ); 37 37 sout | endl; 38 38 39 39 sout | "Array elements reversed:" | endl; 40 write_reverse( begin( vec ), end(vec ), sout );40 write_reverse( begin( &vec ), end( &vec ), sout ); 41 41 sout | endl; 42 42 } -
src/initialization.txt
rbb8ea30 rd668182 34 34 sure that resolved initializers for all declarations are being 35 35 generated. 36 37 38 ------ 39 40 More 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 47 No, unfortunately. Initialization isn't being rewritten as assignment, 48 so you shouldn't allow the particular selection of assignment 49 operators that happen to be in scope (and which may include 50 user-defined operators) to guide the type resolution. 51 52 I don't think there is any way to rewrite an initializer as a single 53 expression and have the resolver just do the right thing. I see the 54 algorithm as: 55 56 For 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 62 Go through the list of possibilities and pick the lowest cost 63 64 As with many things in the resolver, it's conceptually simple but the 65 implementation may be a bit of a pain. It fits in with functions like 66 findSingleExpression, findIntegralExpression in Resolver.cc, although 67 it will be significantly more complicated than any of the existing 68 ones. 69 70 71 -
src/libcfa/Makefile.am
rbb8ea30 rd668182 6 6 ## file "LICENCE" distributed with Cforall. 7 7 ## 8 ## Makefile.am -- 8 ## Makefile.am -- 9 9 ## 10 10 ## Author : Peter A. Buhr … … 51 51 52 52 CFLAGS = -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 53 CC = ${abs_top_srcdir}/src/driver/cfa 54 54 55 55 # extension-less header files are overridden by default make rules => explicitly override rule … … 67 67 include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders} 68 68 69 CLEANFILES = libcfa-prelude.c 69 70 MAINTAINERCLEANFILES += ${includedir}/* -
src/libcfa/Makefile.in
rbb8ea30 rd668182 111 111 AWK = @AWK@ 112 112 BACKEND_CC = @BACKEND_CC@ 113 CC = ${abs_top_srcdir}/src/driver/cfa 113 CC = ${abs_top_srcdir}/src/driver/cfa 114 114 CCDEPMODE = @CCDEPMODE@ 115 115 CFA_BINDIR = @CFA_BINDIR@ … … 219 219 cfaheaders = # limits 220 220 include_HEADERS = ${cheaders:=.h} ${libs} ${cfaheaders} 221 CLEANFILES = libcfa-prelude.c 221 222 all: all-am 222 223 … … 457 458 458 459 clean-generic: 460 -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) 459 461 460 462 distclean-generic: -
src/libcfa/fstream
rbb8ea30 rd668182 10 10 // Created On : Wed May 27 17:56:53 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue Apr 19 20:44:10201613 // Update Count : 8 412 // Last Modified On : Thu Apr 28 08:08:04 2016 13 // Update Count : 88 14 14 // 15 15 … … 22 22 struct ofstream { 23 23 void *file; 24 intsepDefault;25 int sepOnOff; 24 _Bool sepDefault; 25 int sepOnOff; // FIX ME: type should be _Bool 26 26 char separator[separateSize]; 27 27 }; // ofstream -
src/libcfa/fstream.c
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // fstream.c -- 7 // fstream.c -- 8 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Wed May 27 17:56:53 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Apr 6 17:55:27201613 // Update Count : 1 7611 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon May 02 15:14:52 2016 13 // Update Count : 187 14 14 // 15 15 … … 75 75 if ( fclose( (FILE *)(os->file) ) == EOF ) { 76 76 perror( IO_MSG "close output" ); 77 } // if 77 } // if 78 78 } // close 79 79 … … 93 93 int prtfmt( ofstream * os, const char fmt[], ... ) { 94 94 va_list args; 95 96 95 va_start( args, fmt ); 97 96 int len = vfprintf( (FILE *)(os->file), fmt, args ); … … 103 102 } // if 104 103 va_end( args ); 104 105 sepReset( os ); // reset separator 105 106 return len; 106 107 } // prtfmt … … 139 140 if ( fclose( (FILE *)(is->file) ) == EOF ) { 140 141 perror( IO_MSG "close input" ); 141 } // if 142 } // if 142 143 } // close 143 144 … … 154 155 return is; 155 156 } // read 156 157 157 158 ifstream *ungetc( ifstream * is, char c ) { 158 159 if ( fail( is ) ) { -
src/libcfa/iostream.c
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // iostream.c -- 7 // iostream.c -- 8 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Wed May 27 17:56:53 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Apr 6 16:13:29201613 // Update Count : 27811 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon May 02 15:13:55 2016 13 // Update Count : 302 14 14 // 15 15 … … 34 34 ostype * ?|?( ostype *os, short int si ) { 35 35 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 36 sepReset( os );37 36 prtfmt( os, "%hd", si ); 38 37 return os; … … 42 41 ostype * ?|?( ostype *os, unsigned short int usi ) { 43 42 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 44 sepReset( os );45 43 prtfmt( os, "%hu", usi ); 46 44 return os; … … 50 48 ostype * ?|?( ostype *os, int i ) { 51 49 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 52 sepReset( os );53 50 prtfmt( os, "%d", i ); 54 51 return os; … … 58 55 ostype * ?|?( ostype *os, unsigned int ui ) { 59 56 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 60 sepReset( os );61 57 prtfmt( os, "%u", ui ); 62 58 return os; … … 66 62 ostype * ?|?( ostype *os, long int li ) { 67 63 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 68 sepReset( os );69 64 prtfmt( os, "%ld", li ); 70 65 return os; … … 74 69 ostype * ?|?( ostype *os, unsigned long int uli ) { 75 70 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 76 sepReset( os );77 71 prtfmt( os, "%lu", uli ); 78 72 return os; … … 82 76 ostype * ?|?( ostype *os, long long int lli ) { 83 77 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 84 sepReset( os );85 78 prtfmt( os, "%lld", lli ); 86 79 return os; … … 90 83 ostype * ?|?( ostype *os, unsigned long long int ulli ) { 91 84 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 92 sepReset( os );93 85 prtfmt( os, "%llu", ulli ); 94 86 return os; … … 98 90 ostype * ?|?( ostype *os, float f ) { 99 91 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 100 sepReset( os );101 92 prtfmt( os, "%g", f ); 102 93 return os; … … 106 97 ostype * ?|?( ostype *os, double d ) { 107 98 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 108 sepReset( os );109 99 prtfmt( os, "%.*lg", DBL_DIG, d ); 110 100 return os; … … 114 104 ostype * ?|?( ostype *os, long double ld ) { 115 105 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 116 sepReset( os );117 106 prtfmt( os, "%.*Lg", LDBL_DIG, ld ); 118 107 return os; … … 155 144 // opening delimiters 156 145 ['('] : 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, 158 148 // closing delimiters 159 149 [','] : Close, ['.'] : Close, [':'] : Close, [';'] : Close, ['!'] : Close, ['?'] : Close, … … 162 152 // opening-closing delimiters 163 153 ['\''] : OpenClose, ['`'] : OpenClose, ['"'] : OpenClose, 164 [' \f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace154 [' '] : OpenClose, ['\f'] : OpenClose, ['\n'] : OpenClose, ['\r'] : OpenClose, ['\t'] : OpenClose, ['\v'] : OpenClose, // isspace 165 155 }; // mask 166 156 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 170 159 // first character IS NOT spacing or closing punctuation => add left separator 171 160 unsigned char ch = cp[0]; // must make unsigned … … 173 162 prtfmt( os, "%s", sepGet( os ) ); 174 163 } // if 164 165 // if string starts line, must reset to determine open state because separator is off 166 sepReset( os ); // reset separator 167 175 168 // 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; 177 170 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 { 179 174 sepOff( os ); 180 } else {181 sepOn( os );182 175 } // if 183 176 return write( os, cp, len ); … … 187 180 ostype * ?|?( ostype *os, const void *p ) { 188 181 if ( sepPrt( os ) ) prtfmt( os, "%s", sepGet( os ) ); 189 sepReset( os );190 182 prtfmt( os, "%p", p ); 191 183 return os; … … 193 185 194 186 195 forall( dtype ostype | ostream( ostype ) ) 187 forall( dtype ostype | ostream( ostype ) ) 196 188 ostype * ?|?( ostype *os, ostype * (* manip)( ostype * ) ) { 197 189 return manip( os ); 198 190 } // ?|? 199 191 200 forall( dtype ostype | ostream( ostype ) ) 192 forall( dtype ostype | ostream( ostype ) ) 201 193 ostype * endl( ostype * os ) { 202 194 os | '\n'; … … 206 198 } // endl 207 199 208 forall( dtype ostype | ostream( ostype ) ) 200 forall( dtype ostype | ostream( ostype ) ) 209 201 ostype * sepOn( ostype * os ) { 210 202 sepOn( os ); … … 212 204 } // sepOn 213 205 214 forall( dtype ostype | ostream( ostype ) ) 206 forall( dtype ostype | ostream( ostype ) ) 215 207 ostype * sepOff( ostype * os ) { 216 208 sepOff( os ); … … 218 210 } // sepOff 219 211 220 forall( dtype ostype | ostream( ostype ) ) 212 forall( dtype ostype | ostream( ostype ) ) 221 213 ostype * sepEnable( ostype * os ) { 222 214 sepEnable( os ); … … 224 216 } // sepEnable 225 217 226 forall( dtype ostype | ostream( ostype ) ) 218 forall( dtype ostype | ostream( ostype ) ) 227 219 ostype * sepDisable( ostype * os ) { 228 220 sepDisable( os ); … … 344 336 } // ?|? 345 337 346 _Istream_cstrUC cstr( char * s ) { _Istream_cstrUC s = { s}; return s; }338 _Istream_cstrUC cstr( char * str ) { _Istream_cstrUC s = { str }; return s; } 347 339 forall( dtype istype | istream( istype ) ) 348 340 istype * ?|?( istype * is, _Istream_cstrUC cstr ) { … … 351 343 } // cstr 352 344 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; } 354 346 forall( dtype istype | istream( istype ) ) 355 347 istype * ?|?( istype * is, _Istream_cstrC cstr ) { -
src/libcfa/prelude.cf
rbb8ea30 rd668182 1 1 # 2 "prelude.cf" // needed for error messages from this file 2 // -*- Mode: C -*- 3 // 2 // -*- Mode: C -*- 3 // 4 4 // Copyright (C) Glen Ditchfield 1994, 1999 5 // 5 // 6 6 // prelude.cf -- Standard Cforall Preample for C99 7 // 7 // 8 8 // Author : Glen Ditchfield 9 9 // Created On : Sat Nov 29 07:23:41 2014 … … 117 117 forall( ftype FT ) lvalue FT *?( FT * ); 118 118 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 ); 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 ); 126 126 float +?( float ), -?( float ); 127 127 double +?( double ), -?( double ); … … 627 627 ?+=?( long double _Complex *, long double _Complex ), ?+=?( volatile long double _Complex *, long double _Complex ), 628 628 ?-=?( 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 641 void ?{}( _Bool * ), ?{}( volatile _Bool * ); 642 void ?{}( char * ), ?{}( volatile char * ); 643 void ?{}( unsigned char * ), ?{}( volatile unsigned char * ); 644 void ?{}( char signed * ), ?{}( volatile char signed * ); 645 void ?{}( int short * ), ?{}( volatile int short * ); 646 void ?{}( int short unsigned * ), ?{}( volatile int short unsigned * ); 647 void ?{}( signed int * ), ?{}( volatile signed int * ); 648 void ?{}( unsigned int * ), ?{}( volatile unsigned int * ); 649 void ?{}( signed long int * ), ?{}( volatile signed long int * ); 650 void ?{}( unsigned long int * ), ?{}( volatile unsigned long int * ); 651 void ?{}( signed long long int * ), ?{}( volatile signed long long int * ); 652 void ?{}( unsigned long long int * ), ?{}( volatile unsigned long long int * ); 653 void ?{}( float * ), ?{}( volatile float * ); 654 void ?{}( double * ), ?{}( volatile double * ); 655 void ?{}( long double * ), ?{}( volatile long double * ); 656 void ?{}( float _Complex * ), ?{}( volatile float _Complex * ); 657 void ?{}( double _Complex * ), ?{}( volatile double _Complex * ); 658 void ?{}( long double _Complex * ), ?{}( volatile long double _Complex * ); 659 660 // copy ctor 661 void ?{}( _Bool *, _Bool ), ?{}( volatile _Bool *, _Bool ); 662 void ?{}( char *, char ), ?{}( volatile char *, char ); 663 void ?{}( unsigned char *, unsigned char ), ?{}( volatile unsigned char *, unsigned char ); 664 void ?{}( char signed *, char signed ), ?{}( volatile char signed *, char signed ); 665 void ?{}( int short *, int short ), ?{}( volatile int short *, int short ); 666 void ?{}( int short unsigned *, int short unsigned ), ?{}( volatile int short unsigned *, int short unsigned ); 667 void ?{}( signed int *, signed int), ?{}( volatile signed int *, signed int ); 668 void ?{}( unsigned int *, unsigned int), ?{}( volatile unsigned int *, unsigned int ); 669 void ?{}( signed long int *, signed long int), ?{}( volatile signed long int *, signed long int ); 670 void ?{}( unsigned long int *, unsigned long int), ?{}( volatile unsigned long int *, unsigned long int ); 671 void ?{}( signed long long int *, signed long long int), ?{}( volatile signed long long int *, signed long long int ); 672 void ?{}( unsigned long long int *, unsigned long long int), ?{}( volatile unsigned long long int *, unsigned long long int ); 673 void ?{}( float *, float), ?{}( volatile float *, float ); 674 void ?{}( double *, double), ?{}( volatile double *, double ); 675 void ?{}( long double *, long double), ?{}( volatile long double *, long double ); 676 void ?{}( float _Complex *, float _Complex), ?{}( volatile float _Complex *, float _Complex ); 677 void ?{}( double _Complex *, double _Complex), ?{}( volatile double _Complex *, double _Complex ); 678 void ?{}( long double _Complex *, long double _Complex), ?{}( volatile long double _Complex *, long double _Complex ); 679 680 // dtor 681 void ^?{}( _Bool * ), ^?{}( volatile _Bool * ); 682 void ^?{}( char * ), ^?{}( volatile char * ); 683 void ^?{}( char unsigned * ), ^?{}( volatile char unsigned * ); 684 void ^?{}( char signed * ), ^?{}( volatile char signed * ); 685 void ^?{}( int short * ), ^?{}( volatile int short * ); 686 void ^?{}( int short unsigned * ), ^?{}( volatile int short unsigned * ); 687 void ^?{}( signed int * ), ^?{}( volatile signed int * ); 688 void ^?{}( unsigned int * ), ^?{}( volatile unsigned int * ); 689 void ^?{}( signed long int * ), ^?{}( volatile signed long int * ); 690 void ^?{}( unsigned long int * ), ^?{}( volatile unsigned long int * ); 691 void ^?{}( signed long long int * ), ^?{}( volatile signed long long int * ); 692 void ^?{}( unsigned long long int * ), ^?{}( volatile unsigned long long int * ); 693 void ^?{}( float * ), ^?{}( volatile float * ); 694 void ^?{}( double * ), ^?{}( volatile double * ); 695 void ^?{}( long double * ), ^?{}( volatile long double * ); 696 void ^?{}( float _Complex * ), ^?{}( volatile float _Complex * ); 697 void ^?{}( double _Complex * ), ^?{}( volatile double _Complex * ); 698 void ^?{}( 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 720 forall( ftype FT ) void ?{}( FT **, FT * ); 721 forall( ftype FT ) void ?{}( FT * volatile *, FT * ); 722 723 forall( dtype DT ) void ?{}( DT * *, DT * ); 724 forall( dtype DT ) void ?{}( DT * volatile *, DT * ); 725 forall( dtype DT ) void ?{}( const DT * *, DT * ); 726 forall( dtype DT ) void ?{}( const DT * volatile *, DT * ); 727 forall( dtype DT ) void ?{}( const DT * *, const DT * ); 728 forall( dtype DT ) void ?{}( const DT * volatile *, const DT * ); 729 forall( dtype DT ) void ?{}( volatile DT * *, DT * ); 730 forall( dtype DT ) void ?{}( volatile DT * volatile *, DT * ); 731 forall( dtype DT ) void ?{}( volatile DT * *, volatile DT * ); 732 forall( dtype DT ) void ?{}( volatile DT * volatile *, volatile DT * ); 733 734 forall( dtype DT ) void ?{}( const volatile DT * *, DT * ); 735 forall( dtype DT ) void ?{}( const volatile DT * volatile *, DT * ); 736 forall( dtype DT ) void ?{}( const volatile DT * *, const DT * ); 737 forall( dtype DT ) void ?{}( const volatile DT * volatile *, const DT * ); 738 forall( dtype DT ) void ?{}( const volatile DT * *, volatile DT * ); 739 forall( dtype DT ) void ?{}( const volatile DT * volatile *, volatile DT * ); 740 forall( dtype DT ) void ?{}( const volatile DT * *, const volatile DT * ); 741 forall( dtype DT ) void ?{}( const volatile DT * volatile *, const volatile DT * ); 742 743 forall( dtype DT ) void ?{}( DT * *, void * ); 744 forall( dtype DT ) void ?{}( DT * volatile *, void * ); 745 forall( dtype DT ) void ?{}( const DT * *, void * ); 746 forall( dtype DT ) void ?{}( const DT * volatile *, void * ); 747 forall( dtype DT ) void ?{}( const DT * *, const void * ); 748 forall( dtype DT ) void ?{}( const DT * volatile *, const void * ); 749 forall( dtype DT ) void ?{}( volatile DT * *, void * ); 750 forall( dtype DT ) void ?{}( volatile DT * volatile *, void * ); 751 forall( dtype DT ) void ?{}( volatile DT * *, volatile void * ); 752 forall( dtype DT ) void ?{}( volatile DT * volatile *, volatile void * ); 753 754 forall( dtype DT ) void ?{}( const volatile DT * *, void * ); 755 forall( dtype DT ) void ?{}( const volatile DT * volatile *, void * ); 756 forall( dtype DT ) void ?{}( const volatile DT * *, const void * ); 757 forall( dtype DT ) void ?{}( const volatile DT * volatile *, const void * ); 758 forall( dtype DT ) void ?{}( const volatile DT * *, volatile void * ); 759 forall( dtype DT ) void ?{}( const volatile DT * volatile *, volatile void * ); 760 forall( dtype DT ) void ?{}( const volatile DT * *, const volatile void * ); 761 forall( dtype DT ) void ?{}( const volatile DT * volatile *, const volatile void * ); 762 763 forall( dtype DT ) void ?{}( void * *, DT * ); 764 forall( dtype DT ) void ?{}( void * volatile *, DT * ); 765 forall( dtype DT ) void ?{}( const void * *, DT * ); 766 forall( dtype DT ) void ?{}( const void * volatile *, DT * ); 767 forall( dtype DT ) void ?{}( const void * *, const DT * ); 768 forall( dtype DT ) void ?{}( const void * volatile *, const DT * ); 769 forall( dtype DT ) void ?{}( volatile void * *, DT * ); 770 forall( dtype DT ) void ?{}( volatile void * volatile *, DT * ); 771 forall( dtype DT ) void ?{}( volatile void * *, volatile DT * ); 772 forall( dtype DT ) void ?{}( volatile void * volatile *, volatile DT * ); 773 forall( dtype DT ) void ?{}( const volatile void * *, DT * ); 774 forall( dtype DT ) void ?{}( const volatile void * volatile *, DT * ); 775 forall( dtype DT ) void ?{}( const volatile void * *, const DT * ); 776 forall( dtype DT ) void ?{}( const volatile void * volatile *, const DT * ); 777 forall( dtype DT ) void ?{}( const volatile void * *, volatile DT * ); 778 forall( dtype DT ) void ?{}( const volatile void * volatile *, volatile DT * ); 779 forall( dtype DT ) void ?{}( const volatile void * *, const volatile DT * ); 780 forall( dtype DT ) void ?{}( const volatile void * volatile *, const volatile DT * ); 781 782 void ?{}( void * *, void * ); 783 void ?{}( void * volatile *, void * ); 784 void ?{}( const void * *, void * ); 785 void ?{}( const void * volatile *, void * ); 786 void ?{}( const void * *, const void * ); 787 void ?{}( const void * volatile *, const void * ); 788 void ?{}( volatile void * *, void * ); 789 void ?{}( volatile void * volatile *, void * ); 790 void ?{}( volatile void * *, volatile void * ); 791 void ?{}( volatile void * volatile *, volatile void * ); 792 void ?{}( const volatile void * *, void * ); 793 void ?{}( const volatile void * volatile *, void * ); 794 void ?{}( const volatile void * *, const void * ); 795 void ?{}( const volatile void * volatile *, const void * ); 796 void ?{}( const volatile void * *, volatile void * ); 797 void ?{}( const volatile void * volatile *, volatile void * ); 798 void ?{}( const volatile void * *, const volatile void * ); 799 void ?{}( 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 * ); 803 forall( dtype DT ) void ?{}( const DT * *, forall( dtype DT2 ) const DT2 * ); 804 forall( 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 * ); 807 forall( dtype DT ) void ?{}( const volatile DT * *, forall( dtype DT2 ) const DT2 * ); 808 forall( dtype DT ) void ?{}( const volatile DT * volatile *, forall( dtype DT2 ) const DT2 * ); 809 810 forall( ftype FT ) void ?{}( FT * *, forall( ftype FT2 ) FT2 * ); 811 forall( ftype FT ) void ?{}( FT * volatile *, forall( ftype FT2 ) FT2 * ); 812 813 // default ctors 814 forall( ftype FT ) void ?{}( FT * * ); 815 forall( ftype FT ) void ?{}( FT * volatile * ); 816 817 forall( dtype DT ) void ?{}( DT * *); 818 forall( dtype DT ) void ?{}( DT * volatile *); 819 forall( dtype DT ) void ?{}( const DT * *); 820 forall( dtype DT ) void ?{}( const DT * volatile *); 821 forall( dtype DT ) void ?{}( volatile DT * *); 822 forall( dtype DT ) void ?{}( volatile DT * volatile *); 823 forall( dtype DT ) void ?{}( const volatile DT * *); 824 forall( dtype DT ) void ?{}( const volatile DT * volatile *); 825 826 void ?{}( void * *); 827 void ?{}( void * volatile *); 828 void ?{}( const void * *); 829 void ?{}( const void * volatile *); 830 void ?{}( volatile void * *); 831 void ?{}( volatile void * volatile *); 832 void ?{}( const volatile void * *); 833 void ?{}( const volatile void * volatile *); 834 835 // dtors 836 forall( ftype FT ) void ^?{}( FT * * ); 837 forall( ftype FT ) void ^?{}( FT * volatile * ); 838 839 forall( dtype DT ) void ^?{}( DT * *); 840 forall( dtype DT ) void ^?{}( DT * volatile *); 841 forall( dtype DT ) void ^?{}( const DT * *); 842 forall( dtype DT ) void ^?{}( const DT * volatile *); 843 forall( dtype DT ) void ^?{}( volatile DT * *); 844 forall( dtype DT ) void ^?{}( volatile DT * volatile *); 845 forall( dtype DT ) void ^?{}( const volatile DT * *); 846 forall( dtype DT ) void ^?{}( const volatile DT * volatile *); 847 848 void ^?{}( void * *); 849 void ^?{}( void * volatile *); 850 void ^?{}( const void * *); 851 void ^?{}( const void * volatile *); 852 void ^?{}( volatile void * *); 853 void ^?{}( volatile void * volatile *); 854 void ^?{}( const volatile void * *); 855 void ^?{}( const volatile void * volatile *); -
src/libcfa/rational
rbb8ea30 rd668182 12 12 // Created On : Wed Apr 6 17:56:25 2016 13 13 // Last Modified By : Peter A. Buhr 14 // Last Modified On : Fri Apr 8 11:38:27201615 // Update Count : 1 514 // Last Modified On : Wed May 4 14:11:45 2016 15 // Update Count : 16 16 16 // 17 17 … … 28 28 29 29 // constructors 30 Rational rational();31 Rational rational(long int n );32 Rational rational(long int n, long int d );30 void ?{}( Rational * r ); 31 void ?{}( Rational * r, long int n ); 32 void ?{}( Rational * r, long int n, long int d ); 33 33 34 34 // getter/setter for numerator/denominator -
src/libcfa/rational.c
rbb8ea30 rd668182 11 11 // Created On : Wed Apr 6 17:54:28 2016 12 12 // Last Modified By : Peter A. Buhr 13 // Last Modified On : Thu Apr 21 07:33:03201614 // Update Count : 2 213 // Last Modified On : Wed May 4 14:16:14 2016 14 // Update Count : 25 15 15 // 16 16 … … 53 53 // constructors 54 54 55 Rational rational() {56 r eturn (Rational){ 0, 1 };55 void ?{}( Rational * r ) { 56 r{ 0, 1 }; 57 57 } // rational 58 58 59 Rational rational(long int n ) {60 r eturn (Rational){ n, 1 };59 void ?{}( Rational * r, long int n ) { 60 r{ n, 1 }; 61 61 } // rational 62 62 63 Rational rational(long int n, long int d ) {63 void ?{}( Rational * r, long int n, long int d ) { 64 64 long int t = simplify( &n, &d ); // simplify 65 return (Rational){ n / t, d / t }; 65 r->numerator = n / t; 66 r->denominator = d / t; 66 67 } // rational 67 68 … … 172 173 Rational narrow( double f, long int md ) { 173 174 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 176 176 } // if 177 177 … … 199 199 k[2] = x * k[1] + k[0]; k[0] = k[1]; k[1] = k[2]; 200 200 } // 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] }; 203 202 } // narrow 204 203 -
src/libcfa/stdlib
rbb8ea30 rd668182 10 10 // Created On : Thu Jan 28 17:12:35 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Apr 21 07:55:21201613 // Update Count : 9 512 // Last Modified On : Wed Apr 27 22:03:29 2016 13 // Update Count : 96 14 14 // 15 15 … … 45 45 46 46 forall( otype T ) T * aligned_alloc( size_t alignment ); 47 forall( otype T ) T * memalign( size_t alignment ); 47 forall( otype T ) T * memalign( size_t alignment ); // deprecated 48 48 forall( otype T ) int posix_memalign( T ** ptr, size_t alignment ); 49 49 -
src/libcfa/stdlib.c
rbb8ea30 rd668182 10 10 // Created On : Thu Jan 28 17:10:29 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu Apr 2 1 07:58:29201613 // Update Count : 16 512 // Last Modified On : Thu Apr 28 07:54:21 2016 13 // Update Count : 166 14 14 // 15 15 … … 213 213 //--------------------------------------- 214 214 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 ]; } 217 217 218 218 //--------------------------------------- -
src/main.cc
rbb8ea30 rd668182 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // main.cc -- 7 // main.cc -- 8 8 // 9 9 // Author : Richard C. Bilson 10 10 // Created On : Fri May 15 23:12:02 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Jan 27 22:20:20201613 // Update Count : 19911 // Last Modified By : Rob Schluntz 12 // Last Modified On : Fri May 06 15:59:09 2016 13 // Update Count : 203 14 14 // 15 15 … … 40 40 #include "MakeLibCfa.h" 41 41 #include "InitTweak/Mutate.h" 42 #include "InitTweak/RemoveInit.h" 42 #include "InitTweak/GenInit.h" 43 #include "InitTweak/FixInit.h" 44 #include "InitTweak/FixGlobalInit.h" 43 45 //#include "Explain/GenProlog.h" 44 46 //#include "Try/Visit.h" … … 55 57 56 58 static void parse( FILE * input, LinkageSpec::Type t, bool shouldExit = false ); 57 static void dump( std::list< Declaration * > & translationUnit );59 static void dump( std::list< Declaration * > & translationUnit, std::ostream & out = std::cout ); 58 60 59 61 bool 60 62 astp = false, 61 63 bresolvep = false, 64 bboxp = false, 65 ctorinitp = false, 62 66 exprp = false, 63 67 expraltp = false, … … 74 78 codegenp = false; 75 79 76 enum { Ast, B resolver, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, };80 enum { Ast, Bbox, Bresolver, CtorInitFix, Expr, ExprAlt, Grammar, LibCFA, Nopreamble, Parse, Prototypes, Resolver, Symbol, Tree, Validate, }; 77 81 78 82 static struct option long_opts[] = { 79 83 { "ast", no_argument, 0, Ast }, 84 { "before-box", no_argument, 0, Bbox }, 80 85 { "before-resolver", no_argument, 0, Bresolver }, 86 { "ctorinitfix", no_argument, 0, CtorInitFix }, 81 87 { "expr", no_argument, 0, Expr }, 82 88 { "expralt", no_argument, 0, ExprAlt }, … … 97 103 std::ostream *output = &std::cout; 98 104 int long_index; 99 std::list< Declaration* > translationUnit; 105 std::list< Declaration * > translationUnit; 106 const char *filename = NULL; 100 107 101 108 opterr = 0; // prevent getopt from printing error messages 102 109 103 110 int c; 104 while ( (c = getopt_long( argc, argv, "ab efglnpqrstvyzD:", long_opts, &long_index )) != -1 ) {111 while ( (c = getopt_long( argc, argv, "abBcefglnpqrstvyzD:F:", long_opts, &long_index )) != -1 ) { 105 112 switch ( c ) { 106 113 case Ast: … … 112 119 bresolvep = true; 113 120 break; 121 case 'B': // print before resolver steps 122 bboxp = true; 123 break; 124 case CtorInitFix: 125 case 'c': 126 ctorinitp = true; 127 break; 114 128 case Expr: 115 129 case 'e': // dump AST after expression analysis … … 162 176 break; 163 177 case 'D': // ignore -Dxxx 178 break; 179 case 'F': // source file-name without suffix 180 filename = optarg; 164 181 break; 165 182 case '?': … … 176 193 input = fopen( argv[ optind ], "r" ); 177 194 if ( ! input ) { 178 std::cout << "Error: can't open " << argv[ optind] << std::endl;195 std::cout << "Error: can't open " << argv[ optind ] << std::endl; 179 196 exit( 1 ); 180 197 } // 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"; 181 202 optind += 1; 182 203 } else { … … 187 208 output = new ofstream( argv[ optind ] ); 188 209 } // if 189 210 190 211 Parser::get_parser().set_debug( grammarp ); 191 212 … … 208 229 exit( 1 ); 209 230 } // if 210 231 211 232 parse( prelude, LinkageSpec::Intrinsic ); 212 233 } // if 213 234 } // if 214 235 215 parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp ); 216 236 parse( input, libcfap ? LinkageSpec::Intrinsic : LinkageSpec::Cforall, grammarp ); 237 217 238 if ( parsep ) { 218 239 Parser::get_parser().get_parseTree()->printList( std::cout ); … … 249 270 OPTPRINT( "mutate" ) 250 271 ControlStruct::mutate( translationUnit ); 251 OPTPRINT( "fixNames" ) 272 OPTPRINT( "fixNames" ) 252 273 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 ); 255 278 256 279 if ( libcfap ) { … … 268 291 if ( exprp ) { 269 292 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; 270 302 } 271 303 … … 276 308 OPTPRINT( "convertLvalue" ) 277 309 GenPoly::convertLvalue( translationUnit ); 310 311 if ( bboxp ) { 312 dump( translationUnit ); 313 return 0; 314 } 278 315 OPTPRINT( "box" ) 279 316 GenPoly::box( translationUnit ); 280 317 281 318 // print tree right before code generation 282 319 if ( codegenp ) { … … 292 329 } catch ( SemanticError &e ) { 293 330 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; 295 334 } 296 335 e.print( std::cerr ); … … 314 353 } // try 315 354 355 deleteAll( translationUnit ); 316 356 return 0; 317 357 } // main … … 331 371 } 332 372 333 static void dump( std::list< Declaration * > & translationUnit ) {373 static void dump( std::list< Declaration * > & translationUnit, std::ostream & out ) { 334 374 std::list< Declaration * > decls; 335 375 if ( noprotop ) { 336 filter( translationUnit.begin(), translationUnit.end(), 376 filter( translationUnit.begin(), translationUnit.end(), 337 377 std::back_inserter( decls ), notPrelude ); 338 378 } else { … … 340 380 } 341 381 342 printAll( decls, std::cout );382 printAll( decls, out ); 343 383 deleteAll( translationUnit ); 344 384 }
Note:
See TracChangeset
for help on using the changeset viewer.