Changeset 70a06f6
- Timestamp:
- Apr 14, 2016, 4:13:10 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 356189a
- Parents:
- db4ecc5 (diff), 37f0da8 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 10 added
- 3 deleted
- 48 edited
- 2 moved
Legend:
- Unmodified
- Added
- Removed
-
doc/refrat/Makefile
rdb4ecc5 r70a06f6 1 1 ## Define the appropriate configuration variables. 2 2 3 Macros = 4 TeXLIB = .:${Macros}: 3 TeXLIB = .:../bibliography/:../LaTeXmacros/: 5 4 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex 6 BibTeX = B STINPUTS=${TeXLIB} && export BSTINPUTS && bibtex5 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex 7 6 8 7 ## Define the text source files. … … 44 43 dvips $< -o $@ 45 44 46 ${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ${basename ${DOCUMENT}}.bib 45 ${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \ 46 ../LaTeXmacros/common.tex ../LaTeXmacros/indexstyle ../bibliography/cfa.bib 47 47 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 48 48 if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi … … 54 54 -${BibTeX} ${basename $@} 55 55 # Make index from *.aux entries and input index at end of document 56 makeindex -s indexstyle ${basename $@}.idx56 makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx 57 57 ${LaTeX} ${basename $@}.tex 58 58 # Run again to get index title into table of contents -
doc/refrat/refrat.tex
rdb4ecc5 r70a06f6 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 %% 3 %% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 4 %% 5 %% The contents of this file are covered under the licence agreement in the 6 %% file "LICENCE" distributed with Cforall. 7 %% 8 %% refrat.tex -- 9 %% 10 %% Author : Peter A. Buhr 11 %% Created On : Wed Apr 6 14:52:25 2016 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sat Apr 9 10:19:12 2016 14 %% Update Count : 8 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 1 17 % requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended 2 18 … … 5 21 6 22 % Latex packages used in the document. 7 8 23 \usepackage{fullpage,times} 9 24 \usepackage{xspace} … … 11 26 \usepackage{listings} 12 27 \usepackage{comment} 13 \usepackage{latexsym} 14 \usepackage{mathptmx} 28 \usepackage{latexsym} % \Box 29 \usepackage{mathptmx} % better math font with "times" 15 30 \usepackage[pagewise]{lineno} 16 31 \renewcommand{\linenumberfont}{\scriptsize\sffamily} … … 21 36 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 22 37 23 % Names used in the document. 24 25 \newcommand{\CFA}{C$\forall$\xspace} % set language symbolic name 26 \newcommand{\CFL}{Cforall\xspace} % set language text name 27 \newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace} % CC symbolic name 28 \def\c11{ISO/IEC C} % C11 name (cannot have numbers in latex command name) 38 % Bespoke macros used in the document. 39 \input{common} 29 40 30 41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 31 42 32 % Bespoke macros used in the document. 33 34 \makeatletter 35 % allow escape sequence in lstinline 36 %\usepackage{etoolbox} 37 %\patchcmd{\lsthk@TextStyle}{\let\lst@DefEsc\@empty}{}{}{\errmessage{failed to patch}} 38 39 \renewcommand\small{% 40 \@setfontsize\small{8.5}{11}% 41 \abovedisplayskip 8.5pt \@plus 3pt \@minus 4pt 42 \abovedisplayshortskip \z@ \@plus 2pt 43 \belowdisplayshortskip 4pt \@plus 2pt \@minus 2pt 44 \def\@listi{\leftmargin\leftmargini 45 \topsep 4pt \@plus 2pt \@minus 2pt 46 \parsep 2pt \@pluspt \@minuspt 47 \itemsep \parsep}% 48 \belowdisplayskip \abovedisplayskip 49 } 50 \usepackage{relsize} % must be after change to small 51 52 \renewcommand{\labelitemi}{{\raisebox{0.25ex}{\footnotesize$\bullet$}}} 53 \renewenvironment{itemize}{\begin{list}{\labelitemi}{\topsep=5pt\itemsep=5pt\parsep=0pt}}{\end{list}} 54 55 % Reduce size of chapter/section titles 56 \def\@makechapterhead#1{% 57 \vspace*{50\p@}% 58 {\parindent \z@ \raggedright \normalfont 59 \ifnum \c@secnumdepth >\m@ne 60 \large\bfseries \@chapapp\space \thechapter 61 \par\nobreak 62 \vskip 5\p@ 63 \fi 64 \interlinepenalty\@M 65 \Large \bfseries #1\par\nobreak 66 \vskip 50\p@ 67 }} 68 \def\@makeschapterhead#1{% 69 \vspace*{50\p@}% 70 {\parindent \z@ \raggedright 71 \normalfont 72 \interlinepenalty\@M 73 \Large \bfseries #1\par\nobreak 74 \vskip 50\p@ 75 }} 76 \renewcommand\section{\@startsection{section}{1}{\z@}{-3.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\large\bfseries}} 77 \renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 78 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 79 \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}} 80 81 % index macros 82 \newcommand{\italic}[1]{\emph{\hyperpage{#1}}} 83 \newcommand{\definition}[1]{\textbf{\hyperpage{#1}}} 84 \newcommand{\see}[1]{\emph{see} #1} 85 86 % Define some commands that produce formatted index entries suitable for cross-references. 87 % ``\spec'' produces entries for specifications of entities. ``\impl'' produces entries for their 88 % implementations, and ``\use'' for their uses. 89 90 % \newcommand{\bold}[1]{{\bf #1}} 91 % \def\spec{\@bsphack\begingroup 92 % \def\protect##1{\string##1\space}\@sanitize 93 % \@wrxref{|bold}} 94 \def\impl{\@bsphack\begingroup 95 \def\protect##1{\string##1\space}\@sanitize 96 \@wrxref{|definition}} 97 \newcommand{\indexcode}[1]{{\lstinline$#1$}} 98 \def\use{\@bsphack\begingroup 99 \def\protect##1{\string##1\space}\@sanitize 100 \@wrxref{|hyperpage}} 101 \def\@wrxref#1#2{\let\thepage\relax 102 \xdef\@gtempa{\write\@indexfile{\string 103 \indexentry{#2@{\lstinline$#2$}#1}{\thepage}}}\endgroup\@gtempa 104 \if@nobreak \ifvmode\nobreak\fi\fi\@esphack} 105 %\newcommand{\use}[1]{\index{#1@{\lstinline$#1$}}} 106 %\newcommand{\impl}[1]{\index{\protect#1@{\lstinline$\protect#1$}|definition}} 107 108 % inline text and lowercase index: \Index{inline and lowercase index text} 109 % inline text and as-in index: \Index[as-is index text]{inline text} 110 % inline text but index with different as-is text: \Index[index text]{inline text} 111 \newcommand{\Index}{\@ifstar\@sIndex\@Index} 112 \newcommand{\@Index}[2][\@empty]{\lowercase{\def\temp{#2}}#2\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi} 113 \newcommand{\@sIndex}[2][\@empty]{#2\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi} 114 \makeatother 115 116 % blocks and titles 117 \newenvironment{rationale}{% 118 \begin{quotation}\noindent$\Box$\enspace 119 }{% 120 \hfill\enspace$\Box$\end{quotation} 121 }% 122 \newcommand{\define}[1]{\emph{#1\/}\index{#1}} 123 \newcommand{\rewrite}{\(\Rightarrow\)} 124 \newcommand{\rewriterules}{\paragraph{Rewrite Rules}~\par\noindent} 125 \newcommand{\examples}{\paragraph{Examples}~\par\noindent} 126 \newcommand{\semantics}{\paragraph{Semantics}~\par\noindent} 127 \newcommand{\constraints}{\paragraph{Constraints}~\par\noindent} 128 \newcommand{\predefined}{\paragraph{Predefined Identifiers}~\par\noindent} 129 130 % BNF macros 131 \def\syntax{\paragraph{Syntax}\trivlist\parindent=.5in\item[\hskip.5in]} 132 \let\endsyntax=\endtrivlist 133 \newcommand{\lhs}[1]{\par{\emph{#1:}}\index{#1@{\emph{#1}}|italic}} 134 \newcommand{\rhs}{\hfil\break\hbox{\hskip1in}} 135 \newcommand{\oldlhs}[1]{\emph{#1: \ldots}\index{#1@{\emph{#1}}|italic}} 136 \newcommand{\nonterm}[1]{\emph{#1\/}\index{#1@{\emph{#1}}|italic}} 137 \newcommand{\opt}{$_{opt}$\ } 138 139 % adjust varioref package with default "section" and "page" titles, and optional title with faraway page numbers 140 % \VRef{label} => Section 2.7, \VPageref{label} => page 17 141 % \VRef[Figure]{label} => Figure 3.4, \VPageref{label} => page 17 142 \renewcommand{\reftextfaceafter}{\unskip} 143 \renewcommand{\reftextfacebefore}{\unskip} 144 \renewcommand{\reftextafter}{\unskip} 145 \renewcommand{\reftextbefore}{\unskip} 146 \renewcommand{\reftextfaraway}[1]{\unskip, p.~\pageref{#1}} 147 \renewcommand{\reftextpagerange}[2]{\unskip, pp.~\pageref{#1}--\pageref{#2}} 148 \newcommand{\VRef}[2][Section]{\ifx#1\@empty\else{#1}\nobreakspace\fi\vref{#2}} 149 \newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}} 150 151 % CFA based on ANSI C 152 \lstdefinelanguage{CFA}[ANSI]{C}% 153 {morekeywords={asm,_Alignas,_Alignof,_At,_Atomic,_Bool,catch,catchResume,choose,_Complex,trait,disable,dtype,enable, 154 fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,lvalue,_Noreturn,otype,restrict,_Static_assert, 155 _Thread_local,throw,throwResume,try,}, 156 }% 157 158 \lstset{ 159 language=CFA, 160 columns=flexible, 161 basicstyle=\sf\relsize{-1}, 162 tabsize=4, 163 xleftmargin=\parindent, 164 escapechar=@, 165 keepspaces=true, 166 showstringspaces=false, 167 showlines=true, 168 }% 169 170 \makeatletter 171 % replace/adjust listings characters that look bad in sanserif 172 \lst@CCPutMacro 173 \lst@ProcessOther{"2D}{\lst@ttfamily{-{}}{{\ttfamily\upshape -}}} % replace minus 174 \lst@ProcessOther{"3C}{\lst@ttfamily{<}{\texttt{<}}} % replace less than 175 \lst@ProcessOther{"3E}{\lst@ttfamily{<}{\texttt{>}}} % replace greater than 176 \lst@ProcessOther{"5E}{\raisebox{0.4ex}{$\scriptstyle\land\,$}} % replace circumflex 177 \lst@ProcessLetter{"5F}{\lst@ttfamily{\char95}{{\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}}} % replace underscore 178 \lst@ProcessOther{"7E}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}} % replace tilde 179 %\lst@ProcessOther{"7E}{\raisebox{-.4ex}[1ex][0pt]{\textasciitilde}} % lower tilde 180 \@empty\z@\@empty 181 \makeatother 182 183 \setcounter{secnumdepth}{3} % number subsubsections 184 \setcounter{tocdepth}{3} % subsubsections in table of contents 43 \setcounter{secnumdepth}{3} % number subsubsections 44 \setcounter{tocdepth}{3} % subsubsections in table of contents 185 45 \makeindex 186 46 … … 189 49 \begin{document} 190 50 \pagestyle{headings} 191 \linenumbers 51 \linenumbers % comment out to turn off line numbering 192 52 193 53 \title{\Huge 54 \vspace*{1in} 194 55 \CFA (\CFL) Reference Manual and Rationale 195 56 }% title … … 226 87 227 88 This document is a reference manual and rationale for \CFA, a polymorphic extension of the C programming language. 228 It makes frequent reference to the {\c11} standard \cite{ ANS:C11}, and occasionally compares \CFA to {\CC} \cite{c++}.89 It makes frequent reference to the {\c11} standard \cite{C11}, and occasionally compares \CFA to {\CC} \cite{C++}. 229 90 230 91 The manual deliberately imitates the ordering of the {\c11} standard (although the section numbering differs). … … 720 581 721 582 There are two notable differences between \CFA's overload resolution rules and the rules for 722 {\CC} defined in \cite{ c++}.583 {\CC} defined in \cite{C++}. 723 584 First, the result type of a function plays a role. 724 585 In {\CC}, a function call must be completely resolved based on the arguments to the call in most circumstances. … … 3384 3245 \begin{itemize} 3385 3246 \item 3386 Inside a Clu cluster \cite{ clu}, the declaration of an instance states which view applies.3247 Inside a Clu cluster \cite{CLU}, the declaration of an instance states which view applies. 3387 3248 Two primitives called \lstinline$up$ and \lstinline$down$ can be used to convert between the views. 3388 3249 \item 3389 The Simula class \cite{S imula87} is essentially a record type.3250 The Simula class \cite{SIMULA87} is essentially a record type. 3390 3251 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. 3391 3252 In {\CC} 3392 \cite{ c++}, operations on class instances include assignment and ``\lstinline$&$'', which can be overloaded.3253 \cite{C++}, operations on class instances include assignment and ``\lstinline$&$'', which can be overloaded. 3393 3254 A ``scope resolution'' operator can be used inside the class to specify whether the abstract or implementation version of the operation should be used. 3394 3255 \item 3395 An Ada derived type definition \cite{ ada} creates a new type from an old type, and also implicitly declares derived subprograms that correspond to the existing subprograms that use the old type as a parameter type or result type.3256 An Ada derived type definition \cite{Ada} creates a new type from an old type, and also implicitly declares derived subprograms that correspond to the existing subprograms that use the old type as a parameter type or result type. 3396 3257 The derived subprograms are clones of the existing subprograms with the old type replaced by the derived type. 3397 3258 Literals and aggregates of the old type are also cloned. … … 3843 3704 ``\lstinline$Safe_pointer$ acts like a pointer to \lstinline$int$''. 3844 3705 \begin{lstlisting} 3845 trait ptr_to( type P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@3706 trait ptr_to( otype P | pointer( P ), otype T ) {@\impl{ptr_to}@@\use{pointer}@ 3846 3707 lvalue T *?( P ); 3847 3708 lvalue T ?[?]( P, long int ); 3848 3709 }; 3849 trait ptr_to_const( type P | pointer( P ), otype T ) {@\impl{ptr_to_const}@3710 trait ptr_to_const( otype P | pointer( P ), otype T ) {@\impl{ptr_to_const}@ 3850 3711 const lvalue T *?( P ); 3851 3712 const lvalue T ?[?]( P, long int );@\use{pointer}@ 3852 3713 }; 3853 trait ptr_to_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@3714 trait ptr_to_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_volatile}@ 3854 3715 volatile lvalue T *?( P ); 3855 3716 volatile lvalue T ?[?]( P, long int );@\use{pointer}@ 3856 3717 }; 3857 trait ptr_to_const_volatile( type P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@3718 trait ptr_to_const_volatile( otype P | pointer( P ), otype T ) }@\impl{ptr_to_const_volatile}@ 3858 3719 const volatile lvalue T *?( P );@\use{pointer}@ 3859 3720 const volatile lvalue T ?[?]( P, long int ); … … 3865 3726 ``\lstinline$ptr_to$'' specifications. 3866 3727 \begin{lstlisting} 3867 trait m_l_ptr_to( type P | m_l_pointer( P ),@\use{m_l_pointer}@@\impl{m_l_ptr_to}@ otype T | ptr_to( P, T )@\use{ptr_to}@ {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}@ { 3868 3729 P ?=?( P *, T * ); 3869 3730 T * ?=?( T **, P ); 3870 3731 }; 3871 trait m_l_ptr_to_const( type 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}@) {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}@) { 3872 3733 P ?=?( P *, const T * ); 3873 3734 const T * ?=?( const T **, P ); 3874 3735 }; 3875 trait m_l_ptr_to_volatile( type 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}@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}@ 3876 3737 P ?=?( P *, volatile T * ); 3877 3738 volatile T * ?=?( volatile T **, P ); 3878 3739 }; 3879 trait m_l_ptr_to_const_volatile( type P | ptr_to_const_volatile( P ),@\use{ptr_to_const_volatile}@@\impl{m_l_ptr_to_const_volatile}@3880 type 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}@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}@ 3881 3742 P ?=?( P *, const volatile T * ); 3882 3743 const volatile T * ?=?( const volatile T **, P ); … … 4006 3867 4007 3868 \bibliographystyle{plain} 4008 \bibliography{ refrat}3869 \bibliography{cfa} 4009 3870 4010 3871 -
doc/user/Makefile
rdb4ecc5 r70a06f6 1 1 ## Define the appropriate configuration variables. 2 2 3 TeXLIB = .: :3 TeXLIB = .:../bibliography/:../LaTeXmacros/: 4 4 LaTeX = TEXINPUTS=${TeXLIB} && export TEXINPUTS && latex 5 BibTeX = B STINPUTS=${TeXLIB} && export BSTINPUTS && bibtex5 BibTeX = BIBINPUTS=${TeXLIB} && export BIBINPUTS && bibtex 6 6 7 7 ## Define the text source files. … … 43 43 dvips $< -o $@ 44 44 45 ${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex ${basename ${DOCUMENT}}.bib /usr/local/bibliographies/pl.bib 45 ${basename ${DOCUMENT}}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${basename ${DOCUMENT}}.tex \ 46 ../LaTeXmacros/common.tex ../LaTeXmacros/indexstyle ../bibliography/cfa.bib 46 47 # Conditionally create an empty *.ind (index) file for inclusion until makeindex is run. 47 48 if [ ! -r ${basename $@}.ind ] ; then touch ${basename $@}.ind ; fi … … 53 54 -${BibTeX} ${basename $@} 54 55 # Make index from *.aux entries and input index at end of document 55 makeindex -s indexstyle ${basename $@}.idx56 makeindex -s ../LaTeXmacros/indexstyle ${basename $@}.idx 56 57 ${LaTeX} ${basename $@}.tex 57 58 # Run again to get index title into table of contents -
doc/user/user.tex
rdb4ecc5 r70a06f6 1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -*- Mode: Latex -*- %%%%%%%%%%%%%%%%%%%%%%%%%%%% 2 %% 3 %% Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo 4 %% 5 %% The contents of this file are covered under the licence agreement in the 6 %% file "LICENCE" distributed with Cforall. 7 %% 8 %% user.tex -- 9 %% 10 %% Author : Peter A. Buhr 11 %% Created On : Wed Apr 6 14:53:29 2016 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Sun Apr 10 22:50:15 2016 14 %% Update Count : 72 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 1 17 % requires tex packages: texlive-base texlive-latex-base tex-common texlive-humanities texlive-latex-extra texlive-fonts-recommended 2 18 … … 5 21 6 22 % Latex packages used in the document. 7 23 \usepackage[T1]{fontenc} % allow Latin1 (extended ASCII) characters 24 \usepackage{textcomp} 25 \usepackage[latin1]{inputenc} 26 \usepackage{upquote} 8 27 \usepackage{fullpage,times} 9 28 \usepackage{xspace} … … 12 31 \usepackage{footmisc} 13 32 \usepackage{comment} 14 \usepackage{latexsym} 15 \usepackage{mathptmx} 33 \usepackage{latexsym} % \Box 34 \usepackage{mathptmx} % better math font with "times" 16 35 \usepackage[pagewise]{lineno} 17 36 \renewcommand{\linenumberfont}{\scriptsize\sffamily} … … 22 41 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 23 42 43 % Bespoke macros used in the document. 44 \input{common} 45 46 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 47 24 48 % Names used in the document. 25 49 26 \newcommand{\CFA}{C$\forall$\xspace} % set language symbolic name27 \newcommand{\CFL}{Cforall\xspace} % set language text name28 \newcommand{\CC}{C\kern-.1em\hbox{+\kern-.25em+}\xspace} % CC symbolic name29 \def\c11{ISO/IEC C} % C11 name (cannot have numbers in latex command name)30 50 \newcommand{\CS}{C\raisebox{-0.9ex}{\large$^\sharp$}\xspace} 31 51 32 52 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33 53 34 % Bespoke macros used in the document. 35 36 \makeatletter 37 % allow escape sequence in lstinline 38 %\usepackage{etoolbox} 39 %\patchcmd{\lsthk@TextStyle}{\let\lst@DefEsc\@empty}{}{}{\errmessage{failed to patch}} 40 41 \renewcommand\small{% 42 \@setfontsize\small{8.5}{11}% 43 \abovedisplayskip 8.5pt \@plus 3pt \@minus 4pt 44 \abovedisplayshortskip \z@ \@plus 2pt 45 \belowdisplayshortskip 4pt \@plus 2pt \@minus 2pt 46 \def\@listi{\leftmargin\leftmargini 47 \topsep 4pt \@plus 2pt \@minus 2pt 48 \parsep 2pt \@pluspt \@minuspt 49 \itemsep \parsep}% 50 \belowdisplayskip \abovedisplayskip 51 } 52 \usepackage{relsize} % must be after change to small 53 54 \renewcommand{\labelitemi}{{\raisebox{0.25ex}{\footnotesize$\bullet$}}} 55 \renewenvironment{itemize}{\begin{list}{\labelitemi}{\topsep=5pt\itemsep=5pt\parsep=0pt}}{\end{list}} 56 57 % Reduce size of section titles 58 \renewcommand\section{\@startsection{section}{1}{\z@}{-3.0ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\large\bfseries}} 59 \renewcommand\subsection{\@startsection{subsection}{2}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 60 \renewcommand\subsubsection{\@startsection{subsubsection}{3}{\z@}{-2.5ex \@plus -1ex \@minus -.2ex}{1.0ex \@plus .2ex}{\normalfont\normalsize\bfseries}} 61 \renewcommand\paragraph{\@startsection{paragraph}{4}{\z@}{-2.0ex \@plus -1ex \@minus -.2ex}{-1em}{\normalfont\normalsize\bfseries}} 62 63 % index macros 64 \newcommand{\italic}[1]{\emph{\hyperpage{#1}}} 65 \newcommand{\definition}[1]{\textbf{\hyperpage{#1}}} 66 \newcommand{\see}[1]{\emph{see} #1} 67 68 % Define some commands that produce formatted index entries suitable for cross-references. 69 % ``\spec'' produces entries for specifications of entities. ``\impl'' produces entries for their 70 % implementations, and ``\use'' for their uses. 71 72 % \newcommand{\bold}[1]{{\bf #1}} 73 % \def\spec{\@bsphack\begingroup 74 % \def\protect##1{\string##1\space}\@sanitize 75 % \@wrxref{|bold}} 76 \def\impl{\@bsphack\begingroup 77 \def\protect##1{\string##1\space}\@sanitize 78 \@wrxref{|definition}} 79 \newcommand{\indexcode}[1]{{\lstinline$#1$}} 80 \def\use{\@bsphack\begingroup 81 \def\protect##1{\string##1\space}\@sanitize 82 \@wrxref{|hyperpage}} 83 \def\@wrxref#1#2{\let\thepage\relax 84 \xdef\@gtempa{\write\@indexfile{\string 85 \indexentry{#2@{\lstinline$#2$}#1}{\thepage}}}\endgroup\@gtempa 86 \if@nobreak \ifvmode\nobreak\fi\fi\@esphack} 87 %\newcommand{\use}[1]{\index{#1@{\lstinline$#1$}}} 88 %\newcommand{\impl}[1]{\index{\protect#1@{\lstinline$\protect#1$}|definition}} 89 90 % inline text and lowercase index: \Index{inline and lowercase index text} 91 % inline text and as-in index: \Index[as-is index text]{inline text} 92 % inline text but index with different as-is text: \Index[index text]{inline text} 93 \newcommand{\Index}{\@ifstar\@sIndex\@Index} 94 \newcommand{\@Index}[2][\@empty]{\lowercase{\def\temp{#2}}#2\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi} 95 \newcommand{\@sIndex}[2][\@empty]{#2\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi} 96 97 \newcommand{\newtermFontInline}{\emph} 98 \newcommand{\newterm}{\@ifstar\@snewterm\@newterm} 99 \newcommand{\@newterm}[2][\@empty]{\lowercase{\def\temp{#2}}{\newtermFontInline{#2}}\ifx#1\@empty\index{\temp}\else\index{#1@{\protect#2}}\fi} 100 \newcommand{\@snewterm}[2][\@empty]{{\newtermFontInline{#2}}\ifx#1\@empty\index{#2}\else\index{#1@{\protect#2}}\fi} 101 \makeatother 102 103 % blocks and titles 104 \newenvironment{quote2}{% 105 \list{}{\lstset{resetmargins=true}\leftmargin=\parindent\rightmargin\leftmargin}% 106 \item\relax 107 }{% 108 \endlist 109 }% quote2 110 \newenvironment{rationale}{% 111 \begin{quotation}\noindent$\Box$\enspace 112 }{% 113 \hfill\enspace$\Box$\end{quotation} 114 }% 115 \newcommand{\define}[1]{\emph{#1\/}\index{#1}} 116 \newcommand{\rewrite}{\(\Rightarrow\)} 117 \newcommand{\rewriterules}{\paragraph{Rewrite Rules}~\par\noindent} 118 \newcommand{\examples}{\paragraph{Examples}~\par\noindent} 119 \newcommand{\semantics}{\paragraph{Semantics}~\par\noindent} 120 \newcommand{\constraints}{\paragraph{Constraints}~\par\noindent} 121 \newcommand{\predefined}{\paragraph{Predefined Identifiers}~\par\noindent} 122 123 % BNF macros 124 \def\syntax{\paragraph{Syntax}\trivlist\parindent=.5in\item[\hskip.5in]} 125 \let\endsyntax=\endtrivlist 126 \newcommand{\lhs}[1]{\par{\emph{#1:}}\index{#1@{\emph{#1}}|italic}} 127 \newcommand{\rhs}{\hfil\break\hbox{\hskip1in}} 128 \newcommand{\oldlhs}[1]{\emph{#1: \ldots}\index{#1@{\emph{#1}}|italic}} 129 \newcommand{\nonterm}[1]{\emph{#1\/}\index{#1@{\emph{#1}}|italic}} 130 \newcommand{\opt}{$_{opt}$\ } 131 132 % adjust varioref package with default "section" and "page" titles, and optional title with faraway page numbers 133 % \VRef{label} => Section 2.7, \VPageref{label} => page 17 134 % \VRef[Figure]{label} => Figure 3.4, \VPageref{label} => page 17 135 \renewcommand{\reftextfaceafter}{\unskip} 136 \renewcommand{\reftextfacebefore}{\unskip} 137 \renewcommand{\reftextafter}{\unskip} 138 \renewcommand{\reftextbefore}{\unskip} 139 \renewcommand{\reftextfaraway}[1]{\unskip, p.~\pageref{#1}} 140 \renewcommand{\reftextpagerange}[2]{\unskip, pp.~\pageref{#1}--\pageref{#2}} 141 \newcommand{\VRef}[2][Section]{\ifx#1\@empty\else{#1}\nobreakspace\fi\vref{#2}} 142 \newcommand{\VPageref}[2][page]{\ifx#1\@empty\else{#1}\nobreakspace\fi\pageref{#2}} 143 144 % Go programming language 145 \lstdefinelanguage{Golang}% 146 {morekeywords=[1]{package,import,func,type,struct,return,defer,panic, recover,select,var,const,iota,},% 147 morekeywords=[2]{string,uint,uint8,uint16,uint32,uint64,int,int8,int16, int32,int64, 148 bool,float32,float64,complex64,complex128,byte,rune,uintptr, error,interface},% 149 morekeywords=[3]{map,slice,make,new,nil,len,cap,copy,close,true,false, delete,append,real,imag,complex,chan,},% 150 morekeywords=[4]{for,break,continue,range,goto,switch,case,fallthrough,if, else,default,},% 151 morekeywords=[5]{Println,Printf,Error,},% 152 sensitive=true,% 153 morecomment=[l]{//},% 154 morecomment=[s]{/*}{*/},% 155 morestring=[b]',% 156 morestring=[b]",% 157 morestring=[s]{`}{`},% 158 } 159 160 % CFA based on ANSI C 161 \lstdefinelanguage{CFA}[ANSI]{C}% 162 {morekeywords={asm,_Alignas,_Alignof,_At,_Atomic,_Bool,catch,catchResume,choose,_Complex,trait,disable,dtype,enable, 163 fallthru,finally,forall,ftype,_Generic,_Imaginary,inline,lvalue,_Noreturn,otype,restrict,_Static_assert, 164 _Thread_local,throw,throwResume,try,}, 165 }% 166 167 \lstset{ 168 language=CFA, 169 columns=flexible, 170 basicstyle=\sf\relsize{-1}, 171 tabsize=4, 172 xleftmargin=\parindent, 173 escapechar=@, 174 mathescape=true, 175 keepspaces=true, 176 showstringspaces=false, 177 showlines=true, 178 }% 179 180 \makeatletter 181 % replace/adjust listings characters that look bad in sanserif 182 \lst@CCPutMacro 183 \lst@ProcessOther{"2D}{\lst@ttfamily{-{}}{{\ttfamily\upshape -}}} % replace minus 184 \lst@ProcessOther{"3C}{\lst@ttfamily{<}{\texttt{<}}} % replace less than 185 \lst@ProcessOther{"3E}{\lst@ttfamily{<}{\texttt{>}}} % replace greater than 186 \lst@ProcessOther{"5E}{\raisebox{0.4ex}{$\scriptstyle\land\,$}} % replace circumflex 187 \lst@ProcessLetter{"5F}{\lst@ttfamily{\char95}{{\makebox[1.2ex][c]{\rule{1ex}{0.1ex}}}}} % replace underscore 188 \lst@ProcessOther{"7E}{\raisebox{0.3ex}{$\scriptstyle\sim\,$}} % replace tilde 189 %\lst@ProcessOther{"7E}{\raisebox{-.4ex}[1ex][0pt]{\textasciitilde}} % lower tilde 190 \@empty\z@\@empty 191 \makeatother 192 193 \setcounter{secnumdepth}{3} % number subsubsections 194 \setcounter{tocdepth}{3} % subsubsections in table of contents 54 \setcounter{secnumdepth}{3} % number subsubsections 55 \setcounter{tocdepth}{3} % subsubsections in table of contents 195 56 \makeindex 196 57 … … 199 60 \begin{document} 200 61 \pagestyle{headings} 201 \linenumbers 62 \linenumbers % comment out to turn off line numbering 202 63 203 64 \title{\Huge … … 213 74 }% author 214 75 \date{ 215 DRAFT\\\today 76 DRAFT \\ 77 \today 216 78 }% date 217 79 … … 241 103 242 104 \CFA\footnote{Pronounced ``C-for-all'', and written \CFA, CFA, or \CFL.} is a modern general-purpose programming-language, designed an as evolutionary step forward from the C programming language. 243 The syntax of the \CFA language builds from that ofC, and should look immediately familiar to C programmers.105 The syntax of the \CFA language builds from C, and should look immediately familiar to C programmers. 244 106 % Any language feature that is not described here can be assumed to be using the standard C11 syntax. 245 \CFA has added many modern programming-language features, which directly leads to increased safety and productivity, while maintaining interoperability with existing C programs,and maintaining C-like performance.107 \CFA adds many modern programming-language features, which directly leads to increased safety and productivity, while maintaining interoperability with existing C programs and maintaining C-like performance. 246 108 Like C, \CFA is a statically typed, procedural language with a low-overhead runtime, meaning there is no global garbage-collection. 247 109 The primary new features include parametric-polymorphism routines and types, exceptions, concurrency, and modules. … … 254 116 New programs can be written in \CFA using a combination of C and \CFA features. 255 117 \CC had a similar goal 30 years ago, but has struggled over the intervening time to incorporate modern programming-language features because of early design choices. 256 \CFA has 30 years of hindsight and a much cleaner starting point than \CC.118 \CFA has 30 years of hindsight and clean starting point. 257 119 258 120 Like \CC, there may be both an old and new ways to achieve the same effect. … … 279 141 \end{quote2} 280 142 Both programs output the same result. 281 While the \CFA I/O looks similar to the \CC style of output, there are several important differences, such as automatic spacing between variables as in Python (see also~\VRef{s:IOLibrary}).143 While the \CFA I/O looks similar to the \CC output style, there are several important differences, such as automatic spacing between variables as in Python (see also~\VRef{s:IOLibrary}). 282 144 283 145 This document is a reference manual for the \CFA programming language, targeted at \CFA programmers. 284 Implementers may alsorefer to the \CFA Programming Language Specification for details about the language syntax and semantics.146 Implementers may refer to the \CFA Programming Language Specification for details about the language syntax and semantics. 285 147 In its current state, this document covers the intended core features of the language. 286 148 Changes to the syntax and additional features are expected to be included in later revisions. … … 294 156 The original \CFA project~\cite{Ditchfield92} extended the C type system with parametric polymorphism and overloading, as opposed to the \CC approach of object-oriented extensions to the C type-system. 295 157 A first implementation of the core Cforall language was created~\cite{Bilson03,Esteves04}, but at the time there was little interesting in extending C, so work did not continue. 296 As the saying goes, ``What goes around, comes around'', and there is now renewed interest in the C programming language , so the \CFA project has been restarted.297 298 299 \section{ Motivation:Why fix C?}158 As the saying goes, ``What goes around, comes around'', and there is now renewed interest in the C programming language because of legacy code-bases, so the \CFA project has been restarted. 159 160 161 \section{Why fix C?} 300 162 301 163 Even with all its problems, C is a very popular programming language because it allows writing software at virtually any level in a computer system without restriction. … … 314 176 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. 315 177 These languages have different syntax and semantics from C, and do not interoperate directly with C, largely because of garbage collection. 316 As a result, there is a significant learning curve to move to these languages, and C legacy-code must be completerewritten.178 As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten. 317 179 These costs can be prohibitive for many companies with a large software base in C/\CC, and many programmers that require retraining to a new programming language. 318 180 … … 331 193 This feature allows users of \CFA to take advantage of the existing panoply of C libraries from inside their \CFA code. 332 194 In fact, one of the biggest issues for any new programming language is establishing a minimum level of library code to support a large body of activities. 333 Programming-language developers often state that adequate library support costs many times morethan designing and implementing the language itself.195 Programming-language developers often state that adequate library support takes more work than designing and implementing the language itself. 334 196 Like \CC, \CFA starts with immediate access to all exiting C libraries, and in many cases, can easily wrap library routines with simpler and safer interfaces, at very low cost. 335 197 … … 338 200 Whereas, \CFA wraps each of these routines into one with the common name \lstinline@abs@. 339 201 \begin{lstlisting} 202 char abs( char ); 340 203 extern "C" { 341 #include <stdlib.h> // provide C prototype for integer "abs" routine 204 int abs( int ); // use default C routine for int 342 205 } // extern "C" 343 344 char abs( char ); 345 long int abs( long int ); // @{\CFA}@ overload name "abs" for other types 206 long int abs( long int ); 346 207 long long int abs( long long int ); 347 208 float abs( float ); … … 360 221 The name ``\lstinline@abs@'' evokes the notion of absolute value, and many mathematical types provide the notion of absolute value. 361 222 Hence, knowing the name \lstinline@abs@ should be sufficient to apply it to any type where it is applicable. 362 The time savings and safety of using one name uniformly versus @N@unique names should not be underestimated.223 The time savings and safety of using one name uniformly versus $N$ unique names should not be underestimated. 363 224 364 225 … … 366 227 367 228 The command \lstinline@cfa@ is used to compile \CFA program(s). 368 This command works like the GNU \lstinline@gcc@ command, e.g.:229 This command works like the GNU \lstinline@gcc@\index{gcc} command, e.g.: 369 230 \begin{lstlisting} 370 231 cfa [ gcc-options ] C/@{\CFA}@-files [ assembler/loader-files ] 371 232 \end{lstlisting} 372 The following additional option is available: 233 By default, \CFA programs having the following \lstinline@gcc@ flags turned on: 234 \begin{description} 235 \item 236 \hspace*{-4pt}\lstinline@-std=gnu99@ 237 The 1999 C standard plus GNU extensions. 238 \end{description} 239 The following new \CFA option is available: 373 240 \begin{description} 374 241 \item … … 382 249 Numeric constants are extended to allow \Index{underscore}s within constants\index{constant!underscore}, e.g.: 383 250 \begin{lstlisting} 384 2 _147_483_648; // decimal constant251 2`_`147`_`483`_`648; // decimal constant 385 252 56_ul; // decimal unsigned long constant 386 253 0_377; // octal constant … … 408 275 the type suffixes \lstinline@U@, \lstinline@L@, etc. may start with an underscore \lstinline@1_U@, \lstinline@1_ll@ or \lstinline@1.0E10_f@. 409 276 \end{enumerate} 410 It is significantly easier to read and typelong constants when they are broken up into smaller groupings (most cultures use comma or period among digits for the same purpose).277 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). 411 278 This extension is backwards compatible, matches with the use of underscore in variable names, and appears in Ada and Java. 412 279 … … 425 292 \begin{lstlisting} 426 293 int (*f())[ 10 ] {...}; 427 ... (*f())[ 3 ] += 1;// definition mimics usage294 ... (*f())[ 3 ] += 1; // definition mimics usage 428 295 \end{lstlisting} 429 296 Essentially, the return type is wrapped around the routine name in successive layers (like an onion). … … 434 301 The only exception is bit field specification, which always appear to the right of the base type. 435 302 C and the new \CFA declarations may appear together in the same program block, but cannot be mixed within a specific declaration. 436 Unsupported are K\&R C declarations where the base type defaults to \lstinline@int@, if no type is specified\footnote{437 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}},438 e.g.:439 \begin{lstlisting}440 x; // int x441 *y; // int *y442 f( p1, p2 ); // int f( int p1, int p2 );443 f( p1, p2 ) {} // int f( int p1, int p2 ) {}444 \end{lstlisting}445 303 446 304 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. … … 451 309 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 452 310 \begin{lstlisting} 453 * int x, y; 311 `* int x, y;` 454 312 \end{lstlisting} 455 313 & … … 468 326 * [ 10 ] double v; 469 327 struct s { 470 int f0:3;328 int f0:3; 471 329 * int f1; 472 330 [ 10 ] * int f2; … … 498 356 \end{quote2} 499 357 500 As stated above, the two styles of declaration may appear together in the same block.501 Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style.502 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX systems.503 In general, mixing declaration styles in a routine or even a translation unit is not recommended, as it makes a program more difficult to read.504 Therefore, it is suggested that an entire translation unit be written in one declaration style or the other.505 506 358 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.: 507 359 \begin{quote2} … … 546 398 \end{quote2} 547 399 400 Unsupported are K\&R C declarations where the base type defaults to \lstinline@int@, if no type is specified\footnote{ 401 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}}, 402 e.g.: 403 \begin{lstlisting} 404 x; // int x 405 *y; // int *y 406 f( p1, p2 ); // int f( int p1, int p2 ); 407 f( p1, p2 ) {} // int f( int p1, int p2 ) {} 408 \end{lstlisting} 409 410 As stated above, the two styles of declaration may appear together in the same block. 411 Therefore, a programmer has the option of either continuing to use traditional C declarations or take advantage of the new style. 412 Clearly, both styles need to be supported for some time due to existing C-style header-files, particularly for UNIX systems. 413 548 414 549 415 \section{Type Operators} … … 571 437 The point of the new syntax is to allow returning multiple values from a routine~\cite{CLU,Galletly96}, e.g.: 572 438 \begin{lstlisting} 573 [ int o1, int o2, char o3 ]f( int i1, char i2, char i3 ) {439 `[ int o1, int o2, char o3 ]` f( int i1, char i2, char i3 ) { 574 440 @\emph{routine body}@ 575 441 } … … 583 449 Declaration qualifiers can only appear at the start of a routine definition, e.g.: 584 450 \begin{lstlisting} 585 extern [ int x ] g( int y ) { }451 extern [ int x ] g( int y ) {@\,@} 586 452 \end{lstlisting} 587 453 Lastly, if there are no output parameters or input parameters, the brackets and/or parentheses must still be specified; 588 454 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: 589 455 \begin{lstlisting} 590 [ ] g();// no input or output parameters456 [@\,@] g(@\,@); // no input or output parameters 591 457 [ void ] g( void ); // no input or output parameters 592 458 \end{lstlisting} … … 639 505 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: 640 506 \begin{lstlisting} 641 [ int x ]f() {507 `[ int x ]` f() { 642 508 ... x = 0; ... x = y; ... 643 return;// implicitly return x509 `return;` // implicitly return x 644 510 } 645 511 \end{lstlisting} … … 697 563 for example, the following is incorrect: 698 564 \begin{lstlisting} 699 * [ int x ] f () fp; // routine name ``f''is not allowed565 * [ int x ] f () fp; // routine name "f" is not allowed 700 566 \end{lstlisting} 701 567 … … 703 569 \section{Named and Default Arguments} 704 570 705 Named and default arguments~\cite{Hardgrave76} .\footnote{571 Named and default arguments~\cite{Hardgrave76}\footnote{ 706 572 Francez~\cite{Francez77} proposed a further extension to the named-parameter passing style, which specifies what type of communication (by value, by reference, by name) the argument is passed to the routine.} 707 573 are two mechanisms to simplify routine call. … … 864 730 \subsection{Type Nesting} 865 731 866 C allows \Index{type nesting}, but the nested types are hoisted\index{type!hoisting} (refactored) into the enclosing scope.732 \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. 867 733 \begin{quote2} 868 734 \begin{tabular}{@{}l@{\hspace{30pt}}l|l@{}} … … 919 785 920 786 int fred() { 921 s.t.c = S.R;922 struct S.T t = { S.R, 1, 2 };923 enum S.C c;924 union S.T.U u;787 s.t.c = `S.`R; // type qualification 788 struct `S.`T t = { `S.`R, 1, 2 }; 789 enum `S.`C c; 790 union `S.T.`U u; 925 791 } 926 792 \end{lstlisting} 927 793 \end{tabular} 928 794 \end{quote2} 929 930 \CFA is C \emph{incompatible} on this issue, and provides semantics similar to \CC. 931 Nested types are not hoisted and can be referenced using the field selection operator ``\lstinline@.@'', unlike the \CC scope-resolution operator ``\lstinline@::@''. 932 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. 795 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. 796 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@::@''. 933 797 934 798 … … 944 808 \begin{lstlisting} 945 809 const unsigned int size = 10; 946 int a[size]; 947 948 qsort( a, size ); // ascending order using built in ?<? 949 { // descending order by local redefinition 950 int ?<?( int a, int b ) { return a > b; } // nested routine 951 qsort( a, size ); 952 } 953 \end{lstlisting} 954 955 956 \section{Incompatible} 957 958 The following incompatibles exist between C and \CFA, and are similar to Annex C for \CC~\cite{ANSI14:C++}. 959 960 \begin{enumerate} 961 \item 962 Change type of character literal \lstinline@int@ to \lstinline@char@. 963 This change allows overloading differentiation argument type matching, e.g.: 964 \begin{lstlisting} 965 int function( int i ); 966 int function( char c ); 967 function( 'x' ); 968 \end{lstlisting} 969 It is preferable that this call match the second version of function rather than the first. \\ 970 Effect on original feature: Change to semantics of well-defined feature. ISO C programs which depend on 971 \begin{lstlisting} 972 sizeof('x') == sizeof(int) 973 \end{lstlisting} 974 will not work the same as C++ programs. \\ 975 Difficulty of converting: Simple. \\ 976 How widely used: Programs which depend upon sizeof('x') are probably rare. 977 978 \item 979 Change: String literals made \lstinline@const@ \\ 980 The type of a string literal is changed from \lstinline@array of char@ to \lstinline@array of const char@. 981 The type of a wide string literal is changed from \lstinline@array of wchar_t@ to \lstinline@array of const wchar_t@. \\ 982 Rationale: This avoids calling an inappropriate overloaded function, which might expect to be able to modify its argument. 983 Effect on original feature: Change to semantics of well-defined feature. \\ 984 Difficulty of converting: Simple syntactic transformation, because string literals can be converted to \lstinline@char*;@ (4.2). 985 The most common cases are handled by a new but deprecated standard conversion: 986 \begin{lstlisting} 987 char* p = "abc"; // valid in C, deprecated in C++ 988 char* q = expr ? "abc" : "de"; // valid in C, invalid in C++ 989 \end{lstlisting} 990 How widely used: Programs that have a legitimate reason to treat string literals as pointers to potentially modifiable memory are probably rare. 991 992 \item 993 Change: C++ does not have \emph{tentative definitions} as in C. 994 E.g., at file scope, 995 \begin{lstlisting} 996 int i; 997 int i; 998 \end{lstlisting} 999 is valid in C, invalid in C++. 1000 This makes it impossible to define mutually referential file-local static 1001 objects, if initializers are restricted to the syntactic forms of C. For example, 1002 \begin{lstlisting} 1003 struct X { int i; struct X *next; }; 1004 static struct X a; 1005 static struct X b = { 0, &a }; 1006 static struct X a = { 1, &b }; 1007 \end{lstlisting} 1008 Rationale: This avoids having different initialization rules for builtin types and userdefined types. 1009 Effect on original feature: Deletion of semantically welldefined feature. \\ 1010 Difficulty of converting: Semantic transformation. 1011 In C++, the initializer for one of a set of mutuallyreferential filelocal static objects must invoke a function call to achieve the initialization. 1012 How widely used: Seldom. 1013 1014 \item 1015 Change: A struct is a scope in C++, not in C 1016 Rationale: Class scope is crucial to C++, and a struct is a class. 1017 Effect on original feature: Change to semantics of well-defined feature. 1018 Difficulty of converting: Semantic transformation. 1019 How widely used: C programs use struct extremely frequently, but the change is only noticeable when 1020 struct, enumeration, or enumerator names are referred to outside the struct. The latter is probably 1021 rare. 1022 1023 \item 1024 Change: In C++, the name of a nested class is local to its enclosing class. 1025 In C the name of the nested class belongs to the same scope as the name of the outermost enclosing class 1026 Example: 1027 \begin{lstlisting} 1028 struct X { 1029 struct Y { /* ... */ } y; 1030 }; 1031 struct Y yy; // valid C, invalid C++ 1032 \end{lstlisting} 1033 Rationale: C++ classes have member functions which require that classes establish scopes. The C rule 1034 would leave classes as an incomplete scope mechanism which would prevent C++ programmers from maintaining 1035 locality within a class. A coherent set of scope rules for C++ based on the C rule would be very 1036 complicated and C++ programmers would be unable to predict reliably the meanings of nontrivial examples 1037 involving nested or local functions. 1038 Effect on original feature: Change of semantics of welldefined 1039 feature. 1040 Difficulty of converting: Semantic transformation. To make the struct type name visible in the scope of 1041 the enclosing struct, the struct tag could be declared in the scope of the enclosing struct, before the enclosing 1042 struct is defined. Example: 1043 \begin{lstlisting} 1044 struct Y; // struct Y and struct X are at the same scope 1045 struct X { 1046 struct Y { /* ... */ } y; 1047 }; 1048 \end{lstlisting} 1049 All the definitions of C struct types enclosed in other struct definitions and accessed outside the scope of 1050 the enclosing struct could be exported to the scope of the enclosing struct. Note: this is a consequence of 1051 the difference in scope rules, which is documented in 3.3. 1052 How widely used: Seldom. 1053 \end{enumerate} 810 int ia[size]; 811 ... // assign values to array ia 812 qsort( ia, size ); // sort ascending order using builtin ?<? 813 { 814 `int ?<?( int x, int y ) { return x > y; }` // nested routine 815 qsort( ia, size ); // sort descending order by local redefinition 816 } 817 \end{lstlisting} 818 819 Nested routines are not first-class, meaning a nested routine cannot be returned if it has references to variables in its enclosing blocks; 820 the only exception is references to the external block of the translation unit, as these variables persist for the duration of the program. 821 The following program in undefined in \CFA (and \lstinline@gcc@\index{gcc}) 822 \begin{lstlisting} 823 [* [int]( int )] foo() { // int (*foo())( int ) 824 int `i` = 7; 825 int bar( int p ) { 826 `i` += 1; // dependent on local variable 827 sout | `i` | endl; 828 } 829 return bar; // undefined because of local dependence 830 } 831 int main() { 832 * [int](int) fp = foo(); // int (*fp)(int) 833 sout | fp( 3 ) | endl; 834 } 835 \end{lstlisting} 836 because 837 838 Currently, there are no \Index{lambda} expressions, i.e., unnamed routines because routine names are very important to properly select the correct routine. 1054 839 1055 840 … … 1185 970 First the right-hand tuple is flattened and then the values are assigned individually. 1186 971 Flattening is also performed on tuple types. 1187 For example, the type \lstinline@[ int, [ int, int ], int ]@ can be coerced, using flattening, into the type lstinline@[ int, int, int, int ]@.972 For example, the type \lstinline@[ int, [ int, int ], int ]@ can be coerced, using flattening, into the type \lstinline@[ int, int, int, int ]@. 1188 973 1189 974 A \newterm{structuring coercion} is the opposite of flattening; … … 1352 1137 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1353 1138 \begin{lstlisting} 1354 L1:for ( ... ) {1355 L2:for ( ... ) {1356 L3:for ( ... ) {1357 ... break L1; ...1358 ... break L2; ...1359 ... break L3; // or break1139 `L1:` for ( ... ) { 1140 `L2:` for ( ... ) { 1141 `L3:` for ( ... ) { 1142 ... break `L1`; ... 1143 ... break `L2`; ... 1144 ... break `L3`; // or break 1360 1145 } 1361 1146 } … … 1382 1167 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{C}} \\ 1383 1168 \begin{lstlisting} 1384 L1: for ( ... ) {1385 L2: for ( ... ) {1386 L3: for ( ... ) {1387 ... continue L1; ...1388 ... continue L2; ...1389 ... continue L3; ...1169 `L1`: for ( ... ) { 1170 `L2`: for ( ... ) { 1171 `L3`: for ( ... ) { 1172 ... continue `L1`; ... 1173 ... continue `L2`; ... 1174 ... continue `L3`; ... 1390 1175 1391 1176 } … … 1623 1408 \begin{lstlisting} 1624 1409 switch ( i ) { 1625 case 1, 3, 5:1410 `case 1, 3, 5`: 1626 1411 ... 1627 case 2, 4, 6:1412 `case 2, 4, 6`: 1628 1413 ... 1629 1414 } … … 1634 1419 case 1: case 3 : case 5: 1635 1420 ... 1636 case 2: case 4 : case 6: /* even values */1421 case 2: case 4 : case 6: 1637 1422 ... 1638 1423 } … … 1655 1440 \begin{lstlisting} 1656 1441 switch ( i ) { 1657 case 1~51442 `case 1~5:` 1658 1443 ... 1659 case 10~151444 `case 10~15:` 1660 1445 ... 1661 1446 } … … 1672 1457 & 1673 1458 \begin{lstlisting} 1459 1674 1460 // 1, 2, 3, 4, 5 1675 1461 … … 2168 1954 2169 1955 2170 \section{Generics } 1956 \section{Auto Type-Inferencing} 1957 1958 Auto type-inferencing occurs in a declaration where a variable's type is inferred from its initialization expression type. 1959 \begin{quote2} 1960 \begin{tabular}{@{}l@{\hspace{30pt}}ll@{}} 1961 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CC}} & \multicolumn{1}{c}{\lstinline@gcc@}\index{gcc} \\ 1962 \begin{lstlisting} 1963 1964 auto j = 3.0 * 4; 1965 int i; 1966 auto k = i; 1967 \end{lstlisting} 1968 & 1969 \begin{lstlisting} 1970 #define expr 3.0 * i 1971 typeof(expr) j = expr; 1972 int i; 1973 typeof(i) k = i; 1974 \end{lstlisting} 1975 & 1976 \begin{lstlisting} 1977 1978 // use type of initialization expression 1979 1980 // use type of primary variable 1981 \end{lstlisting} 1982 \end{tabular} 1983 \end{quote2} 1984 The two important capabilities are: 1985 \begin{itemize} 1986 \item 1987 preventing having to determine or write out long generic types, 1988 \item 1989 ensure secondary variables, related to a primary variable, always have the same type. 1990 \end{itemize} 1991 1992 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. 1993 \lstinline@gcc@ provides \lstinline@typeof@ to declare a secondary variable from a primary variable. 1994 \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. 1995 Only for overloaded routines with the same return type is variable type-inferencing possible. 1996 Finally, \lstinline@auto@ presents the programming problem of tracking down a type when the type is actually needed. 1997 For example, given 1998 \begin{lstlisting} 1999 auto j = `...` 2000 \end{lstlisting} 2001 and the need to write a routine to compute using \lstinline@j@ 2002 \begin{lstlisting} 2003 void rtn( `...` parm ); 2004 rtn( j ); 2005 \end{lstlisting} 2006 A programmer must work backwards to determine the type of \lstinline@j@'s initialization expression, reconstructing the possibly long generic type-name. 2007 In this situation, having the type name or a short alias is very useful. 2008 2009 There is also the conundrum in type inferencing of when to \emph{\Index{brand}} a type. 2010 That is, when is the type of the variable more important than the type of its initialization expression. 2011 For example, if a change is made in an initialization expression, it can cause hundreds or thousands of cascading type changes and/or errors. 2012 At some point, a programmer wants the type of the variable to remain constant and the expression to be in error when it changes. 2013 2014 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. 2015 Should a significant need arise, this feature can be revisited. 2016 2017 2018 \section{Generics} 2171 2019 2172 2020 \CFA supports parametric polymorphism to allow users to define generic functions and types. … … 2457 2305 2458 2306 2459 \section{I/O Library} 2460 \label{s:IOLibrary} 2461 2462 The goal for \CFA I/O is to make I/O as simple as possible for the general case, while fully supporting polmorphism and user defined types in a consistent way. 2463 The general case is printing out a sequence of variables separated by whitespace. 2464 \begin{lstlisting} 2465 int x = 0, y = 1, z = 2; 2466 sout | x | y | z | endl; 2467 2468 cout << x << " " << y << " " << z << endl; 2469 \end{lstlisting} 2470 The \CC form takes almost twice as many characters. 2471 2472 The logical-or operator is used because it is the lowest priority overloadable operator, other than assignment. 2473 Therefore, most output expressions do not require parenthesis. 2474 \begin{lstlisting} 2475 int x = 0, y = 1, z = 2; 2476 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl; 2477 2478 cout << x * 3 << y + 1 << (z << 2) << (x == y) << (x | y) << (x || y) << (x > z ? 1 : 2) << endl; 2479 \end{lstlisting} 2480 2481 Finally, the logical-or operator has a link with the Shell pipe-operator for moving data, although data flows in the opposite direction. 2482 2483 \begin{figure} 2484 \begin{lstlisting}[mathescape=off] 2485 #include <fstream> 2486 2487 int main() { 2488 char c; 2489 short int si; 2490 unsigned short int usi; 2491 int i; 2492 unsigned int ui; 2493 long int li; 2494 unsigned long int uli; 2495 long long int lli; 2496 unsigned long long int ulli; 2497 float f; 2498 double d; 2499 long double ld; 2500 float _Complex fc; 2501 double _Complex dc; 2502 long double _Complex ldc; 2503 char s1[10], s2[10]; 2504 2505 ifstream in; 2506 open( &in, "read.data", "r" ); 2507 2508 &in | &c 2509 | &si | &usi | &i | &ui | &li | &uli | &lli | &ulli 2510 | &f | &d | &ld 2511 | &fc | &dc | &ldc 2512 | str( s1 ) | str( s2, 10 ); 2513 2514 sout | c | ' ' | endl 2515 | si | usi | i | ui | li | uli | lli | ulli | endl 2516 | f | d | ld | endl 2517 | f | "" | d | "" | ld | endl; 2518 2519 sepSet( sout, ", $" ); 2520 sout | fc | dc | ldc | endl 2521 | sepOn | s1 | sepOff | s2 | endl 2522 | s1 | "" | s2 | endl; 2523 } 2524 2525 $ cat read.data 2526 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 2527 $ a.out 2528 A 2529 1 2 3 4 5 6 7 8 2530 1.1 1.2 1.3 2531 1.11.21.3 2532 1.1+2.3i, $1.1-2.3i, $1.1-2.3i 2533 , $abcxyz 2534 abcxyz 2535 \end{lstlisting} 2536 \end{figure} 2537 2538 2539 \section{Standard Library} 2540 \label{s:StandardLibrary} 2541 2542 The goal of the \CFA standard-library is to wrap many of the existing C library-routines that are explicitly polymorphic into implicitly polymorphic versions. 2543 2544 2545 \subsection{malloc} 2546 2547 \begin{lstlisting} 2548 forall( otype T ) T * malloc( void ); 2549 forall( otype T ) T * malloc( char fill ); 2550 forall( otype T ) T * malloc( T * ptr, size_t size ); 2551 forall( otype T ) T * malloc( T * ptr, size_t size, unsigned char fill ); 2552 forall( otype T ) T * calloc( size_t size ); 2553 forall( otype T ) T * realloc( T * ptr, size_t size ); 2554 forall( otype T ) T * realloc( T * ptr, size_t size, unsigned char fill ); 2555 2556 forall( otype T ) T * aligned_alloc( size_t alignment ); 2557 forall( otype T ) T * memalign( size_t alignment ); // deprecated 2558 forall( otype T ) int posix_memalign( T ** ptr, size_t alignment ); 2559 2560 forall( otype T ) T * memset( T * ptr, unsigned char fill ); // use default value '\0' for fill 2561 forall( otype T ) T * memset( T * ptr ); // remove when default value available 2562 \end{lstlisting} 2563 2564 2565 \subsection{ato/strto} 2566 2567 \begin{lstlisting} 2568 int ato( const char * ptr ); 2569 unsigned int ato( const char * ptr ); 2570 long int ato( const char * ptr ); 2571 unsigned long int ato( const char * ptr ); 2572 long long int ato( const char * ptr ); 2573 unsigned long long int ato( const char * ptr ); 2574 float ato( const char * ptr ); 2575 double ato( const char * ptr ); 2576 long double ato( const char * ptr ); 2577 float _Complex ato( const char * ptr ); 2578 double _Complex ato( const char * ptr ); 2579 long double _Complex ato( const char * ptr ); 2580 2581 int strto( const char * sptr, char ** eptr, int base ); 2582 unsigned int strto( const char * sptr, char ** eptr, int base ); 2583 long int strto( const char * sptr, char ** eptr, int base ); 2584 unsigned long int strto( const char * sptr, char ** eptr, int base ); 2585 long long int strto( const char * sptr, char ** eptr, int base ); 2586 unsigned long long int strto( const char * sptr, char ** eptr, int base ); 2587 float strto( const char * sptr, char ** eptr ); 2588 double strto( const char * sptr, char ** eptr ); 2589 long double strto( const char * sptr, char ** eptr ); 2590 float _Complex strto( const char * sptr, char ** eptr ); 2591 double _Complex strto( const char * sptr, char ** eptr ); 2592 long double _Complex strto( const char * sptr, char ** eptr ); 2593 \end{lstlisting} 2594 2595 2596 \subsection{bsearch/qsort} 2597 2598 \begin{lstlisting} 2599 forall( otype T | { int ?<?( T, T ); } ) 2600 T * bsearch( const T key, const T * arr, size_t dimension ); 2601 2602 forall( otype T | { int ?<?( T, T ); } ) 2603 void qsort( const T * arr, size_t dimension ); 2604 \end{lstlisting} 2605 2606 2607 \subsection{abs} 2608 2609 \begin{lstlisting} 2610 char abs( char ); 2611 extern "C" { 2612 int abs( int ); // use default C routine for int 2613 } // extern 2614 long int abs( long int ); 2615 long long int abs( long long int ); 2616 float abs( float ); 2617 double abs( double ); 2618 long double abs( long double ); 2619 float _Complex abs( float _Complex ); 2620 double _Complex abs( double _Complex ); 2621 long double _Complex abs( long double _Complex ); 2622 \end{lstlisting} 2623 2624 2625 \subsection{random} 2626 2627 \begin{lstlisting} 2628 void randseed( long int s ); 2629 char random(); 2630 int random(); 2631 unsigned int random(); 2632 long int random(); 2633 unsigned long int random(); 2634 float random(); 2635 double random(); 2636 float _Complex random(); 2637 double _Complex random(); 2638 long double _Complex random(); 2639 \end{lstlisting} 2640 2641 2642 \subsection{min/max/swap} 2643 2644 \begin{lstlisting} 2645 forall( otype T | { int ?<?( T, T ); } ) 2646 T min( const T t1, const T t2 ); 2647 2648 forall( otype T | { int ?>?( T, T ); } ) 2649 T max( const T t1, const T t2 ); 2650 2651 forall( otype T ) 2652 void swap( T * t1, T * t2 ); 2653 \end{lstlisting} 2307 \section{Syntactic Anomalies} 2308 2309 The number 0 and 1 are treated specially in \CFA, and can be redefined as variables. 2310 One syntactic anomaly is when a field in an structure is names 0 or 1: 2311 \begin{lstlisting} 2312 struct S { 2313 int 0, 1; 2314 } s; 2315 \end{lstlisting} 2316 The problem occurs in accesing these fields using the selection operation ``\lstinline@.@'': 2317 \begin{lstlisting} 2318 s.0 = 0; // ambiguity with floating constant .0 2319 s.1 = 1; // ambiguity with floating constant .1 2320 \end{lstlisting} 2321 To make this work, a space is required after the field selection: 2322 \begin{lstlisting} 2323 `s.@\textvisiblespace@0` = 0; 2324 `s.@\textvisiblespace@1` = 1; 2325 \end{lstlisting} 2326 While this sytact is awkward, it is unlikely many programers will name fields of a structure 0 or 1. 2327 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. 2328 2329 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@*?@. 2330 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. 2331 Even with this special hack, there are 5 general cases that cannot be handled. 2332 The first case is for the function-call identifier \lstinline@?()@: 2333 \begin{lstlisting} 2334 int *@\textvisiblespace@?()(); // declaration: space required after '*' 2335 *@\textvisiblespace@?()(); // expression: space required after '*' 2336 \end{lstlisting} 2337 Without the space, the string \lstinline@*?()@ is ambiguous without N character look ahead; 2338 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument/parameter list. 2339 2340 The 4 remaining cases occur in expressions: 2341 \begin{lstlisting} 2342 i++@\textvisiblespace@?i:0; // space required before '?' 2343 i--@\textvisiblespace@?i:0; // space required before '?' 2344 i@\textvisiblespace@?++i:0; // space required after '?' 2345 i@\textvisiblespace@?--i:0; // space required after '?' 2346 \end{lstlisting} 2347 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@?@; 2348 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument list. 2349 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@; 2350 it requires scanning ahead to determine if there is a \lstinline@'('@, which is the start of an argument list. 2654 2351 2655 2352 … … 2676 2373 2677 2374 task creates a type with implicit locking, separate stack, and a thread 2375 2678 2376 2679 2377 \subsection{Monitors} … … 3775 3473 \multicolumn{1}{c|}{\textbf{\CFA/\CC}} & \multicolumn{1}{c|}{\textbf{Go}} & \multicolumn{1}{c}{\textbf{Rust}} \\ 3776 3474 \hline 3777 \begin{lstlisting} 3475 \begin{lstlisting}[boxpos=t] 3778 3476 extern "C" { 3779 3477 #include <sys/types.h> … … 3782 3480 } 3783 3481 size_t fileSize( const char *path ) { 3784 st at s;3482 struct stat s; 3785 3483 stat(path, &s); 3786 3484 return s.st_size; … … 3788 3486 \end{lstlisting} 3789 3487 & 3790 \begin{lstlisting} 3488 \begin{lstlisting}[boxpos=t] 3791 3489 /* 3792 3490 #cgo … … 3807 3505 \end{lstlisting} 3808 3506 & 3809 \begin{lstlisting} 3507 \begin{lstlisting}[boxpos=t] 3810 3508 use libc::{c_int, size_t}; 3811 3812 // The following declarations are3813 3509 // translated from sys/stat.h 3814 3510 #[repr(C)] … … 3818 3514 ... 3819 3515 } 3820 3821 3516 #[link(name = "libc")] 3822 3517 extern { … … 3824 3519 buf: *mut stat_t) -> c_int; 3825 3520 } 3826 3827 3521 fn fileSize(path: *const u8) -> size_t 3828 3522 { 3829 3523 unsafe { 3830 let mut buf: stat_t = uninit();3831 stat(path, &mut buf);3832 buf.st_size3524 let mut buf: stat_t = uninit(); 3525 stat(path, &mut buf); 3526 buf.st_size 3833 3527 } 3834 3528 } … … 3953 3647 3954 3648 3649 \begin{comment} 3955 3650 \subsubsection{Modules/Packages} 3956 3651 … … 4032 3727 } 4033 3728 \end{lstlisting} 3729 \end{comment} 3730 4034 3731 4035 3732 \subsubsection{Parallel Tasks} … … 4187 3884 \end{flushleft} 4188 3885 3886 \lstset{basicstyle=\sf\relsize{-1}} 3887 3888 4189 3889 \subsection{Summary of Language Comparison} 4190 3890 … … 4255 3955 4256 3956 3957 \appendix 3958 3959 3960 \section{Incompatible} 3961 3962 The following incompatibles exist between C and \CFA, and are similar to Annex C for \CC~\cite{ANSI14:C++}. 3963 3964 \begin{enumerate} 3965 \item 3966 Change type of character literal \lstinline@int@ to \lstinline@char@. 3967 This change allows overloading differentiation argument type matching, e.g.: 3968 \begin{lstlisting} 3969 int function( int i ); 3970 int function( char c ); 3971 function( 'x' ); 3972 \end{lstlisting} 3973 It is preferable that this call match the second version of function rather than the first. \\ 3974 Effect on original feature: Change to semantics of well-defined feature. ISO C programs which depend on 3975 \begin{lstlisting} 3976 sizeof('x') == sizeof(int) 3977 \end{lstlisting} 3978 will not work the same as C++ programs. \\ 3979 Difficulty of converting: Simple. \\ 3980 How widely used: Programs which depend upon sizeof('x') are probably rare. 3981 3982 \item 3983 Change: String literals made \lstinline@const@ \\ 3984 The type of a string literal is changed from \lstinline@array of char@ to \lstinline@array of const char@. 3985 The type of a wide string literal is changed from \lstinline@array of wchar_t@ to \lstinline@array of const wchar_t@. \\ 3986 Rationale: This avoids calling an inappropriate overloaded function, which might expect to be able to modify its argument. 3987 Effect on original feature: Change to semantics of well-defined feature. \\ 3988 Difficulty of converting: Simple syntactic transformation, because string literals can be converted to \lstinline@char*;@ (4.2). 3989 The most common cases are handled by a new but deprecated standard conversion: 3990 \begin{lstlisting} 3991 char* p = "abc"; // valid in C, deprecated in C++ 3992 char* q = expr ? "abc" : "de"; // valid in C, invalid in C++ 3993 \end{lstlisting} 3994 How widely used: Programs that have a legitimate reason to treat string literals as pointers to potentially modifiable memory are probably rare. 3995 3996 \item 3997 Change: C++ does not have \emph{tentative definitions} as in C. 3998 E.g., at file scope, 3999 \begin{lstlisting} 4000 int i; 4001 int i; 4002 \end{lstlisting} 4003 is valid in C, invalid in C++. 4004 This makes it impossible to define mutually referential file-local static 4005 objects, if initializers are restricted to the syntactic forms of C. For example, 4006 \begin{lstlisting} 4007 struct X { int i; struct X *next; }; 4008 static struct X a; 4009 static struct X b = { 0, &a }; 4010 static struct X a = { 1, &b }; 4011 \end{lstlisting} 4012 Rationale: This avoids having different initialization rules for builtin types and userdefined types. 4013 Effect on original feature: Deletion of semantically welldefined feature. \\ 4014 Difficulty of converting: Semantic transformation. 4015 In C++, the initializer for one of a set of mutuallyreferential filelocal static objects must invoke a function call to achieve the initialization. 4016 How widely used: Seldom. 4017 4018 \item 4019 Change: A struct is a scope in C++, not in C \\ 4020 Rationale: Class scope is crucial to C++, and a struct is a class. \\ 4021 Effect on original feature: Change to semantics of well-defined feature. \\ 4022 Difficulty of converting: Semantic transformation. \\ 4023 How widely used: C programs use struct extremely frequently, but the change is only noticeable when struct, enumeration, or enumerator names are referred to outside the struct. 4024 The latter is probably rare. 4025 4026 \CFA is C \emph{incompatible} on this issue, and provides semantics similar to \CC. 4027 Nested types are not hoisted and can be referenced using the field selection operator ``\lstinline@.@'', unlike the \CC scope-resolution operator ``\lstinline@::@''. 4028 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. 4029 4030 4031 \item 4032 Change: In C++, the name of a nested class is local to its enclosing class. 4033 In C the name of the nested class belongs to the same scope as the name of the outermost enclosing class 4034 Example: 4035 \begin{lstlisting} 4036 struct X { 4037 struct Y { /* ... */ } y; 4038 }; 4039 struct Y yy; // valid C, invalid C++ 4040 \end{lstlisting} 4041 Rationale: C++ classes have member functions which require that classes establish scopes. The C rule 4042 would leave classes as an incomplete scope mechanism which would prevent C++ programmers from maintaining 4043 locality within a class. A coherent set of scope rules for C++ based on the C rule would be very 4044 complicated and C++ programmers would be unable to predict reliably the meanings of nontrivial examples 4045 involving nested or local functions. 4046 Effect on original feature: Change of semantics of welldefined 4047 feature. 4048 Difficulty of converting: Semantic transformation. To make the struct type name visible in the scope of 4049 the enclosing struct, the struct tag could be declared in the scope of the enclosing struct, before the enclosing 4050 struct is defined. Example: 4051 \begin{lstlisting} 4052 struct Y; // struct Y and struct X are at the same scope 4053 struct X { 4054 struct Y { /* ... */ } y; 4055 }; 4056 \end{lstlisting} 4057 All the definitions of C struct types enclosed in other struct definitions and accessed outside the scope of 4058 the enclosing struct could be exported to the scope of the enclosing struct. Note: this is a consequence of 4059 the difference in scope rules, which is documented in 3.3. 4060 How widely used: Seldom. 4061 \end{enumerate} 4062 4063 4064 \section{I/O Library} 4065 \label{s:IOLibrary} 4066 \index{input/output library} 4067 4068 The goal for \CFA I/O is to make I/O as simple as possible for the general case, while fully supporting polmorphism and user defined types in a consistent way. 4069 The general case is printing out a sequence of variables separated by whitespace. 4070 \begin{quote2} 4071 \begin{tabular}{@{}l@{\hspace{30pt}}l@{}} 4072 \multicolumn{1}{c@{\hspace{30pt}}}{\textbf{\CFA}} & \multicolumn{1}{c}{\textbf{\CC}} \\ 4073 \begin{lstlisting} 4074 int x = 0, y = 1, z = 2; 4075 `sout` `|` x `|` y `|` z `| endl`; 4076 \end{lstlisting} 4077 & 4078 \begin{lstlisting} 4079 4080 cout << x << " " << y << " " << z << endl; 4081 \end{lstlisting} 4082 \end{tabular} 4083 \end{quote2} 4084 The \CFA form is half as many characters, and is similar to Python I/O with respect to implicit separators. 4085 4086 The logical-or operator is used because it is the lowest-priority overloadable operator, other than assignment. 4087 Therefore, fewer output expressions require parenthesis. 4088 \begin{quote2} 4089 \begin{tabular}{@{}ll@{}} 4090 \textbf{\CFA:} 4091 & 4092 \begin{lstlisting} 4093 sout | x * 3 | y + 1 | z << 2 | x == y | (x | y) | (x || y) | (x > z ? 1 : 2) | endl; 4094 \end{lstlisting} 4095 \\ 4096 \textbf{\CC:} 4097 & 4098 \begin{lstlisting} 4099 cout << x * 3 << y + 1 << (z << 2) << (x == y) << (x | y) << (x || y) << (x > z ? 1 : 2) << endl; 4100 \end{lstlisting} 4101 \end{tabular} 4102 \end{quote2} 4103 Finally, the logical-or operator has a link with the Shell pipe-operator for moving data, although data flows in the opposite direction. 4104 4105 The implicit seperator\index{I/O separator} character (space/blank) is a separator not a terminator. 4106 The rules for implicitly adding the separator are: 4107 \begin{enumerate} 4108 \item 4109 A seperator does not appear at the start or end of a line. 4110 \begin{lstlisting}[belowskip=0pt] 4111 sout 1 | 2 | 3 | endl; 4112 \end{lstlisting} 4113 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4114 1 2 3 4115 \end{lstlisting} 4116 \item 4117 A seperator does not appear before or after a character literal or variable. 4118 \begin{lstlisting} 4119 sout | '1' | '2' | '3' | endl; 4120 123 4121 \end{lstlisting} 4122 \item 4123 A seperator does not appear before or after a null (empty) C string 4124 \begin{lstlisting} 4125 sout | 1 | "" | 2 | "" | 3 | endl; 4126 123 4127 \end{lstlisting} 4128 which is a local mechanism to disable insertion of the separator character. 4129 \item 4130 A seperator does not appear before a C string starting with the \Index{extended ASCII}\index{ASCII} characters: \lstinline[mathescape=off]@([{$£¥¿«@ 4131 %$ 4132 \begin{lstlisting}[mathescape=off] 4133 sout | "x (" | 1 | "x [" | 2 | "x {" | 3 | "x $" | 4 | "x £" | 5 | "x ¥" | 6 | "x ¿" | 7 | "x «" | 8 | endl; 4134 \end{lstlisting} 4135 %$ 4136 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4137 x (1 x [2 x {3 x $4 x £5 x ¥6 x ¿7 x «8 4138 \end{lstlisting} 4139 %$ 4140 \item 4141 A seperator does not appear after a C string ending with the extended ASCII characters: \lstinline@,.:;!?)]}%¢»@ 4142 \begin{lstlisting}[belowskip=0pt] 4143 sout | 1 | ", x" | 2 | ". x" | 3 | ": x" | 4 | "; x" | 5 | "! x" | 6 | "? x" | 7 | ") x" | 8 | "] x" | 9 | "} x" 4144 | 10 | "% x" | 11 | L"¢ x" | 12 | L"» x" | endl; 4145 \end{lstlisting} 4146 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4147 1, x 2. x 3: x 4; x 5! x 6? x 7) x 8] x 9} x 10% x 11¢ 12» 4148 \end{lstlisting} 4149 \item 4150 A seperator does not appear before or after a C string begining/ending with the characters: \lstinline@\f\n\r\t\v\`'"@ 4151 \begin{lstlisting}[belowskip=0pt] 4152 sout | "x '" | 1 | "' x \`" | 2 | "\` x \"" | 3 | "\" x" | endl; 4153 \end{lstlisting} 4154 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4155 x '1' x \`2\` x "3" x 4156 \end{lstlisting} 4157 \begin{lstlisting}[showtabs=true,aboveskip=0pt] 4158 sout | "x\t" | 1 | "\tx" | endl; 4159 x 1 x 4160 \end{lstlisting} 4161 \end{enumerate} 4162 The following \CC-style \Index{manipulator}s allow further control over implicit seperation. 4163 \begin{lstlisting}[mathescape=off,belowskip=0pt] 4164 sout | sepOn | 1 | 2 | 3 | sepOn | endl; // separator at start of line 4165 \end{lstlisting} 4166 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4167 1 2 3 4168 \end{lstlisting} 4169 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt] 4170 sout | 1 | sepOff | 2 | 3 | endl; // turn off implicit separator temporarily 4171 \end{lstlisting} 4172 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4173 12 3 4174 \end{lstlisting} 4175 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt] 4176 sout | sepDisable | 1 | 2 | 3 | endl; // turn off implicit separation, affects all subsequent prints 4177 \end{lstlisting} 4178 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4179 123 4180 \end{lstlisting} 4181 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt] 4182 sout | 1 | sepOn | 2 | 3 | endl; // turn on implicit separator temporarily 4183 \end{lstlisting} 4184 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4185 1 23 4186 \end{lstlisting} 4187 \begin{lstlisting}[mathescape=off,aboveskip=0pt,belowskip=0pt] 4188 sout | sepEnable | 1 | 2 | 3 | endl; // turn on implicit separation, affects all subsequent prints 4189 \end{lstlisting} 4190 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt,belowskip=0pt] 4191 1 2 3 4192 \end{lstlisting} 4193 \begin{lstlisting}[mathescape=off,aboveskip=0pt,aboveskip=0pt,belowskip=0pt] 4194 sepSet( sout, ", $" ); // change separator from " " to ", $" 4195 sout | 1 | 2 | 3 | endl; 4196 \end{lstlisting} 4197 %$ 4198 \begin{lstlisting}[mathescape=off,showspaces=true,aboveskip=0pt] 4199 1, $2, $3 4200 \end{lstlisting} 4201 %$ 4202 \VRef[Figure]{f:ExampleIO} shows an example of input and output I/O in \CFA. 4203 4204 \begin{figure} 4205 \begin{lstlisting}[mathescape=off] 4206 #include <fstream> 4207 4208 int main() { 4209 char c; // basic types 4210 short int si; 4211 unsigned short int usi; 4212 int i; 4213 unsigned int ui; 4214 long int li; 4215 unsigned long int uli; 4216 long long int lli; 4217 unsigned long long int ulli; 4218 float f; 4219 double d; 4220 long double ld; 4221 float _Complex fc; 4222 double _Complex dc; 4223 long double _Complex ldc; 4224 char s1[10], s2[10]; 4225 4226 ifstream in; // create / open file 4227 open( &in, "input.data", "r" ); 4228 4229 &in | &c // character 4230 | &si | &usi | &i | &ui | &li | &uli | &lli | &ulli // integral 4231 | &f | &d | &ld // floating point 4232 | &fc | &dc | &ldc // floating-point complex 4233 | cstr( s1 ) | cstr( s2, 10 ); // C string, length unchecked and checked 4234 4235 sout | c | ' ' | endl // character 4236 | si | usi | i | ui | li | uli | lli | ulli | endl // integral 4237 | f | d | ld | endl // floating point 4238 | fc | dc | ldc | endl; // complex 4239 sout | endl; 4240 sout | f | "" | d | "" | ld | endl // floating point without separator 4241 | sepDisable | fc | dc | ldc | sepEnable | endl // complex without separator 4242 | sepOn | s1 | sepOff | s2 | endl // local separator removal 4243 | s1 | "" | s2 | endl; // C string withou separator 4244 sout | endl; 4245 sepSet( sout, ", $" ); // change separator, maximum of 15 characters 4246 sout | f | d | ld | endl // floating point without separator 4247 | fc | dc | ldc | endl // complex without separator 4248 | s1 | s2 | endl; 4249 } 4250 4251 $ cat input.data 4252 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 4253 $ a.out 4254 A 4255 1 2 3 4 5 6 7 8 4256 1.1 1.2 1.3 4257 1.1+2.3i 1.1-2.3i 1.1-2.3i 4258 4259 1.11.21.3 4260 1.1+2.3i1.1-2.3i1.1-2.3i 4261 abcxyz 4262 abcxyz 4263 4264 1.1, $1.2, $1.3 4265 1.1+2.3i, $1.1-2.3i, $1.1-2.3i 4266 abc, $xyz 4267 \end{lstlisting} 4268 \caption{Example I/O} 4269 \label{f:ExampleIO} 4270 \end{figure} 4271 4272 4273 \section{Standard Library} 4274 \label{s:StandardLibrary} 4275 4276 The goal of the \CFA standard-library is to wrap many of the existing C library-routines that are explicitly polymorphic into implicitly polymorphic versions. 4277 4278 4279 \subsection{malloc} 4280 4281 \begin{lstlisting} 4282 forall( otype T ) T * malloc( void ); 4283 forall( otype T ) T * malloc( char fill ); 4284 forall( otype T ) T * malloc( T * ptr, size_t size ); 4285 forall( otype T ) T * malloc( T * ptr, size_t size, unsigned char fill ); 4286 forall( otype T ) T * calloc( size_t size ); 4287 forall( otype T ) T * realloc( T * ptr, size_t size ); 4288 forall( otype T ) T * realloc( T * ptr, size_t size, unsigned char fill ); 4289 4290 forall( otype T ) T * aligned_alloc( size_t alignment ); 4291 forall( otype T ) T * memalign( size_t alignment ); // deprecated 4292 forall( otype T ) int posix_memalign( T ** ptr, size_t alignment ); 4293 4294 forall( otype T ) T * memset( T * ptr, unsigned char fill ); // use default value '\0' for fill 4295 forall( otype T ) T * memset( T * ptr ); // remove when default value available 4296 \end{lstlisting} 4297 4298 4299 \subsection{ato/strto} 4300 4301 \begin{lstlisting} 4302 int ato( const char * ptr ); 4303 unsigned int ato( const char * ptr ); 4304 long int ato( const char * ptr ); 4305 unsigned long int ato( const char * ptr ); 4306 long long int ato( const char * ptr ); 4307 unsigned long long int ato( const char * ptr ); 4308 float ato( const char * ptr ); 4309 double ato( const char * ptr ); 4310 long double ato( const char * ptr ); 4311 float _Complex ato( const char * ptr ); 4312 double _Complex ato( const char * ptr ); 4313 long double _Complex ato( const char * ptr ); 4314 4315 int strto( const char * sptr, char ** eptr, int base ); 4316 unsigned int strto( const char * sptr, char ** eptr, int base ); 4317 long int strto( const char * sptr, char ** eptr, int base ); 4318 unsigned long int strto( const char * sptr, char ** eptr, int base ); 4319 long long int strto( const char * sptr, char ** eptr, int base ); 4320 unsigned long long int strto( const char * sptr, char ** eptr, int base ); 4321 float strto( const char * sptr, char ** eptr ); 4322 double strto( const char * sptr, char ** eptr ); 4323 long double strto( const char * sptr, char ** eptr ); 4324 float _Complex strto( const char * sptr, char ** eptr ); 4325 double _Complex strto( const char * sptr, char ** eptr ); 4326 long double _Complex strto( const char * sptr, char ** eptr ); 4327 \end{lstlisting} 4328 4329 4330 \subsection{bsearch/qsort} 4331 4332 \begin{lstlisting} 4333 forall( otype T | { int ?<?( T, T ); } ) 4334 T * bsearch( const T key, const T * arr, size_t dimension ); 4335 4336 forall( otype T | { int ?<?( T, T ); } ) 4337 void qsort( const T * arr, size_t dimension ); 4338 \end{lstlisting} 4339 4340 4341 \subsection{abs} 4342 4343 \begin{lstlisting} 4344 char abs( char ); 4345 extern "C" { 4346 int abs( int ); // use default C routine for int 4347 } // extern "C" 4348 long int abs( long int ); 4349 long long int abs( long long int ); 4350 float abs( float ); 4351 double abs( double ); 4352 long double abs( long double ); 4353 float _Complex abs( float _Complex ); 4354 double _Complex abs( double _Complex ); 4355 long double _Complex abs( long double _Complex ); 4356 \end{lstlisting} 4357 4358 4359 \subsection{floor/ceil} 4360 4361 \begin{lstlisting} 4362 float floor( float ); 4363 extern "C" { 4364 double floor( double ); // use C routine for double 4365 } // extern "C" 4366 long double floor( long double ); 4367 4368 float ceil( float ); 4369 extern "C" { 4370 double ceil( double ); // use C routine for double 4371 } // extern "C" 4372 long double ceil( long double ); 4373 \end{lstlisting} 4374 4375 4376 \subsection{random} 4377 4378 \begin{lstlisting} 4379 void rand48seed( long int s ); 4380 char rand48(); 4381 int rand48(); 4382 unsigned int rand48(); 4383 long int rand48(); 4384 unsigned long int rand48(); 4385 float rand48(); 4386 double rand48(); 4387 float _Complex rand48(); 4388 double _Complex rand48(); 4389 long double _Complex rand48(); 4390 \end{lstlisting} 4391 4392 4393 \subsection{min/max/swap} 4394 4395 \begin{lstlisting} 4396 forall( otype T | { int ?<?( T, T ); } ) 4397 T min( const T t1, const T t2 ); 4398 4399 forall( otype T | { int ?>?( T, T ); } ) 4400 T max( const T t1, const T t2 ); 4401 4402 forall( otype T ) 4403 void swap( T * t1, T * t2 ); 4404 \end{lstlisting} 4405 4406 4407 \section{Rational Numbers} 4408 \label{s:RationalNumbers} 4409 4410 Rational numbers are numbers written as a ratio, i.e., as a fraction, where the numerator (top number) and the denominator (bottom number) are whole numbers. 4411 When creating and computing with rational numbers, results are constantly reduced to keep the numerator and denominator as small as possible. 4412 4413 \begin{lstlisting} 4414 // implementation 4415 struct Rational { 4416 long int numerator, denominator; // invariant: denominator > 0 4417 }; // Rational 4418 4419 // constants 4420 extern struct Rational 0; 4421 extern struct Rational 1; 4422 4423 // constructors 4424 Rational rational(); 4425 Rational rational( long int n ); 4426 Rational rational( long int n, long int d ); 4427 4428 // getter/setter for numerator/denominator 4429 long int numerator( Rational r ); 4430 long int numerator( Rational r, long int n ); 4431 long int denominator( Rational r ); 4432 long int denominator( Rational r, long int d ); 4433 4434 // comparison 4435 int ?==?( Rational l, Rational r ); 4436 int ?!=?( Rational l, Rational r ); 4437 int ?<?( Rational l, Rational r ); 4438 int ?<=?( Rational l, Rational r ); 4439 int ?>?( Rational l, Rational r ); 4440 int ?>=?( Rational l, Rational r ); 4441 4442 // arithmetic 4443 Rational -?( Rational r ); 4444 Rational ?+?( Rational l, Rational r ); 4445 Rational ?-?( Rational l, Rational r ); 4446 Rational ?*?( Rational l, Rational r ); 4447 Rational ?/?( Rational l, Rational r ); 4448 4449 // conversion 4450 double widen( Rational r ); 4451 Rational narrow( double f, long int md ); 4452 4453 // I/O 4454 forall( dtype istype | istream( istype ) ) istype * ?|?( istype *, Rational * ); 4455 forall( dtype ostype | ostream( ostype ) ) ostype * ?|?( ostype *, Rational ); 4456 \end{lstlisting} 4457 4458 4257 4459 \bibliographystyle{plain} 4258 \bibliography{ /usr/local/bibliographies/pl.bib}4460 \bibliography{cfa} 4259 4461 4260 4462 -
src/CodeGen/CodeGenerator.cc
rdb4ecc5 r70a06f6 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon Apr 11 15:30:52201612 // Last Modified On : Thu Apr 14 15:40:00 2016 13 13 // Update Count : 255 14 14 // … … 485 485 486 486 void CodeGenerator::visit( UntypedOffsetofExpr *offsetofExpr ) { 487 assert( false );487 assert( false && "UntypedOffsetofExpr should not reach code generation" ); 488 488 } 489 489 … … 494 494 output << ", " << mangleName( offsetofExpr->get_member() ); 495 495 output << ")"; 496 } 497 498 void CodeGenerator::visit( OffsetPackExpr *offsetPackExpr ) { 499 assert( false && "OffsetPackExpr should not reach code generation" ); 496 500 } 497 501 -
src/CodeGen/CodeGenerator.h
rdb4ecc5 r70a06f6 65 65 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 66 66 virtual void visit( OffsetofExpr *offsetofExpr ); 67 virtual void visit( OffsetPackExpr *offsetPackExpr ); 67 68 virtual void visit( LogicalExpr *logicalExpr ); 68 69 virtual void visit( ConditionalExpr *conditionalExpr ); -
src/GenPoly/Box.cc
rdb4ecc5 r70a06f6 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : T ue Feb 09 14:39:52201612 // Last Modified On : Thu Apr 14 15:57:46 2016 13 13 // Update Count : 295 14 14 // … … 30 30 #include "FindFunction.h" 31 31 #include "ScopedMap.h" 32 #include "ScopedSet.h" 32 33 #include "ScrubTyVars.h" 33 34 … … 62 63 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 63 64 64 /// Key for a unique concrete type; generic base type paired with type parameter list 65 struct ConcreteType { 66 ConcreteType() : base(NULL), params() {} 67 68 ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); } 69 70 ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); } 65 /// Abstracts type equality for a list of parameter types 66 struct TypeList { 67 TypeList() : params() {} 68 TypeList( const std::list< Type* > &_params ) : params() { cloneAll(_params, params); } 69 TypeList( std::list< Type* > &&_params ) : params( _params ) {} 70 71 TypeList( const TypeList &that ) : params() { cloneAll(that.params, params); } 72 TypeList( TypeList &&that ) : params( std::move( that.params ) ) {} 71 73 72 74 /// Extracts types from a list of TypeExpr* 73 ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base),params() {75 TypeList( const std::list< TypeExpr* >& _params ) : params() { 74 76 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) { 75 77 params.push_back( (*param)->get_type()->clone() ); … … 77 79 } 78 80 79 ConcreteType& operator= (const ConcreteType& that) {81 TypeList& operator= ( const TypeList &that ) { 80 82 deleteAll( params ); 83 81 84 params.clear(); 82 83 base = that.base;84 85 cloneAll( that.params, params ); 85 86 … … 87 88 } 88 89 89 ~ConcreteType() { deleteAll( params ); } 90 91 bool operator== (const ConcreteType& that) const { 92 if ( base != that.base ) return false; 90 TypeList& operator= ( TypeList &&that ) { 91 deleteAll( params ); 92 93 params = std::move( that.params ); 94 95 return *this; 96 } 97 98 ~TypeList() { deleteAll( params ); } 99 100 bool operator== ( const TypeList& that ) const { 101 if ( params.size() != that.params.size() ) return false; 93 102 94 103 SymTab::Indexer dummy; 95 if ( params.size() != that.params.size() ) return false;96 104 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) { 97 105 if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false; … … 100 108 } 101 109 102 AggregateDecl *base; ///< Base generic type103 110 std::list< Type* > params; ///< Instantiation parameters 104 111 }; 105 112 106 /// Maps a concrete typeto the some value, accounting for scope107 template< typename Value >113 /// Maps a key and a TypeList to the some value, accounting for scope 114 template< typename Key, typename Value > 108 115 class InstantiationMap { 109 /// Information about a specific instantiation of a generic type 110 struct Instantiation { 111 ConcreteType key; ///< Instantiation parameters for this type 112 Value *value; ///< Value for this instantiation 113 114 Instantiation() : key(), value(0) {} 115 Instantiation(const ConcreteType &_key, Value *_value) : key(_key), value(_value) {} 116 }; 117 /// Map of generic types to instantiations of them 118 typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope; 119 120 std::vector< Scope > scopes; ///< list of scopes, from outermost to innermost 116 /// Wraps value for a specific (Key, TypeList) combination 117 typedef std::pair< TypeList, Value* > Instantiation; 118 /// List of TypeLists paired with their appropriate values 119 typedef std::vector< Instantiation > ValueList; 120 /// Underlying map type; maps keys to a linear list of corresponding TypeLists and values 121 typedef ScopedMap< Key*, ValueList > InnerMap; 122 123 InnerMap instantiations; ///< instantiations 121 124 122 125 public: 123 126 /// Starts a new scope 124 void beginScope() { 125 Scope scope; 126 scopes.push_back(scope); 127 } 127 void beginScope() { instantiations.beginScope(); } 128 128 129 129 /// Ends a scope 130 void endScope() { 131 scopes.pop_back(); 132 } 133 134 /// Default constructor initializes with one scope 135 InstantiationMap() { beginScope(); } 136 137 // private: 138 /// Gets the value for the concrete instantiation of this type, assuming it has already been instantiated in the current scope. 139 /// Returns NULL on none such. 140 Value *lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) { 141 ConcreteType key(generic, params); 142 // scan scopes from innermost out 143 for ( typename std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) { 144 // skip scope if no instantiations of this generic type 145 typename Scope::const_iterator insts = scope->find( generic ); 146 if ( insts == scope->end() ) continue; 147 // look through instantiations for matches to concrete type 148 for ( typename std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) { 149 if ( inst->key == key ) return inst->value; 130 void endScope() { instantiations.endScope(); } 131 132 /// Gets the value for the (key, typeList) pair, returns NULL on none such. 133 Value *lookup( Key *key, const std::list< TypeExpr* >& params ) const { 134 TypeList typeList( params ); 135 136 // scan scopes for matches to the key 137 for ( typename InnerMap::const_iterator insts = instantiations.find( key ); insts != instantiations.end(); insts = instantiations.findNext( insts, key ) ) { 138 for ( typename ValueList::const_reverse_iterator inst = insts->second.rbegin(); inst != insts->second.rend(); ++inst ) { 139 if ( inst->first == typeList ) return inst->second; 150 140 } 151 141 } 152 // no matching instantiation found142 // no matching instantiations found 153 143 return 0; 154 144 } 155 public: 156 // StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); } 157 // UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); } 158 159 // private: 160 /// Adds a value for a concrete type to the current scope 161 void insert( AggregateDecl *generic, const std::list< TypeExpr* > ¶ms, Value *value ) { 162 ConcreteType key(generic, params); 163 scopes.back()[generic].push_back( Instantiation( key, value ) ); 164 } 165 // public: 166 // void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); } 167 // void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); } 145 146 /// Adds a value for a (key, typeList) pair to the current scope 147 void insert( Key *key, const std::list< TypeExpr* > ¶ms, Value *value ) { 148 instantiations[ key ].push_back( Instantiation( TypeList( params ), value ) ); 149 } 168 150 }; 169 151 … … 178 160 virtual Declaration *mutate( UnionDecl *unionDecl ); 179 161 }; 180 162 181 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 182 164 class Pass1 : public PolyMutator { … … 197 179 virtual void doEndScope(); 198 180 private: 199 /// Makes a new temporary array holding the offsets of the fields of `type`, and returns a new variable expression referencing it200 Expression *makeOffsetArray( StructInstType *type );201 181 /// Pass the extra type parameters from polymorphic generic arguments or return types into a function application 202 182 void passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ); … … 225 205 ObjectDecl *makeTemporary( Type *type ); 226 206 227 std::map< std::string, DeclarationWithType *> assignOps; 228 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; 229 ScopedMap< std::string, DeclarationWithType* > adapters; 207 ScopedMap< std::string, DeclarationWithType *> assignOps; ///< Currently known type variable assignment operators 208 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; ///< Currently known assignment operators 209 ScopedMap< std::string, DeclarationWithType* > adapters; ///< Set of adapter functions in the current scope 210 230 211 DeclarationWithType *retval; 231 212 bool useRetval; … … 233 214 }; 234 215 235 /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well 216 /// * Moves polymorphic returns in function types to pointer-type parameters 217 /// * adds type size and assertion parameters to parameter lists 236 218 class Pass2 : public PolyMutator { 237 219 public: … … 244 226 virtual Type *mutate( PointerType *pointerType ); 245 227 virtual Type *mutate( FunctionType *funcType ); 228 246 229 private: 247 230 void addAdapters( FunctionType *functionType ); … … 253 236 class GenericInstantiator : public DeclMutator { 254 237 /// Map of (generic type, parameter list) pairs to concrete type instantiations 255 InstantiationMap< AggregateDecl > instantiations;238 InstantiationMap< AggregateDecl, AggregateDecl > instantiations; 256 239 /// Namer for concrete types 257 240 UniqueName typeNamer; … … 278 261 }; 279 262 280 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference; 281 /// also fixes offsetof expressions. 282 class MemberExprFixer : public PolyMutator { 283 public: 263 /// Replaces member and size/align/offsetof expressions on polymorphic generic types with calculated expressions. 264 /// * Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference 265 /// * Calculates polymorphic offsetof expressions from offset array 266 /// * Inserts dynamic calculation of polymorphic type layouts where needed 267 class PolyGenericCalculator : public PolyMutator { 268 public: 284 269 template< typename DeclClass > 285 270 DeclClass *handleDecl( DeclClass *decl, Type *type ); … … 292 277 virtual Type *mutate( FunctionType *funcType ); 293 278 virtual Expression *mutate( MemberExpr *memberExpr ); 279 virtual Expression *mutate( SizeofExpr *sizeofExpr ); 280 virtual Expression *mutate( AlignofExpr *alignofExpr ); 294 281 virtual Expression *mutate( OffsetofExpr *offsetofExpr ); 282 virtual Expression *mutate( OffsetPackExpr *offsetPackExpr ); 283 284 virtual void doBeginScope(); 285 virtual void doEndScope(); 286 287 private: 288 /// Makes a new variable in the current scope with the given name, type & optional initializer 289 ObjectDecl *makeVar( const std::string &name, Type *type, Initializer *init = 0 ); 290 /// returns true if the type has a dynamic layout; such a layout will be stored in appropriately-named local variables when the function returns 291 bool findGeneric( Type *ty ); 292 /// adds type parameters to the layout call; will generate the appropriate parameters if needed 293 void addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ); 294 295 /// Enters a new scope for type-variables, adding the type variables from ty 296 void beginTypeScope( Type *ty ); 297 /// Exits the type-variable scope 298 void endTypeScope(); 299 300 ScopedSet< std::string > knownLayouts; ///< Set of generic type layouts known in the current scope, indexed by sizeofName 301 ScopedSet< std::string > knownOffsets; ///< Set of non-generic types for which the offset array exists in the current scope, indexed by offsetofName 295 302 }; 296 303 … … 342 349 Pass2 pass2; 343 350 GenericInstantiator instantiator; 344 MemberExprFixer memberFixer;351 PolyGenericCalculator polyCalculator; 345 352 Pass3 pass3; 346 353 347 354 layoutBuilder.mutateDeclarationList( translationUnit ); 348 355 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 349 356 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 350 // instantiateGeneric( translationUnit );351 357 instantiator.mutateDeclarationList( translationUnit ); 352 mutateTranslationUnit/*All*/( translationUnit, memberFixer );358 mutateTranslationUnit/*All*/( translationUnit, polyCalculator ); 353 359 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 354 360 } … … 364 370 return functionDecl; 365 371 } 366 372 367 373 /// Get a list of type declarations that will affect a layout function 368 374 std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) { … … 374 380 } 375 381 } 376 382 377 383 return otypeDecls; 378 384 } … … 381 387 void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) { 382 388 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 383 389 384 390 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 385 391 TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param ); 386 layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 387 layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 392 std::string paramName = mangleType( ¶mType ); 393 layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( paramName ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 394 layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( paramName ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) ); 388 395 } 389 396 } 390 397 391 398 /// Builds a layout function declaration 392 FunctionDecl *buildLayoutFunctionDecl( const std::string &typeName, unsigned int functionNesting, FunctionType *layoutFnType ) {399 FunctionDecl *buildLayoutFunctionDecl( AggregateDecl *typeDecl, unsigned int functionNesting, FunctionType *layoutFnType ) { 393 400 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units 394 401 // because each unit generates copies of the default routines for each aggregate. 395 402 FunctionDecl *layoutDecl = new FunctionDecl( 396 "__layoutof_" + typeName, functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false );403 layoutofName( typeDecl ), functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false ); 397 404 layoutDecl->fixUniqueId(); 398 405 return layoutDecl; … … 437 444 return makeCond( ifCond, ifExpr ); 438 445 } 439 446 440 447 /// adds an expression to a compound statement 441 448 void addExpr( CompoundStmt *stmts, Expression *expr ) { … … 447 454 stmts->get_kids().push_back( stmt ); 448 455 } 449 456 450 457 Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) { 451 458 // do not generate layout function for "empty" tag structs … … 460 467 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 461 468 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 462 463 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );469 470 ObjectDecl *sizeParam = new ObjectDecl( sizeofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 464 471 layoutFnType->get_parameters().push_back( sizeParam ); 465 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );472 ObjectDecl *alignParam = new ObjectDecl( alignofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 ); 466 473 layoutFnType->get_parameters().push_back( alignParam ); 467 ObjectDecl *offsetParam = new ObjectDecl( "__offsetof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );474 ObjectDecl *offsetParam = new ObjectDecl( offsetofName( structDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 ); 468 475 layoutFnType->get_parameters().push_back( offsetParam ); 469 476 addOtypeParams( layoutFnType, otypeParams ); 470 477 471 478 // build function decl 472 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl ->get_name(), functionNesting, layoutFnType );479 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl, functionNesting, layoutFnType ); 473 480 474 481 // calculate struct layout in function body … … 490 497 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) ); 491 498 } 492 499 493 500 // place current size in the current offset index 494 501 addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ), … … 498 505 // add member size to current size 499 506 addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) ); 500 507 501 508 // take max of member alignment and global alignment 502 509 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) ); … … 508 515 return structDecl; 509 516 } 510 517 511 518 Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) { 512 519 // do not generate layout function for "empty" tag unions 513 520 if ( unionDecl->get_members().empty() ) return unionDecl; 514 521 515 522 // get parameters that can change layout, exiting early if none 516 523 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() ); … … 521 528 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 522 529 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType ); 523 524 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );530 531 ObjectDecl *sizeParam = new ObjectDecl( sizeofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 ); 525 532 layoutFnType->get_parameters().push_back( sizeParam ); 526 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );533 ObjectDecl *alignParam = new ObjectDecl( alignofName( unionDecl->get_name() ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 ); 527 534 layoutFnType->get_parameters().push_back( alignParam ); 528 535 addOtypeParams( layoutFnType, otypeParams ); 529 536 530 537 // build function decl 531 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl ->get_name(), functionNesting, layoutFnType );538 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl, functionNesting, layoutFnType ); 532 539 533 540 // calculate union layout in function body … … 538 545 assert( dwt ); 539 546 Type *memberType = dwt->get_type(); 540 547 541 548 // take max member size and global size 542 549 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) ); 543 550 544 551 // take max of member alignment and global alignment 545 552 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) ); … … 551 558 return unionDecl; 552 559 } 553 560 554 561 ////////////////////////////////////////// Pass1 //////////////////////////////////////////////////// 555 562 … … 612 619 return 0; 613 620 } 614 621 615 622 /// returns T if the given declaration is: (*?=?)(T *, T) for some type T (return not checked, but maybe should be), NULL otherwise 616 623 /// Only picks assignments where neither parameter is cv-qualified … … 624 631 Type *paramType2 = funType->get_parameters().back()->get_type(); 625 632 if ( paramType2->get_qualifiers() != defaultQualifiers ) return 0; 626 633 627 634 if ( PointerType *pointerType = dynamic_cast< PointerType* >( paramType1 ) ) { 628 635 Type *baseType1 = pointerType->get_base(); … … 653 660 654 661 DeclarationWithType *Pass1::mutate( FunctionDecl *functionDecl ) { 655 // if this is a polymorphicassignment function, put it in the map for this scope662 // if this is a assignment function, put it in the map for this scope 656 663 if ( Type *assignedType = isAssignment( functionDecl ) ) { 657 664 if ( ! dynamic_cast< TypeInstType* >( assignedType ) ) { … … 662 669 if ( functionDecl->get_statements() ) { // empty routine body ? 663 670 doBeginScope(); 664 TyVarMap oldtyVars = scopeTyVars;665 std::map< std::string, DeclarationWithType *> oldassignOps = assignOps;671 scopeTyVars.beginScope(); 672 assignOps.beginScope(); 666 673 DeclarationWithType *oldRetval = retval; 667 674 bool oldUseRetval = useRetval; … … 704 711 functionDecl->set_statements( functionDecl->get_statements()->acceptMutator( *this ) ); 705 712 706 scopeTyVars = oldtyVars; 707 assignOps = oldassignOps; 708 // std::cerr << "end FunctionDecl: "; 709 // for ( TyVarMap::iterator i = scopeTyVars.begin(); i != scopeTyVars.end(); ++i ) { 710 // std::cerr << i->first << " "; 711 // } 712 // std::cerr << "\n"; 713 scopeTyVars.endScope(); 714 assignOps.endScope(); 713 715 retval = oldRetval; 714 716 useRetval = oldUseRetval; … … 743 745 } 744 746 745 Expression *Pass1::makeOffsetArray( StructInstType *ty ) {746 std::list<Expression*> noDesignators;747 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members();748 749 // make a new temporary array750 Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );751 std::stringstream lenGen;752 lenGen << baseMembers.size();753 ConstantExpr *lenExpr = new ConstantExpr( Constant( offsetType->clone(), lenGen.str() ) );754 ObjectDecl *arrayTemp = makeTemporary( new ArrayType( Type::Qualifiers(), offsetType, lenExpr, false, false ) );755 756 // build initializer list for temporary757 std::list< Initializer* > inits;758 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) {759 DeclarationWithType *memberDecl;760 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) {761 memberDecl = origMember->clone();762 } else {763 memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 );764 }765 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ), noDesignators ) );766 }767 arrayTemp->set_init( new ListInit( inits, noDesignators ) );768 769 // return variable pointing to temporary770 return new VariableExpr( arrayTemp );771 }772 773 747 void Pass1::passArgTypeVars( ApplicationExpr *appExpr, Type *parmType, Type *argBaseType, std::list< Expression *>::iterator &arg, const TyVarMap &exprTyVars, std::set< std::string > &seenTypes ) { 774 Type *poly Base = hasPolyBase( parmType, exprTyVars );775 if ( poly Base && ! dynamic_cast< TypeInstType* >( polyBase ) ) {776 std::string sizeName = sizeofName( polyBase );777 if ( seenTypes.count( sizeName ) ) return;748 Type *polyType = isPolyType( parmType, exprTyVars ); 749 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 750 std::string typeName = mangleType( polyType ); 751 if ( seenTypes.count( typeName ) ) return; 778 752 779 753 arg = appExpr->get_args().insert( arg, new SizeofExpr( argBaseType->clone() ) ); … … 781 755 arg = appExpr->get_args().insert( arg, new AlignofExpr( argBaseType->clone() ) ); 782 756 arg++; 783 if ( dynamic_cast< StructInstType* >( poly Base ) ) {757 if ( dynamic_cast< StructInstType* >( polyType ) ) { 784 758 if ( StructInstType *argBaseStructType = dynamic_cast< StructInstType* >( argBaseType ) ) { 785 arg = appExpr->get_args().insert( arg, makeOffsetArray( argBaseStructType ) ); 786 arg++; 759 // zero-length arrays are forbidden by C, so don't pass offset for empty struct 760 if ( ! argBaseStructType->get_baseStruct()->get_members().empty() ) { 761 arg = appExpr->get_args().insert( arg, new OffsetPackExpr( argBaseStructType->clone() ) ); 762 arg++; 763 } 787 764 } else { 788 765 throw SemanticError( "Cannot pass non-struct type for generic struct" ); … … 790 767 } 791 768 792 seenTypes.insert( sizeName );769 seenTypes.insert( typeName ); 793 770 } 794 771 } … … 826 803 passArgTypeVars( appExpr, polyRetType, concRetType, arg, exprTyVars, seenTypes ); 827 804 } 828 805 829 806 // add type information args for presently unseen types in parameter list 830 807 for ( ; fnParm != funcType->get_parameters().end() && fnArg != appExpr->get_args().end(); ++fnParm, ++fnArg ) { … … 905 882 assert( env ); 906 883 Type *concrete = replaceWithConcrete( appExpr, polyType ); 907 // add out-parameter for return value 884 // add out-parameter for return value 908 885 return addRetParam( appExpr, function, concrete, arg ); 909 886 } … … 932 909 return; 933 910 } else if ( arg->get_results().front()->get_isLvalue() ) { 934 // VariableExpr and MemberExpr are lvalues 935 arg = new AddressExpr( arg ); 911 // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue) 912 if ( CommaExpr *commaArg = dynamic_cast< CommaExpr* >( arg ) ) { 913 commaArg->set_arg2( new AddressExpr( commaArg->get_arg2() ) ); 914 } else { 915 arg = new AddressExpr( arg ); 916 } 936 917 } else { 937 918 // use type computed in unification to declare boxed variables … … 1028 1009 } // for 1029 1010 } 1030 1031 1032 1011 1033 1012 FunctionDecl *Pass1::makeAdapter( FunctionType *adaptee, FunctionType *realType, const std::string &mangleName, const TyVarMap &tyVars ) { … … 1146 1125 addAssign->get_args().push_back( appExpr->get_args().front() ); 1147 1126 } // if 1148 addAssign->get_args().push_back( new NameExpr( sizeofName( polyType) ) );1127 addAssign->get_args().push_back( new NameExpr( sizeofName( mangleType( polyType ) ) ) ); 1149 1128 addAssign->get_results().front() = appExpr->get_results().front()->clone(); 1150 1129 if ( appExpr->get_env() ) { … … 1173 1152 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1174 1153 multiply->get_args().push_back( appExpr->get_args().back() ); 1175 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1) ) );1154 multiply->get_args().push_back( new SizeofExpr( baseType1->clone() ) ); 1176 1155 ret->get_args().push_back( appExpr->get_args().front() ); 1177 1156 ret->get_args().push_back( multiply ); … … 1179 1158 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1180 1159 multiply->get_args().push_back( appExpr->get_args().front() ); 1181 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2) ) );1160 multiply->get_args().push_back( new SizeofExpr( baseType2->clone() ) ); 1182 1161 ret->get_args().push_back( multiply ); 1183 1162 ret->get_args().push_back( appExpr->get_args().back() ); … … 1242 1221 UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) ); 1243 1222 divide->get_args().push_back( appExpr ); 1244 divide->get_args().push_back( new NameExpr( sizeofName( baseType1) ) );1223 divide->get_args().push_back( new SizeofExpr( baseType1->clone() ) ); 1245 1224 divide->get_results().push_front( appExpr->get_results().front()->clone() ); 1246 1225 if ( appExpr->get_env() ) { … … 1252 1231 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1253 1232 multiply->get_args().push_back( appExpr->get_args().back() ); 1254 multiply->get_args().push_back( new NameExpr( sizeofName( baseType1) ) );1233 multiply->get_args().push_back( new SizeofExpr( baseType1->clone() ) ); 1255 1234 appExpr->get_args().back() = multiply; 1256 1235 } else if ( baseType2 ) { 1257 1236 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1258 1237 multiply->get_args().push_back( appExpr->get_args().front() ); 1259 multiply->get_args().push_back( new NameExpr( sizeofName( baseType2) ) );1238 multiply->get_args().push_back( new SizeofExpr( baseType2->clone() ) ); 1260 1239 appExpr->get_args().front() = multiply; 1261 1240 } // if … … 1267 1246 UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) ); 1268 1247 multiply->get_args().push_back( appExpr->get_args().back() ); 1269 multiply->get_args().push_back( new NameExpr( sizeofName( baseType) ) );1248 multiply->get_args().push_back( new SizeofExpr( baseType->clone() ) ); 1270 1249 appExpr->get_args().back() = multiply; 1271 1250 } // if … … 1304 1283 std::list< Expression *>::iterator paramBegin = appExpr->get_args().begin(); 1305 1284 1306 TyVarMap exprTyVars ;1285 TyVarMap exprTyVars( (TypeDecl::Kind)-1 ); 1307 1286 makeTyVarMap( function, exprTyVars ); 1308 1287 ReferenceToType *polyRetType = isPolyRet( function ); … … 1327 1306 1328 1307 boxParams( appExpr, function, arg, exprTyVars ); 1329 1330 1308 passAdapters( appExpr, function, exprTyVars ); 1331 1309 … … 1388 1366 return new VariableExpr( functionObj ); 1389 1367 } 1390 1368 1391 1369 Statement * Pass1::mutate( ReturnStmt *returnStmt ) { 1392 1370 if ( retval && returnStmt->get_expr() ) { … … 1407 1385 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( retval->get_type() ) ) { 1408 1386 // find assignment operator for type variable 1409 std::map< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() );1387 ScopedMap< std::string, DeclarationWithType *>::const_iterator assignIter = assignOps.find( typeInst->get_name() ); 1410 1388 if ( assignIter == assignOps.end() ) { 1411 1389 throw SemanticError( "Attempt to return dtype or ftype object in ", returnStmt->get_expr() ); … … 1429 1407 std::list< TypeDecl* >::const_iterator forallIt = forallParams.begin(); 1430 1408 for ( ; tyIt != tyParams.end() && forallIt != forallParams.end(); ++tyIt, ++forallIt ) { 1431 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; // skip types with no assign op (ftype/dtype) 1432 1433 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions(); 1434 assert( ! asserts.empty() && "Type param needs assignment operator assertion" ); 1435 DeclarationWithType *actualDecl = asserts.front(); 1436 TypeInstType *actualType = isTypeInstAssignment( actualDecl ); 1437 assert( actualType && "First assertion of type with assertions should be assignment operator" ); 1409 // Add appropriate mapping to assignment expression environment 1438 1410 TypeExpr *formalTypeExpr = dynamic_cast< TypeExpr* >( *tyIt ); 1439 1411 assert( formalTypeExpr && "type parameters must be type expressions" ); 1440 1412 Type *formalType = formalTypeExpr->get_type(); 1441 assignExpr->get_env()->add( actualType->get_name(), formalType ); 1442 1413 assignExpr->get_env()->add( (*forallIt)->get_name(), formalType ); 1414 1415 // skip types with no assign op (ftype/dtype) 1416 if ( (*forallIt)->get_kind() != TypeDecl::Any ) continue; 1417 1418 // find assignment operator for formal type 1443 1419 DeclarationWithType *assertAssign = 0; 1444 1420 if ( TypeInstType *formalTypeInstType = dynamic_cast< TypeInstType* >( formalType ) ) { 1445 std::map< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() );1421 ScopedMap< std::string, DeclarationWithType *>::const_iterator assertAssignIt = assignOps.find( formalTypeInstType->get_name() ); 1446 1422 if ( assertAssignIt == assignOps.end() ) { 1447 1423 throw SemanticError( "No assignment operation found for ", formalTypeInstType ); … … 1454 1430 } 1455 1431 } 1456 1457 1432 1433 // add inferred parameter for field assignment operator to assignment expression 1434 std::list< DeclarationWithType* > &asserts = (*forallIt)->get_assertions(); 1435 assert( ! asserts.empty() && "Type param needs assignment operator assertion" ); 1436 DeclarationWithType *actualDecl = asserts.front(); 1458 1437 assignExpr->get_inferParams()[ actualDecl->get_uniqueId() ] 1459 1438 = ParamEntry( assertAssign->get_uniqueId(), assertAssign->get_type()->clone(), actualDecl->get_type()->clone(), wrapFunctionDecl( assertAssign ) ); … … 1481 1460 1482 1461 Type * Pass1::mutate( PointerType *pointerType ) { 1483 TyVarMap oldtyVars = scopeTyVars;1462 scopeTyVars.beginScope(); 1484 1463 makeTyVarMap( pointerType, scopeTyVars ); 1485 1464 1486 1465 Type *ret = Mutator::mutate( pointerType ); 1487 1466 1488 scopeTyVars = oldtyVars;1467 scopeTyVars.endScope(); 1489 1468 return ret; 1490 1469 } 1491 1470 1492 1471 Type * Pass1::mutate( FunctionType *functionType ) { 1493 TyVarMap oldtyVars = scopeTyVars;1472 scopeTyVars.beginScope(); 1494 1473 makeTyVarMap( functionType, scopeTyVars ); 1495 1474 1496 1475 Type *ret = Mutator::mutate( functionType ); 1497 1476 1498 scopeTyVars = oldtyVars;1477 scopeTyVars.endScope(); 1499 1478 return ret; 1500 1479 } … … 1561 1540 1562 1541 Type * Pass2::mutate( PointerType *pointerType ) { 1563 TyVarMap oldtyVars = scopeTyVars;1542 scopeTyVars.beginScope(); 1564 1543 makeTyVarMap( pointerType, scopeTyVars ); 1565 1544 1566 1545 Type *ret = Mutator::mutate( pointerType ); 1567 1546 1568 scopeTyVars = oldtyVars;1547 scopeTyVars.endScope(); 1569 1548 return ret; 1570 1549 } 1571 1550 1572 1551 Type *Pass2::mutate( FunctionType *funcType ) { 1573 TyVarMap oldtyVars = scopeTyVars;1552 scopeTyVars.beginScope(); 1574 1553 makeTyVarMap( funcType, scopeTyVars ); 1575 1554 … … 1588 1567 ObjectDecl newPtr( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, 1589 1568 new PointerType( Type::Qualifiers(), new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) ), 0 ); 1590 // ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );1591 1569 for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) { 1592 1570 ObjectDecl *sizeParm, *alignParm; … … 1594 1572 if ( (*tyParm)->get_kind() == TypeDecl::Any ) { 1595 1573 TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm ); 1574 std::string parmName = mangleType( &parmType ); 1596 1575 1597 1576 sizeParm = newObj.clone(); 1598 sizeParm->set_name( sizeofName( &parmType ) );1577 sizeParm->set_name( sizeofName( parmName ) ); 1599 1578 last = funcType->get_parameters().insert( last, sizeParm ); 1600 1579 ++last; 1601 1580 1602 1581 alignParm = newObj.clone(); 1603 alignParm->set_name( alignofName( &parmType ) );1582 alignParm->set_name( alignofName( parmName ) ); 1604 1583 last = funcType->get_parameters().insert( last, alignParm ); 1605 1584 ++last; … … 1616 1595 std::set< std::string > seenTypes; // sizeofName for generic types we've seen 1617 1596 for ( std::list< DeclarationWithType* >::const_iterator fnParm = last; fnParm != funcType->get_parameters().end(); ++fnParm ) { 1618 Type *poly Base = hasPolyBase( (*fnParm)->get_type(), scopeTyVars );1619 if ( poly Base && ! dynamic_cast< TypeInstType* >( polyBase ) ) {1620 std::string sizeName = sizeofName( polyBase );1621 if ( seenTypes.count( sizeName ) ) continue;1597 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars ); 1598 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 1599 std::string typeName = mangleType( polyType ); 1600 if ( seenTypes.count( typeName ) ) continue; 1622 1601 1623 1602 ObjectDecl *sizeParm, *alignParm, *offsetParm; 1624 1603 sizeParm = newObj.clone(); 1625 sizeParm->set_name( size Name);1604 sizeParm->set_name( sizeofName( typeName ) ); 1626 1605 last = funcType->get_parameters().insert( last, sizeParm ); 1627 1606 ++last; 1628 1607 1629 1608 alignParm = newObj.clone(); 1630 alignParm->set_name( alignofName( polyBase ) );1609 alignParm->set_name( alignofName( typeName ) ); 1631 1610 last = funcType->get_parameters().insert( last, alignParm ); 1632 1611 ++last; 1633 1612 1634 if ( dynamic_cast< StructInstType* >( polyBase ) ) { 1635 offsetParm = newPtr.clone(); 1636 offsetParm->set_name( offsetofName( polyBase ) ); 1637 last = funcType->get_parameters().insert( last, offsetParm ); 1638 ++last; 1613 if ( StructInstType *polyBaseStruct = dynamic_cast< StructInstType* >( polyType ) ) { 1614 // NOTE zero-length arrays are illegal in C, so empty structs have no offset array 1615 if ( ! polyBaseStruct->get_baseStruct()->get_members().empty() ) { 1616 offsetParm = newPtr.clone(); 1617 offsetParm->set_name( offsetofName( typeName ) ); 1618 last = funcType->get_parameters().insert( last, offsetParm ); 1619 ++last; 1620 } 1639 1621 } 1640 1622 1641 seenTypes.insert( sizeName );1623 seenTypes.insert( typeName ); 1642 1624 } 1643 1625 } … … 1649 1631 mutateAll( funcType->get_parameters(), *this ); 1650 1632 1651 scopeTyVars = oldtyVars;1633 scopeTyVars.endScope(); 1652 1634 return funcType; 1653 1635 } … … 1842 1824 } 1843 1825 1844 ////////////////////////////////////////// MemberExprFixer //////////////////////////////////////////////////// 1826 ////////////////////////////////////////// PolyGenericCalculator //////////////////////////////////////////////////// 1827 1828 void PolyGenericCalculator::beginTypeScope( Type *ty ) { 1829 scopeTyVars.beginScope(); 1830 makeTyVarMap( ty, scopeTyVars ); 1831 } 1832 1833 void PolyGenericCalculator::endTypeScope() { 1834 scopeTyVars.endScope(); 1835 } 1845 1836 1846 1837 template< typename DeclClass > 1847 DeclClass * MemberExprFixer::handleDecl( DeclClass *decl, Type *type ) { 1848 TyVarMap oldtyVars = scopeTyVars; 1849 makeTyVarMap( type, scopeTyVars ); 1838 DeclClass * PolyGenericCalculator::handleDecl( DeclClass *decl, Type *type ) { 1839 beginTypeScope( type ); 1840 knownLayouts.beginScope(); 1841 knownOffsets.beginScope(); 1850 1842 1851 1843 DeclClass *ret = static_cast< DeclClass *>( Mutator::mutate( decl ) ); 1852 1844 1853 scopeTyVars = oldtyVars; 1845 knownOffsets.endScope(); 1846 knownLayouts.endScope(); 1847 endTypeScope(); 1854 1848 return ret; 1855 1849 } 1856 1850 1857 ObjectDecl * MemberExprFixer::mutate( ObjectDecl *objectDecl ) {1851 ObjectDecl * PolyGenericCalculator::mutate( ObjectDecl *objectDecl ) { 1858 1852 return handleDecl( objectDecl, objectDecl->get_type() ); 1859 1853 } 1860 1854 1861 DeclarationWithType * MemberExprFixer::mutate( FunctionDecl *functionDecl ) {1855 DeclarationWithType * PolyGenericCalculator::mutate( FunctionDecl *functionDecl ) { 1862 1856 return handleDecl( functionDecl, functionDecl->get_functionType() ); 1863 1857 } 1864 1858 1865 TypedefDecl * MemberExprFixer::mutate( TypedefDecl *typedefDecl ) {1859 TypedefDecl * PolyGenericCalculator::mutate( TypedefDecl *typedefDecl ) { 1866 1860 return handleDecl( typedefDecl, typedefDecl->get_base() ); 1867 1861 } 1868 1862 1869 TypeDecl * MemberExprFixer::mutate( TypeDecl *typeDecl ) {1863 TypeDecl * PolyGenericCalculator::mutate( TypeDecl *typeDecl ) { 1870 1864 scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind(); 1871 1865 return Mutator::mutate( typeDecl ); 1872 1866 } 1873 1867 1874 Type * MemberExprFixer::mutate( PointerType *pointerType ) { 1875 TyVarMap oldtyVars = scopeTyVars; 1876 makeTyVarMap( pointerType, scopeTyVars ); 1868 Type * PolyGenericCalculator::mutate( PointerType *pointerType ) { 1869 beginTypeScope( pointerType ); 1877 1870 1878 1871 Type *ret = Mutator::mutate( pointerType ); 1879 1872 1880 scopeTyVars = oldtyVars;1873 endTypeScope(); 1881 1874 return ret; 1882 1875 } 1883 1876 1884 Type * MemberExprFixer::mutate( FunctionType *functionType ) { 1885 TyVarMap oldtyVars = scopeTyVars; 1886 makeTyVarMap( functionType, scopeTyVars ); 1887 1888 Type *ret = Mutator::mutate( functionType ); 1889 1890 scopeTyVars = oldtyVars; 1877 Type * PolyGenericCalculator::mutate( FunctionType *funcType ) { 1878 beginTypeScope( funcType ); 1879 1880 // make sure that any type information passed into the function is accounted for 1881 for ( std::list< DeclarationWithType* >::const_iterator fnParm = funcType->get_parameters().begin(); fnParm != funcType->get_parameters().end(); ++fnParm ) { 1882 // condition here duplicates that in Pass2::mutate( FunctionType* ) 1883 Type *polyType = isPolyType( (*fnParm)->get_type(), scopeTyVars ); 1884 if ( polyType && ! dynamic_cast< TypeInstType* >( polyType ) ) { 1885 knownLayouts.insert( mangleType( polyType ) ); 1886 } 1887 } 1888 1889 Type *ret = Mutator::mutate( funcType ); 1890 1891 endTypeScope(); 1891 1892 return ret; 1892 1893 } 1893 1894 1894 Statement * MemberExprFixer::mutate( DeclStmt *declStmt ) {1895 Statement *PolyGenericCalculator::mutate( DeclStmt *declStmt ) { 1895 1896 if ( ObjectDecl *objectDecl = dynamic_cast< ObjectDecl *>( declStmt->get_decl() ) ) { 1896 if ( isPolyType( objectDecl->get_type(), scopeTyVars) ) {1897 if ( findGeneric( objectDecl->get_type() ) ) { 1897 1898 // change initialization of a polymorphic value object 1898 1899 // to allocate storage with alloca 1899 1900 Type *declType = objectDecl->get_type(); 1900 1901 UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) ); 1901 alloc->get_args().push_back( new NameExpr( sizeofName( declType) ) );1902 alloc->get_args().push_back( new NameExpr( sizeofName( mangleType( declType ) ) ) ); 1902 1903 1903 1904 delete objectDecl->get_init(); … … 1931 1932 ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) ); 1932 1933 UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) ); 1933 fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType) ) );1934 fieldOffset->get_args().push_back( new NameExpr( offsetofName( mangleType( objectType ) ) ) ); 1934 1935 fieldOffset->get_args().push_back( fieldIndex ); 1935 1936 return fieldOffset; … … 1946 1947 } 1947 1948 1948 Expression * MemberExprFixer::mutate( MemberExpr *memberExpr ) {1949 Expression *PolyGenericCalculator::mutate( MemberExpr *memberExpr ) { 1949 1950 // mutate, exiting early if no longer MemberExpr 1950 1951 Expression *expr = Mutator::mutate( memberExpr ); … … 1963 1964 Type *objectType = hasPolyBase( objectDecl->get_type(), scopeTyVars, &tyDepth ); 1964 1965 if ( ! objectType ) return memberExpr; 1966 findGeneric( objectType ); // ensure layout for this type is available 1965 1967 1966 1968 Expression *newMemberExpr = 0; … … 1994 1996 } 1995 1997 1996 Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) { 1998 ObjectDecl *PolyGenericCalculator::makeVar( const std::string &name, Type *type, Initializer *init ) { 1999 ObjectDecl *newObj = new ObjectDecl( name, DeclarationNode::NoStorageClass, LinkageSpec::C, 0, type, init ); 2000 stmtsToAdd.push_back( new DeclStmt( noLabels, newObj ) ); 2001 return newObj; 2002 } 2003 2004 void PolyGenericCalculator::addOtypeParamsToLayoutCall( UntypedExpr *layoutCall, const std::list< Type* > &otypeParams ) { 2005 for ( std::list< Type* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) { 2006 if ( findGeneric( *param ) ) { 2007 // push size/align vars for a generic parameter back 2008 std::string paramName = mangleType( *param ); 2009 layoutCall->get_args().push_back( new NameExpr( sizeofName( paramName ) ) ); 2010 layoutCall->get_args().push_back( new NameExpr( alignofName( paramName ) ) ); 2011 } else { 2012 layoutCall->get_args().push_back( new SizeofExpr( (*param)->clone() ) ); 2013 layoutCall->get_args().push_back( new AlignofExpr( (*param)->clone() ) ); 2014 } 2015 } 2016 } 2017 2018 /// returns true if any of the otype parameters have a dynamic layout and puts all otype parameters in the output list 2019 bool findGenericParams( std::list< TypeDecl* > &baseParams, std::list< Expression* > &typeParams, std::list< Type* > &out ) { 2020 bool hasDynamicLayout = false; 2021 2022 std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin(); 2023 std::list< Expression* >::const_iterator typeParam = typeParams.begin(); 2024 for ( ; baseParam != baseParams.end() && typeParam != typeParams.end(); ++baseParam, ++typeParam ) { 2025 // skip non-otype parameters 2026 if ( (*baseParam)->get_kind() != TypeDecl::Any ) continue; 2027 TypeExpr *typeExpr = dynamic_cast< TypeExpr* >( *typeParam ); 2028 assert( typeExpr && "all otype parameters should be type expressions" ); 2029 2030 Type *type = typeExpr->get_type(); 2031 out.push_back( type ); 2032 if ( isPolyType( type ) ) hasDynamicLayout = true; 2033 } 2034 assert( baseParam == baseParams.end() && typeParam == typeParams.end() ); 2035 2036 return hasDynamicLayout; 2037 } 2038 2039 bool PolyGenericCalculator::findGeneric( Type *ty ) { 2040 if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( ty ) ) { 2041 // duplicate logic from isPolyType() 2042 if ( env ) { 2043 if ( Type *newType = env->lookup( typeInst->get_name() ) ) { 2044 return findGeneric( newType ); 2045 } // if 2046 } // if 2047 if ( scopeTyVars.find( typeInst->get_name() ) != scopeTyVars.end() ) { 2048 // NOTE assumes here that getting put in the scopeTyVars included having the layout variables set 2049 return true; 2050 } 2051 return false; 2052 } else if ( StructInstType *structTy = dynamic_cast< StructInstType* >( ty ) ) { 2053 // check if this type already has a layout generated for it 2054 std::string typeName = mangleType( ty ); 2055 if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true; 2056 2057 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 2058 std::list< Type* > otypeParams; 2059 if ( ! findGenericParams( *structTy->get_baseParameters(), structTy->get_parameters(), otypeParams ) ) return false; 2060 2061 // insert local variables for layout and generate call to layout function 2062 knownLayouts.insert( typeName ); // done early so as not to interfere with the later addition of parameters to the layout call 2063 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 2064 2065 int n_members = structTy->get_baseStruct()->get_members().size(); 2066 if ( n_members == 0 ) { 2067 // 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 ) ) ) ); 2070 // NOTE zero-length arrays are forbidden in C, so empty structs have no offsetof array 2071 } else { 2072 ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType ); 2073 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 ) ); 2075 2076 // generate call to layout function 2077 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( layoutofName( structTy->get_baseStruct() ) ) ); 2078 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) ); 2079 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) ); 2080 layoutCall->get_args().push_back( new VariableExpr( offsetVar ) ); 2081 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 2082 2083 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) ); 2084 } 2085 2086 return true; 2087 } else if ( UnionInstType *unionTy = dynamic_cast< UnionInstType* >( ty ) ) { 2088 // check if this type already has a layout generated for it 2089 std::string typeName = mangleType( ty ); 2090 if ( knownLayouts.find( typeName ) != knownLayouts.end() ) return true; 2091 2092 // check if any of the type parameters have dynamic layout; if none do, this type is (or will be) monomorphized 2093 std::list< Type* > otypeParams; 2094 if ( ! findGenericParams( *unionTy->get_baseParameters(), unionTy->get_parameters(), otypeParams ) ) return false; 2095 2096 // insert local variables for layout and generate call to layout function 2097 knownLayouts.insert( typeName ); // done early so as not to interfere with the later addition of parameters to the layout call 2098 Type *layoutType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 2099 2100 ObjectDecl *sizeVar = makeVar( sizeofName( typeName ), layoutType ); 2101 ObjectDecl *alignVar = makeVar( alignofName( typeName ), layoutType->clone() ); 2102 2103 // generate call to layout function 2104 UntypedExpr *layoutCall = new UntypedExpr( new NameExpr( layoutofName( unionTy->get_baseUnion() ) ) ); 2105 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( sizeVar ) ) ); 2106 layoutCall->get_args().push_back( new AddressExpr( new VariableExpr( alignVar ) ) ); 2107 addOtypeParamsToLayoutCall( layoutCall, otypeParams ); 2108 2109 stmtsToAdd.push_back( new ExprStmt( noLabels, layoutCall ) ); 2110 2111 return true; 2112 } 2113 2114 return false; 2115 } 2116 2117 Expression *PolyGenericCalculator::mutate( SizeofExpr *sizeofExpr ) { 2118 Type *ty = sizeofExpr->get_type(); 2119 if ( findGeneric( ty ) ) { 2120 Expression *ret = new NameExpr( sizeofName( mangleType( ty ) ) ); 2121 delete sizeofExpr; 2122 return ret; 2123 } 2124 return sizeofExpr; 2125 } 2126 2127 Expression *PolyGenericCalculator::mutate( AlignofExpr *alignofExpr ) { 2128 Type *ty = alignofExpr->get_type(); 2129 if ( findGeneric( ty ) ) { 2130 Expression *ret = new NameExpr( alignofName( mangleType( ty ) ) ); 2131 delete alignofExpr; 2132 return ret; 2133 } 2134 return alignofExpr; 2135 } 2136 2137 Expression *PolyGenericCalculator::mutate( OffsetofExpr *offsetofExpr ) { 1997 2138 // mutate, exiting early if no longer OffsetofExpr 1998 2139 Expression *expr = Mutator::mutate( offsetofExpr ); … … 2001 2142 2002 2143 // only mutate expressions for polymorphic structs/unions 2003 Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars);2004 if ( ! ty) return offsetofExpr;2144 Type *ty = offsetofExpr->get_type(); 2145 if ( ! findGeneric( ty ) ) return offsetofExpr; 2005 2146 2006 2147 if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) { … … 2019 2160 } 2020 2161 2162 Expression *PolyGenericCalculator::mutate( OffsetPackExpr *offsetPackExpr ) { 2163 StructInstType *ty = offsetPackExpr->get_type(); 2164 2165 Expression *ret = 0; 2166 if ( findGeneric( ty ) ) { 2167 // pull offset back from generated type information 2168 ret = new NameExpr( offsetofName( mangleType( ty ) ) ); 2169 } else { 2170 std::string offsetName = offsetofName( mangleType( ty ) ); 2171 if ( knownOffsets.find( offsetName ) != knownOffsets.end() ) { 2172 // use the already-generated offsets for this type 2173 ret = new NameExpr( offsetName ); 2174 } else { 2175 knownOffsets.insert( offsetName ); 2176 2177 std::list< Declaration* > &baseMembers = ty->get_baseStruct()->get_members(); 2178 Type *offsetType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ); 2179 2180 // build initializer list for offset array 2181 std::list< Initializer* > inits; 2182 for ( std::list< Declaration* >::const_iterator member = baseMembers.begin(); member != baseMembers.end(); ++member ) { 2183 DeclarationWithType *memberDecl; 2184 if ( DeclarationWithType *origMember = dynamic_cast< DeclarationWithType* >( *member ) ) { 2185 memberDecl = origMember->clone(); 2186 } else { 2187 memberDecl = new ObjectDecl( (*member)->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, offsetType->clone(), 0 ); 2188 } 2189 inits.push_back( new SingleInit( new OffsetofExpr( ty->clone(), memberDecl ) ) ); 2190 } 2191 2192 // 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 ), 2194 new ListInit( inits ) ); 2195 ret = new VariableExpr( offsetArray ); 2196 } 2197 } 2198 2199 delete offsetPackExpr; 2200 return ret; 2201 } 2202 2203 void PolyGenericCalculator::doBeginScope() { 2204 knownLayouts.beginScope(); 2205 knownOffsets.beginScope(); 2206 } 2207 2208 void PolyGenericCalculator::doEndScope() { 2209 knownLayouts.endScope(); 2210 knownOffsets.endScope(); 2211 } 2212 2021 2213 ////////////////////////////////////////// Pass3 //////////////////////////////////////////////////// 2022 2214 2023 2215 template< typename DeclClass > 2024 2216 DeclClass * Pass3::handleDecl( DeclClass *decl, Type *type ) { 2025 TyVarMap oldtyVars = scopeTyVars;2217 scopeTyVars.beginScope(); 2026 2218 makeTyVarMap( type, scopeTyVars ); 2027 2219 … … 2029 2221 ScrubTyVars::scrub( decl, scopeTyVars ); 2030 2222 2031 scopeTyVars = oldtyVars;2223 scopeTyVars.endScope(); 2032 2224 return ret; 2033 2225 } … … 2059 2251 2060 2252 Type * Pass3::mutate( PointerType *pointerType ) { 2061 TyVarMap oldtyVars = scopeTyVars;2253 scopeTyVars.beginScope(); 2062 2254 makeTyVarMap( pointerType, scopeTyVars ); 2063 2255 2064 2256 Type *ret = Mutator::mutate( pointerType ); 2065 2257 2066 scopeTyVars = oldtyVars;2258 scopeTyVars.endScope(); 2067 2259 return ret; 2068 2260 } 2069 2261 2070 2262 Type * Pass3::mutate( FunctionType *functionType ) { 2071 TyVarMap oldtyVars = scopeTyVars;2263 scopeTyVars.beginScope(); 2072 2264 makeTyVarMap( functionType, scopeTyVars ); 2073 2265 2074 2266 Type *ret = Mutator::mutate( functionType ); 2075 2267 2076 scopeTyVars = oldtyVars;2268 scopeTyVars.endScope(); 2077 2269 return ret; 2078 2270 } -
src/GenPoly/FindFunction.cc
rdb4ecc5 r70a06f6 55 55 TyVarMap::iterator var = tyVars.find( (*i)->get_name() ); 56 56 if ( var != tyVars.end() ) { 57 tyVars.erase( var );57 tyVars.erase( var->first ); 58 58 } // if 59 59 } // for … … 61 61 62 62 Type * FindFunction::mutate( FunctionType *functionType ) { 63 TyVarMap oldTyVars = tyVars;63 tyVars.beginScope(); 64 64 handleForall( functionType->get_forall() ); 65 65 mutateAll( functionType->get_returnVals(), *this ); … … 72 72 } // if 73 73 } // if 74 tyVars = oldTyVars;74 tyVars.endScope(); 75 75 return ret; 76 76 } 77 77 78 78 Type * FindFunction::mutate( PointerType *pointerType ) { 79 TyVarMap oldTyVars = tyVars;79 tyVars.beginScope(); 80 80 handleForall( pointerType->get_forall() ); 81 81 Type *ret = Mutator::mutate( pointerType ); 82 tyVars = oldTyVars;82 tyVars.endScope(); 83 83 return ret; 84 84 } -
src/GenPoly/GenPoly.cc
rdb4ecc5 r70a06f6 16 16 #include "GenPoly.h" 17 17 18 #include "SymTab/Mangler.h"19 18 #include "SynTree/Expression.h" 20 19 #include "SynTree/Type.h" … … 38 37 ReferenceToType *isPolyRet( FunctionType *function ) { 39 38 if ( ! function->get_returnVals().empty() ) { 40 TyVarMap forallTypes ;39 TyVarMap forallTypes( (TypeDecl::Kind)-1 ); 41 40 makeTyVarMap( function, forallTypes ); 42 41 return (ReferenceToType*)isPolyType( function->get_returnVals().front()->get_type(), forallTypes ); … … 218 217 } 219 218 220 std::string sizeofName( Type *ty ) {221 return std::string( "_sizeof_" ) + SymTab::Mangler::mangleType( ty );222 }223 224 std::string alignofName( Type *ty ) {225 return std::string( "_alignof_" ) + SymTab::Mangler::mangleType( ty );226 }227 228 std::string offsetofName( Type* ty ) {229 return std::string( "_offsetof_" ) + SymTab::Mangler::mangleType( ty );230 }231 232 219 } // namespace GenPoly 233 220 -
src/GenPoly/GenPoly.h
rdb4ecc5 r70a06f6 17 17 #define GENPOLY_H 18 18 19 #include <map>20 19 #include <string> 21 20 #include <iostream> 22 21 #include <utility> 22 23 #include "ErasableScopedMap.h" 24 25 #include "SymTab/Mangler.h" 23 26 24 27 #include "SynTree/Declaration.h" … … 27 30 28 31 namespace GenPoly { 29 typedef std::map< std::string, TypeDecl::Kind > TyVarMap;32 typedef ErasableScopedMap< std::string, TypeDecl::Kind > TyVarMap; 30 33 31 34 /// A function needs an adapter if it returns a polymorphic value or if any of its … … 69 72 void printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap ); 70 73 71 /// Gets the name of the sizeof parameter for the type 72 std::string sizeofName( Type *ty ); 74 /// Gets the mangled name of this type; alias for SymTab::Mangler::mangleType(). 75 inline std::string mangleType( Type *ty ) { return SymTab::Mangler::mangleType( ty ); } 76 77 /// Gets the name of the sizeof parameter for the type, given its mangled name 78 inline std::string sizeofName( const std::string &name ) { return std::string( "_sizeof_" ) + name; } 73 79 74 /// Gets the name of the alignof parameter for the type 75 std::string alignofName( Type *ty );80 /// Gets the name of the alignof parameter for the type, given its mangled name 81 inline std::string alignofName( const std::string &name ) { return std::string( "_alignof_" ) + name; } 76 82 77 /// Gets the name of the offsetof parameter for the type 78 std::string offsetofName( Type *ty ); 83 /// Gets the name of the offsetof parameter for the type, given its mangled name 84 inline std::string offsetofName( const std::string &name ) { return std::string( "_offsetof_" ) + name; } 85 86 /// Gets the name of the layout function for a given aggregate type, given its declaration 87 inline std::string layoutofName( AggregateDecl *decl ) { return std::string( "_layoutof_" ) + decl->get_name(); } 88 79 89 } // namespace GenPoly 80 90 -
src/GenPoly/Lvalue.cc
rdb4ecc5 r70a06f6 17 17 18 18 #include "Lvalue.h" 19 20 #include "GenPoly.h" 19 21 20 22 #include "SynTree/Declaration.h" … … 63 65 64 66 namespace { 65 bool isLvalueRet( FunctionType *function ) { 66 if ( ! function->get_returnVals().empty() ) { 67 return function->get_returnVals().front()->get_type()->get_isLvalue(); 68 } else { 69 return false; 70 } // if 67 Type* isLvalueRet( FunctionType *function ) { 68 if ( function->get_returnVals().empty() ) return 0; 69 Type *ty = function->get_returnVals().front()->get_type(); 70 return ty->get_isLvalue() ? ty : 0; 71 71 } 72 72 … … 107 107 assert( function ); 108 108 109 std::string typeName; 110 if ( isLvalueRet( function ) && ! isIntrinsicApp( appExpr ) ) { 109 Type *funType = isLvalueRet( function ); 110 if ( funType && ! isIntrinsicApp( appExpr ) ) { 111 Expression *expr = appExpr; 112 Type *appType = appExpr->get_results().front(); 113 if ( isPolyType( funType ) && ! isPolyType( appType ) ) { 114 // make sure cast for polymorphic type is inside dereference 115 expr = new CastExpr( appExpr, new PointerType( Type::Qualifiers(), appType->clone() ) ); 116 } 111 117 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); 112 deref->get_results().push_back( app Expr->get_results().front() );113 appExpr->get_results().front() = new PointerType( Type::Qualifiers(), deref->get_results().front()->clone());114 deref->get_args().push_back( appExpr );118 deref->get_results().push_back( appType->clone() ); 119 appExpr->get_results().front() = new PointerType( Type::Qualifiers(), appType ); 120 deref->get_args().push_back( expr ); 115 121 return deref; 116 122 } else { -
src/GenPoly/PolyMutator.cc
rdb4ecc5 r70a06f6 27 27 } 28 28 29 PolyMutator::PolyMutator() : env( 0 ) { 30 } 29 PolyMutator::PolyMutator() : scopeTyVars( (TypeDecl::Kind)-1 ), env( 0 ) {} 31 30 32 31 void PolyMutator::mutateStatementList( std::list< Statement* > &statements ) { -
src/GenPoly/ScopedMap.h
rdb4ecc5 r70a06f6 17 17 #define _SCOPEDMAP_H 18 18 19 #include <cassert> 19 20 #include <iterator> 20 21 #include <map> … … 50 51 typedef typename scope_list::size_type size_type; 51 52 53 /// Checks if this iterator points to a valid item 54 bool is_valid() const { 55 return it != (*scopes)[i].end(); 56 } 57 58 /// Increments on invalid 59 iterator& next_valid() { 60 if ( ! is_valid() ) { ++(*this); } 61 return *this; 62 } 63 64 /// Decrements on invalid 65 iterator& prev_valid() { 66 if ( ! is_valid() ) { --(*this); } 67 return *this; 68 } 69 52 70 iterator(scope_list const &_scopes, const wrapped_iterator &_it, size_type _i) 53 71 : scopes(&_scopes), it(_it), i(_i) {} … … 67 85 --i; 68 86 it = (*scopes)[i].begin(); 69 return *this;70 }71 ++it;72 return *this;87 } else { 88 ++it; 89 } 90 return next_valid(); 73 91 } 74 92 iterator& operator++ (int) { iterator tmp = *this; ++(*this); return tmp; } … … 81 99 } 82 100 --it; 83 return *this;101 return prev_valid(); 84 102 } 85 103 iterator& operator-- (int) { iterator tmp = *this; --(*this); return tmp; } … … 104 122 typedef typename scope_list::size_type size_type; 105 123 124 /// Checks if this iterator points to a valid item 125 bool is_valid() const { 126 return it != (*scopes)[i].end(); 127 } 128 129 /// Increments on invalid 130 const_iterator& next_valid() { 131 if ( ! is_valid() ) { ++(*this); } 132 return *this; 133 } 134 135 /// Decrements on invalid 136 const_iterator& prev_valid() { 137 if ( ! is_valid() ) { --(*this); } 138 return *this; 139 } 140 106 141 const_iterator(scope_list const &_scopes, const wrapped_const_iterator &_it, size_type _i) 107 142 : scopes(&_scopes), it(_it), i(_i) {} … … 126 161 --i; 127 162 it = (*scopes)[i].begin(); 128 return *this;129 }130 ++it;131 return *this;163 } else { 164 ++it; 165 } 166 return next_valid(); 132 167 } 133 168 const_iterator& operator++ (int) { const_iterator tmp = *this; ++(*this); return tmp; } … … 140 175 } 141 176 --it; 142 return *this;177 return prev_valid(); 143 178 } 144 179 const_iterator& operator-- (int) { const_iterator tmp = *this; --(*this); return tmp; } … … 164 199 void endScope() { 165 200 scopes.pop_back(); 201 assert( ! scopes.empty() ); 166 202 } 167 203 … … 169 205 ScopedMap() { beginScope(); } 170 206 171 iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1) ; }172 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1) ; }173 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1) ; }207 iterator begin() { return iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 208 const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 209 const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), scopes.size()-1).next_valid(); } 174 210 iterator end() { return iterator(scopes, scopes[0].end(), 0); } 175 211 const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); } … … 188 224 return end(); 189 225 } 190 const_iterator find( const Key &key ) const { return const_iterator( find( key ) ); } 226 const_iterator find( const Key &key ) const { 227 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->find( key ) ); 228 } 191 229 192 230 /// Finds the given key in the outermost scope inside the given scope where it occurs … … 200 238 return end(); 201 239 } 202 const_iterator findNext( const_iterator &it, const Key &key ) const { return const_iterator( findNext( it, key ) ); } 240 const_iterator findNext( const_iterator &it, const Key &key ) const { 241 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->findNext( it, key ) ); 242 } 203 243 204 244 /// Inserts the given key-value pair into the outermost scope … … 208 248 } 209 249 std::pair< iterator, bool > insert( const Key &key, const Value &value ) { return insert( std::make_pair( key, value ) ); } 210 250 251 Value& operator[] ( const Key &key ) { 252 iterator slot = find( key ); 253 if ( slot != end() ) return slot->second; 254 return insert( key, Value() ).first->second; 255 } 211 256 }; 212 257 } // namespace GenPoly -
src/GenPoly/ScrubTyVars.cc
rdb4ecc5 r70a06f6 64 64 // sizeof( T ) => _sizeof_T parameter, which is the size of T 65 65 if ( Type *polyType = isPolyType( szeof->get_type() ) ) { 66 Expression *expr = new NameExpr( sizeofName( polyType) );66 Expression *expr = new NameExpr( sizeofName( mangleType( polyType ) ) ); 67 67 return expr; 68 68 } else { … … 74 74 // alignof( T ) => _alignof_T parameter, which is the alignment of T 75 75 if ( Type *polyType = isPolyType( algnof->get_type() ) ) { 76 Expression *expr = new NameExpr( alignofName( polyType) );76 Expression *expr = new NameExpr( alignofName( mangleType( polyType ) ) ); 77 77 return expr; 78 78 } else { -
src/InitTweak/InitModel.h
rdb4ecc5 r70a06f6 75 75 void visit( UntypedOffsetofExpr * ) { throw 0; } 76 76 void visit( OffsetofExpr * ) { throw 0; } 77 void visit( OffsetPackExpr * ) { throw 0; } 77 78 void visit( AttrExpr * ) { throw 0; } 78 79 void visit( LogicalExpr * ) { throw 0; } -
src/Parser/DeclarationNode.cc
rdb4ecc5 r70a06f6 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon Apr 04 17:09:46201613 // Update Count : 1 4212 // Last Modified On : Thu Apr 14 15:38:09 2016 13 // Update Count : 161 14 14 // 15 15 … … 190 190 newnode->type->aggregate->name = assign_strptr( name ); 191 191 if ( newnode->type->aggregate->name == "" ) { // anonymous aggregate ? 192 newnode->type->aggregate->name = DeclarationNode::anonymous.newName(); 193 } else if ( ! typedefTable.exists( newnode->type->aggregate->name ) ) { 194 // SKULLDUGGERY: Generate a typedef for the aggregate name so the aggregate does not have to be qualified by 195 // "struct". Only generate the typedef, if the name is not in use. The typedef is implicitly (silently) removed 196 // if the name is explicitly used. 197 typedefTable.addToEnclosingScope( newnode->type->aggregate->name, TypedefTable::TD ); 198 DeclarationNode *typedf = new DeclarationNode; 199 typedf->name = newnode->type->aggregate->name; 200 newnode->appendList( typedf->addType( newnode->clone() )->addTypedef() ); 192 newnode->type->aggregate->name = anonymous.newName(); 201 193 } // if 202 194 newnode->type->aggregate->actuals = actuals; … … 212 204 if ( newnode->type->enumeration->name == "" ) { // anonymous enumeration ? 213 205 newnode->type->enumeration->name = DeclarationNode::anonymous.newName(); 214 } else if ( ! typedefTable.exists( newnode->type->enumeration->name ) ) {215 // SKULLDUGGERY: Generate a typedef for the enumeration name so the enumeration does not have to be qualified by216 // "enum". Only generate the typedef, if the name is not in use. The typedef is implicitly (silently) removed if217 // the name is explicitly used.218 typedefTable.addToEnclosingScope( newnode->type->enumeration->name, TypedefTable::TD );219 DeclarationNode *typedf = new DeclarationNode;220 typedf->name = newnode->type->enumeration->name;221 newnode->appendList( typedf->addType( newnode->clone() )->addTypedef() );222 206 } // if 223 207 newnode->type->enumeration->constants = constants; -
src/Parser/ExpressionNode.cc
rdb4ecc5 r70a06f6 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sun Mar 13 12:34:38201613 // Update Count : 2 7212 // Last Modified On : Fri Apr 8 15:43:05 2016 13 // Update Count : 296 14 14 // 15 15 … … 22 22 23 23 #include "ParseNode.h" 24 #include "TypeData.h" 24 25 #include "SynTree/Constant.h" 25 26 #include "SynTree/Expression.h" 27 #include "SynTree/Declaration.h" 26 28 #include "Common/UnimplementedError.h" 27 29 #include "parseutility.h" … … 872 874 } 873 875 876 877 CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {} 878 CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {} 879 880 CompoundLiteralNode::~CompoundLiteralNode() { 881 delete kids; 882 delete type; 883 } 884 885 CompoundLiteralNode *CompoundLiteralNode::clone() const { 886 return new CompoundLiteralNode( *this ); 887 } 888 889 void CompoundLiteralNode::print( std::ostream &os, int indent ) const { 890 os << string( indent,' ' ) << "CompoundLiteralNode:" << endl; 891 892 os << string( indent + 2, ' ' ) << "type:" << endl; 893 if ( type != 0 ) 894 type->print( os, indent + 4 ); 895 896 os << string( indent + 2, ' ' ) << "initialization:" << endl; 897 if ( kids != 0 ) 898 kids->printList( os, indent + 4 ); 899 } 900 901 void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const { 902 os << "( "; 903 if ( type ) type->print( os ); 904 os << ", "; 905 if ( kids ) kids->printOneLine( os ); 906 os << ") "; 907 } 908 909 Expression *CompoundLiteralNode::build() const { 910 Declaration * newDecl = type->build(); // compound literal type 911 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type 912 return new CompoundLiteralExpr( newDeclWithType->get_type(), kids->build() ); 913 // these types do not have associated type information 914 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) { 915 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), kids->build() ); 916 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) { 917 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), kids->build() ); 918 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) { 919 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), kids->build() ); 920 } else { 921 assert( false ); 922 } // if 923 } 924 925 874 926 ExpressionNode *flattenCommas( ExpressionNode *list ) { 875 927 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) { -
src/Parser/ParseNode.h
rdb4ecc5 r70a06f6 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Rob Schluntz 12 // Last Modified On : Mon Apr 04 17:10:10201613 // Update Count : 19012 // Last Modified On : Thu Apr 14 15:37:52 2016 13 // Update Count : 205 14 14 // 15 15 … … 543 543 }; 544 544 545 class CompoundLiteralNode : public ExpressionNode { 546 public: 547 CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ); 548 CompoundLiteralNode( const CompoundLiteralNode &type ); 549 ~CompoundLiteralNode(); 550 551 virtual CompoundLiteralNode *clone() const; 552 553 DeclarationNode *get_type() const { return type; } 554 CompoundLiteralNode *set_type( DeclarationNode *t ) { type = t; return this; } 555 556 InitializerNode *get_initializer() const { return kids; } 557 CompoundLiteralNode *set_initializer( InitializerNode *k ) { kids = k; return this; } 558 559 void print( std::ostream &, int indent = 0 ) const; 560 void printOneLine( std::ostream &, int indent = 0 ) const; 561 562 virtual Expression *build() const; 563 private: 564 DeclarationNode *type; 565 InitializerNode *kids; 566 }; 567 545 568 template< typename SynTreeType, typename NodeType > 546 569 void buildList( const NodeType *firstNode, std::list< SynTreeType *> &outputList ) { -
src/Parser/TypedefTable.cc
rdb4ecc5 r70a06f6 10 10 // Created On : Sat May 16 15:20:13 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 21 18:18:58201613 // Update Count : 2 312 // Last Modified On : Wed Apr 13 16:57:30 2016 13 // Update Count : 24 14 14 // 15 15 … … 33 33 } 34 34 35 int TypedefTable::isKind( const string &identifier ) const { 36 tableType::const_iterator id_pos = table.find( identifier ); 37 // Name lookup defaults to identifier, and then the identifier's kind is set by the parser. 38 if ( id_pos == table.end() ) return IDENTIFIER; 39 return id_pos->second.begin()->kind; 40 } 41 35 42 void TypedefTable::changeKind( const string &identifier, kind_t kind ) { 36 43 tableType::iterator id_pos = table.find( identifier ); … … 39 46 } 40 47 41 int TypedefTable::isKind( const string &identifier ) const { 42 tableType::const_iterator id_pos = table.find( identifier ); 43 // Name lookup defaults to identifier, and then the identifier's kind is set by the parser. 44 if ( id_pos == table.end() ) return IDENTIFIER; 45 return id_pos->second.begin()->kind; 48 // SKULLDUGGERY: Generate a typedef for the aggregate name so the aggregate does not have to be qualified by 49 // "struct". Only generate the typedef, if the name is not in use. The typedef is implicitly (silently) removed 50 // if the name is explicitly used. 51 void TypedefTable::makeTypedef( const string &name ) { 52 if ( ! typedefTable.exists( name ) ) { 53 typedefTable.addToEnclosingScope( name, TypedefTable::TD ); 54 } // if 46 55 } 47 56 -
src/Parser/TypedefTable.h
rdb4ecc5 r70a06f6 10 10 // Created On : Sat May 16 15:24:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Mar 21 18:17:36 201613 // Update Count : 2 412 // Last Modified On : Wed Apr 13 16:59:56 2016 13 // Update Count : 27 14 14 // 15 15 … … 59 59 int isKind( const std::string &identifier ) const; 60 60 void changeKind( const std::string &identifier, kind_t kind ); 61 61 62 void makeTypedef( const std::string &name ); 63 62 64 // "addToCurrentScope" adds the identifier/type pair to the current scope. This does less than you think it does, 63 65 // since each declaration is within its own scope. Mostly useful for type parameters. -
src/Parser/parser.cc
rdb4ecc5 r70a06f6 590 590 #define YYFINAL 249 591 591 /* YYLAST -- Last index in YYTABLE. */ 592 #define YYLAST 11 290592 #define YYLAST 11449 593 593 594 594 /* YYNTOKENS -- Number of terminals. */ 595 595 #define YYNTOKENS 133 596 596 /* YYNNTS -- Number of nonterminals. */ 597 #define YYNNTS 2 38597 #define YYNNTS 240 598 598 /* YYNRULES -- Number of rules. */ 599 #define YYNRULES 75 2599 #define YYNRULES 754 600 600 /* YYNRULES -- Number of states. */ 601 #define YYNSTATES 15 79601 #define YYNSTATES 1581 602 602 603 603 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ … … 691 691 1223, 1227, 1229, 1232, 1235, 1238, 1243, 1248, 1253, 1258, 692 692 1260, 1263, 1266, 1270, 1272, 1275, 1278, 1280, 1283, 1286, 693 1290, 1292, 1295, 1298, 1300, 1302, 1307, 1310, 131 6, 1324,694 132 7, 1330, 1333, 1335, 1338, 1341, 1345, 1348, 1352, 1354,695 135 7, 1361, 1364, 1367, 1372, 1373, 1375, 1378, 1381, 1383,696 138 4, 1386, 1389, 1392, 1398, 1405, 1408, 1411, 1416, 1417,697 1420, 1421, 142 3, 1425, 1427, 1433, 1439, 1445, 1447, 1453,698 145 9, 1469, 1471, 1477, 1478, 1480, 1482, 1488, 1490, 1492,699 149 8, 1504, 1506, 1510, 1514, 1519, 1521, 1523, 1525, 1527,700 15 30, 1532, 1536, 1540, 1542, 1545, 1547, 1551, 1553, 1555,701 1557, 1559, 1561, 1563, 1565, 1567, 1569, 1571, 1573, 157 6,702 157 8, 1580, 1582, 1585, 1586, 1589, 1592, 1594, 1599, 1600,703 160 2, 1605, 1609, 1614, 1617, 1620, 1622, 1625, 1627, 1630,704 163 6, 1642, 1650, 1657, 1659, 1662, 1665, 1669, 1671, 1674,705 167 7, 1682, 1685, 1690, 1691, 1696, 1699, 1701, 1703, 1705,706 170 6, 1709, 1715, 1721, 1735, 1737, 1739, 1743, 1747, 1750,707 175 4, 1758, 1761, 1766, 1768, 1775, 1785, 1786, 1798, 1800,708 180 4, 1808, 1812, 1814, 1816, 1822, 1825, 1831, 1832, 1834,709 1836, 18 40, 1841, 1843, 1845, 1847, 1849, 1850, 1857, 1860,710 186 2, 1865, 1870, 1873, 1877, 1881, 1885, 1890, 1896, 1902,711 190 8, 1915, 1917, 1919, 1921, 1925, 1926, 1932, 1933, 1935,712 1937, 19 40, 1947, 1949, 1953, 1954, 1956, 1961, 1963, 1965,713 1967, 1969, 197 2, 1974, 1977, 1980, 1982, 1986, 1989, 1993,714 199 7, 2000, 2005, 2010, 2014, 2023, 2027, 2030, 2032, 2035,715 20 42, 2051, 2055, 2058, 2062, 2066, 2071, 2076, 2080, 2082,716 2084, 2086, 20 91, 2098, 2102, 2105, 2109, 2113, 2118, 2123,717 212 7, 2130, 2132, 2135, 2138, 2140, 2144, 2147, 2151, 2155,718 215 8, 2163, 2168, 2172, 2179, 2188, 2192, 2195, 2197, 2200,719 220 3, 2206, 2210, 2214, 2217, 2222, 2227, 2231, 2238, 2247,720 22 51, 2254, 2256, 2259, 2262, 2264, 2266, 2269, 2273, 2277,721 22 80, 2285, 2292, 2301, 2303, 2306, 2309, 2311, 2314, 2317,722 23 21, 2325, 2327, 2332, 2337, 2341, 2347, 2356, 2360, 2363,723 236 7, 2369, 2375, 2381, 2388, 2395, 2397, 2400, 2403, 2405,724 240 8, 2411, 2415, 2419, 2421, 2426, 2431, 2435, 2441, 2450,725 24 54, 2456, 2459, 2461, 2464, 2471, 2477, 2484, 2492, 2500,726 2 502, 2505, 2508, 2510, 2513, 2516, 2520, 2524, 2526, 2531,727 253 6, 2540, 2549, 2553, 2555, 2557, 2560, 2562, 2564, 2567,728 25 71, 2574, 2578, 2581, 2585, 2589, 2592, 2597, 2601, 2604,729 260 8, 2611, 2616, 2620, 2623, 2630, 2637, 2644, 2652, 2654,730 265 7, 2659, 2661, 2663, 2666, 2670, 2673, 2677, 2680, 2684,731 268 8, 2693, 2696, 2700, 2705, 2708, 2714, 2720, 2727, 2734,732 273 5, 2737, 2738693 1290, 1292, 1295, 1298, 1300, 1302, 1307, 1310, 1311, 1318, 694 1326, 1329, 1332, 1335, 1337, 1340, 1343, 1347, 1350, 1354, 695 1356, 1359, 1363, 1366, 1369, 1374, 1375, 1377, 1380, 1383, 696 1385, 1386, 1388, 1391, 1394, 1400, 1403, 1404, 1412, 1415, 697 1420, 1421, 1424, 1425, 1427, 1429, 1431, 1437, 1443, 1449, 698 1451, 1457, 1463, 1473, 1475, 1481, 1482, 1484, 1486, 1492, 699 1494, 1496, 1502, 1508, 1510, 1514, 1518, 1523, 1525, 1527, 700 1529, 1531, 1534, 1536, 1540, 1544, 1546, 1549, 1551, 1555, 701 1557, 1559, 1561, 1563, 1565, 1567, 1569, 1571, 1573, 1575, 702 1577, 1580, 1582, 1584, 1586, 1589, 1590, 1593, 1596, 1598, 703 1603, 1604, 1606, 1609, 1613, 1618, 1621, 1624, 1626, 1629, 704 1631, 1634, 1640, 1646, 1654, 1661, 1663, 1666, 1669, 1673, 705 1675, 1678, 1681, 1686, 1689, 1694, 1695, 1700, 1703, 1705, 706 1707, 1709, 1710, 1713, 1719, 1725, 1739, 1741, 1743, 1747, 707 1751, 1754, 1758, 1762, 1765, 1770, 1772, 1779, 1789, 1790, 708 1802, 1804, 1808, 1812, 1816, 1818, 1820, 1826, 1829, 1835, 709 1836, 1838, 1840, 1844, 1845, 1847, 1849, 1851, 1853, 1854, 710 1861, 1864, 1866, 1869, 1874, 1877, 1881, 1885, 1889, 1894, 711 1900, 1906, 1912, 1919, 1921, 1923, 1925, 1929, 1930, 1936, 712 1937, 1939, 1941, 1944, 1951, 1953, 1957, 1958, 1960, 1965, 713 1967, 1969, 1971, 1973, 1976, 1978, 1981, 1984, 1986, 1990, 714 1993, 1997, 2001, 2004, 2009, 2014, 2018, 2027, 2031, 2034, 715 2036, 2039, 2046, 2055, 2059, 2062, 2066, 2070, 2075, 2080, 716 2084, 2086, 2088, 2090, 2095, 2102, 2106, 2109, 2113, 2117, 717 2122, 2127, 2131, 2134, 2136, 2139, 2142, 2144, 2148, 2151, 718 2155, 2159, 2162, 2167, 2172, 2176, 2183, 2192, 2196, 2199, 719 2201, 2204, 2207, 2210, 2214, 2218, 2221, 2226, 2231, 2235, 720 2242, 2251, 2255, 2258, 2260, 2263, 2266, 2268, 2270, 2273, 721 2277, 2281, 2284, 2289, 2296, 2305, 2307, 2310, 2313, 2315, 722 2318, 2321, 2325, 2329, 2331, 2336, 2341, 2345, 2351, 2360, 723 2364, 2367, 2371, 2373, 2379, 2385, 2392, 2399, 2401, 2404, 724 2407, 2409, 2412, 2415, 2419, 2423, 2425, 2430, 2435, 2439, 725 2445, 2454, 2458, 2460, 2463, 2465, 2468, 2475, 2481, 2488, 726 2496, 2504, 2506, 2509, 2512, 2514, 2517, 2520, 2524, 2528, 727 2530, 2535, 2540, 2544, 2553, 2557, 2559, 2561, 2564, 2566, 728 2568, 2571, 2575, 2578, 2582, 2585, 2589, 2593, 2596, 2601, 729 2605, 2608, 2612, 2615, 2620, 2624, 2627, 2634, 2641, 2648, 730 2656, 2658, 2661, 2663, 2665, 2667, 2670, 2674, 2677, 2681, 731 2684, 2688, 2692, 2697, 2700, 2704, 2709, 2712, 2718, 2724, 732 2731, 2738, 2739, 2741, 2742 733 733 }; 734 734 … … 736 736 static const yytype_int16 yyrhs[] = 737 737 { 738 299, 0, -1, -1, -1, 79, -1, 80, -1, 81,738 301, 0, -1, -1, -1, 79, -1, 80, -1, 81, 739 739 -1, 72, -1, 76, -1, 140, -1, 72, -1, 76, 740 740 -1, 72, -1, 140, -1, 83, -1, 84, -1, 82, … … 745 745 112, -1, 143, 85, 139, -1, 143, 85, 111, 134, 746 746 146, 135, 112, -1, 143, 86, -1, 143, 87, -1, 747 109, 27 2, 110, 114, 276, 369, 115, -1, 143, 114,747 109, 274, 110, 114, 278, 371, 115, -1, 143, 114, 748 748 144, 115, -1, 145, -1, 144, 116, 145, -1, -1, 749 749 163, -1, 139, 117, 163, -1, 111, 134, 163, 135, … … 755 755 141, -1, 86, 148, -1, 87, 148, -1, 40, 150, 756 756 -1, 149, 150, -1, 118, 150, -1, 119, 150, -1, 757 37, 148, -1, 37, 109, 27 2, 110, -1, 38, 109,758 27 2, 116, 139, 110, -1, 76, -1, 76, 109, 273,757 37, 148, -1, 37, 109, 274, 110, -1, 38, 109, 758 274, 116, 139, 110, -1, 76, -1, 76, 109, 275, 759 759 110, -1, 76, 109, 145, 110, -1, 66, 148, -1, 760 66, 109, 27 2, 110, -1, 94, 139, -1, 120, -1,761 121, -1, 122, -1, 123, -1, 148, -1, 109, 27 2,762 110, 150, -1, 109, 27 2, 110, 165, -1, 150, -1,760 66, 109, 274, 110, -1, 94, 139, -1, 120, -1, 761 121, -1, 122, -1, 123, -1, 148, -1, 109, 274, 762 110, 150, -1, 109, 274, 110, 165, -1, 150, -1, 763 763 151, 119, 150, -1, 151, 124, 150, -1, 151, 125, 764 764 150, -1, 151, -1, 152, 121, 151, -1, 152, 122, … … 773 773 117, 161, -1, 160, 130, 168, 117, 165, -1, 161, 774 774 -1, 161, -1, 148, 131, 163, -1, 148, 167, 163, 775 -1, 165, 37 0, -1, -1, 163, -1, 111, 112, -1,775 -1, 165, 372, -1, -1, 163, -1, 111, 112, -1, 776 776 111, 134, 163, 135, 112, -1, 111, 134, 116, 166, 777 777 135, 112, -1, 111, 134, 163, 116, 166, 135, 112, … … 782 782 176, -1, 177, -1, 189, -1, 191, -1, 192, -1, 783 783 197, -1, 128, 143, 114, 144, 115, 132, -1, 139, 784 117, 3 09, 170, -1, 114, 115, -1, 114, 134, 134,784 117, 311, 170, -1, 114, 115, -1, 114, 134, 134, 785 785 208, 173, 135, 115, -1, 174, -1, 173, 134, 174, 786 -1, 211, -1, 40, 211, -1, 30 5, -1, 170, 135,786 -1, 211, -1, 40, 211, -1, 307, -1, 170, 135, 787 787 -1, 170, -1, 175, 170, -1, 169, 132, -1, 41, 788 788 109, 168, 110, 170, -1, 41, 109, 168, 110, 170, … … 791 791 109, 168, 110, 182, -1, 53, 109, 168, 110, 114, 792 792 134, 204, 185, 115, -1, 162, -1, 162, 96, 162, 793 -1, 30 7, -1, 178, -1, 179, 116, 178, -1, 44,793 -1, 309, -1, 178, -1, 179, 116, 178, -1, 44, 794 794 179, 117, -1, 45, 117, -1, 180, -1, 181, 180, 795 795 -1, 181, 170, -1, -1, 184, -1, 181, 175, -1, … … 813 813 134, 196, 135, 110, 172, 135, -1, 194, 59, 109, 814 814 134, 134, 196, 135, 110, 172, 135, -1, 60, 172, 815 -1, 224, -1, 224, 30 6, -1, 224, 354, -1, 363,816 139, -1, 36 3, -1, 64, 198, 109, 141, 110, 132,815 -1, 224, -1, 224, 308, -1, 224, 356, -1, 365, 816 139, -1, 365, -1, 64, 198, 109, 141, 110, 132, 817 817 -1, 64, 198, 109, 141, 117, 199, 110, 132, -1, 818 818 64, 198, 109, 141, 117, 199, 117, 199, 110, 132, … … 826 826 -1, 211, -1, 205, 134, 211, -1, 135, -1, 207, 827 827 -1, 221, -1, 207, 134, 221, -1, -1, 209, -1, 828 29, 210, 132, -1, 209, 29, 210, 132, -1, 27 1,829 -1, 210, 116, 27 1, -1, 212, -1, 221, -1, 213,828 29, 210, 132, -1, 209, 29, 210, 132, -1, 273, 829 -1, 210, 116, 273, -1, 212, -1, 221, -1, 213, 830 830 135, 132, -1, 218, 135, 132, -1, 215, 135, 132, 831 -1, 29 0, 135, 132, -1, 293, 135, 132, -1, 214,832 27 4, -1, 230, 214, 274, -1, 213, 135, 116, 134,833 2 69, 274, -1, 364, 269, 308, -1, 367, 269, 308,834 -1, 226, 36 7, 269, 308, -1, 216, -1, 226, 216,831 -1, 292, 135, 132, -1, 295, 135, 132, -1, 214, 832 276, -1, 230, 214, 276, -1, 213, 135, 116, 134, 833 271, 276, -1, 366, 271, 310, -1, 369, 271, 310, 834 -1, 226, 369, 271, 310, -1, 216, -1, 226, 216, 835 835 -1, 230, 216, -1, 230, 226, 216, -1, 215, 135, 836 116, 134, 2 69, -1, 111, 112, 269, 109, 134, 257,837 135, 110, -1, 36 7, 269, 109, 134, 257, 135, 110,838 -1, 217, 2 69, 109, 134, 257, 135, 110, -1, 111,839 134, 2 59, 135, 112, -1, 111, 134, 259, 135, 116,840 134, 26 0, 135, 112, -1, 3, 214, -1, 3, 216,841 -1, 218, 135, 116, 134, 139, -1, 3, 224, 30 6,842 -1, 219, 135, 116, 134, 30 6, -1, 226, 3, 224,843 30 6, -1, 224, 3, 306, -1, 224, 3, 226, 306,836 116, 134, 271, -1, 111, 112, 271, 109, 134, 259, 837 135, 110, -1, 369, 271, 109, 134, 259, 135, 110, 838 -1, 217, 271, 109, 134, 259, 135, 110, -1, 111, 839 134, 261, 135, 112, -1, 111, 134, 261, 135, 116, 840 134, 262, 135, 112, -1, 3, 214, -1, 3, 216, 841 -1, 218, 135, 116, 134, 139, -1, 3, 224, 308, 842 -1, 219, 135, 116, 134, 308, -1, 226, 3, 224, 843 308, -1, 224, 3, 308, -1, 224, 3, 226, 308, 844 844 -1, 3, 139, 131, 163, -1, 220, 135, 116, 134, 845 845 139, 131, 163, -1, 222, 135, 132, -1, 219, 135, 846 846 132, -1, 220, 135, 132, -1, 239, 135, 132, -1, 847 223, 30 6, 308, 274, -1, 222, 116, 309, 306, 308,848 27 4, -1, 235, -1, 239, -1, 241, -1, 280, -1,849 236, -1, 240, -1, 242, -1, 28 1, -1, -1, 226,850 -1, 227, -1, 226, 227, -1, 228, -1, 31 1, -1,847 223, 308, 310, 276, -1, 222, 116, 311, 308, 310, 848 276, -1, 235, -1, 239, -1, 241, -1, 282, -1, 849 236, -1, 240, -1, 242, -1, 283, -1, -1, 226, 850 -1, 227, -1, 226, 227, -1, 228, -1, 313, -1, 851 851 10, -1, 12, -1, 11, -1, 14, -1, 67, -1, 852 -1, 13, 109, 229, 28 3, 110, -1, 231, -1, 226,852 -1, 13, 109, 229, 285, 110, -1, 231, -1, 226, 853 853 231, -1, 230, 226, 231, -1, 232, -1, 231, 232, 854 854 -1, 233, -1, 5, -1, 7, -1, 4, -1, 6, … … 860 860 -1, 237, -1, 225, 238, 225, -1, 234, -1, 226, 861 861 234, -1, 237, 227, -1, 237, 234, -1, 28, 109, 862 27 3, 110, -1, 28, 109, 168, 110, -1, 78, 109,863 27 3, 110, -1, 78, 109, 168, 110, -1, 240, -1,862 275, 110, -1, 28, 109, 168, 110, -1, 78, 109, 863 275, 110, -1, 78, 109, 168, 110, -1, 240, -1, 864 864 230, 240, -1, 239, 232, -1, 239, 232, 226, -1, 865 865 243, -1, 226, 243, -1, 240, 227, -1, 242, -1, 866 866 230, 242, -1, 241, 232, -1, 241, 232, 226, -1, 867 867 74, -1, 226, 74, -1, 242, 227, -1, 244, -1, 868 25 4, -1, 245, 114, 246, 115, -1, 245, 271, -1,869 245, 271, 114, 246, 115, -1, 245, 109, 289, 110,870 114, 246, 115, -1, 245, 282, -1, 31, 309, -1,871 32, 309, -1, 247, -1, 246, 247, -1, 248, 132,872 -1, 40, 248, 132, -1, 249, 132, -1, 40, 249,873 132, -1, 363, -1, 363, 271, -1, 248, 116, 271,874 -1, 248, 116, -1, 224, 250, -1, 249, 116, 309,875 250, -1, -1, 252, -1, 315, 251, -1, 328, 251,876 -1, 354, -1, -1, 252, -1, 117, 162, -1, 30,877 309, -1, 253, 114, 255, 369, 115, -1, 253, 271,878 114, 255, 369, 115, -1, 253, 271, -1, 271, 256,879 -1, 255, 116, 271, 256, -1, -1, 131, 162, -1,880 -1, 258, -1, 260, -1, 259, -1, 259, 135, 116,881 134, 260, -1, 260, 135, 116, 134, 96, -1, 259,882 13 5, 116, 134, 96, -1, 264, -1, 260, 135, 116,883 134, 264, -1, 259, 135, 116, 134, 264, -1, 259,884 13 5, 116, 134, 260, 135, 116, 134, 264, -1, 265,885 -1, 260, 135, 116, 134, 265, -1, -1, 262, -1,886 263, -1, 263, 135, 116, 134, 96, -1, 267, -1,887 266, -1, 263, 135, 116, 134, 267, -1, 263, 135,888 116, 134, 266, -1, 266, -1, 359, 269, 370, -1,889 36 7, 269, 370, -1, 226, 367, 269, 370, -1, 216,890 -1, 267, -1, 359, -1, 367, -1, 226, 367, -1,891 368, -1, 223, 333, 370, -1, 223, 337, 370, -1,892 223, -1, 223, 348, -1, 139, -1, 268, 116, 139,893 -1, 137, -1, 74, -1, 75, -1, 138, -1, 74,894 -1, 75, -1, 139, -1, 74, -1, 75, -1, 363,895 -1, 224, -1, 224, 354, -1, 363, -1, 368, -1,896 224, -1, 224, 342, -1, -1, 131, 275, -1, 107,897 275, -1, 163, -1, 114, 276, 369, 115, -1, -1,898 275, -1, 277, 275, -1, 276, 116, 275, -1, 276,899 116, 277, 275, -1, 278, 117, -1, 271, 117, -1,900 279, -1, 278, 279, -1, 80, -1, 113, 271, -1,901 111, 134, 163, 135, 112, -1, 111, 134, 307, 135,902 11 2, -1, 111, 134, 162, 96, 162, 135, 112, -1,903 1 13, 111, 134, 146, 135, 112, -1, 281, -1, 230,904 281, -1, 280, 232, -1, 280, 232, 226, -1, 282,905 -1, 226, 282, -1, 281, 227, -1, 75, 109, 289,906 110, -1, 284, 370, -1, 283, 116, 284, 370, -1,907 -1, 286, 271, 285, 287, -1, 224, 333, -1, 33,908 -1, 35, -1, 34, -1, -1, 287, 288, -1, 129,909 2 71, 109, 289, 110, -1, 129, 114, 134, 295, 115,910 -1, 129, 109, 134, 283, 135, 110, 114, 134, 295,911 11 5, 109, 289, 110, -1, 273, -1, 163, -1, 289,912 116, 273, -1, 289, 116, 163, -1, 33, 291, -1,913 231, 33, 291, -1, 290, 116, 291, -1, 292, 287,914 -1, 292, 287, 131, 273, -1, 271, -1, 270, 109,915 134, 283, 135, 110, -1, 36, 271, 109, 134, 283,916 135, 110, 114, 115, -1, -1, 36, 271, 109, 134,917 283, 135, 110, 114, 294, 295, 115, -1, 296, -1,918 295, 134, 296, -1, 297, 135, 132, -1, 298, 135,919 132, -1, 214, -1, 216, -1, 297, 135, 116, 134,920 2 69, -1, 224, 306, -1, 298, 135, 116, 134, 306,921 -1, -1, 300, -1, 302, -1, 300, 134, 302, -1,922 -1, 300, -1, 211, -1, 304, -1, 197, -1, -1,923 5, 82, 303, 114, 301, 115, -1, 40, 302, -1,924 305, -1, 320, 172, -1, 324, 134, 206, 172, -1,925 215, 172, -1, 223, 320, 172, -1, 226, 320, 172,926 -1, 2 30, 320, 172, -1, 230, 226, 320, 172, -1,927 22 3, 324, 134, 206, 172, -1, 226, 324, 134, 206,928 172, -1, 230, 324, 134, 206, 172, -1, 230, 226,929 324, 134, 206, 172, -1, 315, -1, 320, -1, 328,930 -1, 162, 123, 162, -1, -1, 64, 109, 141, 110,931 309, -1, -1, 310, -1, 311, -1, 310, 311, -1,932 39, 109, 109, 312, 110, 110, -1, 313, -1, 312,933 116, 313, -1, -1, 314, -1, 314, 109, 169, 110,934 -1, 269, -1, 233, -1, 234, -1, 227, -1, 316,935 309, -1, 317, -1, 318, 309, -1, 319, 309, -1,936 137, -1, 109, 316, 110, -1, 119, 315, -1, 119,937 226, 315, -1, 109, 317, 110, -1, 316, 346, -1,938 109, 317, 110, 346, -1, 109, 318, 110, 347, -1,939 109, 318, 110, -1, 109, 317, 110, 109, 134, 261,940 1 35, 110, -1, 109, 319, 110, -1, 321, 309, -1,941 322, -1, 323, 309, -1, 316, 109, 134, 261, 135,942 1 10, -1, 109, 322, 110, 109, 134, 261, 135, 110,943 -1, 109, 321, 110, -1, 119, 320, -1, 119, 226,944 32 0, -1, 109, 322, 110, -1, 109, 322, 110, 346,945 -1, 109, 323, 110, 347, -1, 109, 323, 110, -1,946 325, -1, 326, -1, 327, -1, 316, 109, 268, 110,947 -1, 109, 326, 110, 109, 268, 110, -1, 109, 325,948 110, -1, 1 19, 324, -1, 119, 226, 324, -1, 109,949 326, 110, -1, 109, 326, 110, 346, -1, 109, 327,950 110, 347, -1, 109, 327, 110, -1, 329, 309, -1,951 330, -1, 331, 309, -1, 332, 309, -1, 338, -1,952 109, 329, 110, -1, 119, 328, -1, 119, 226, 328,953 -1, 1 09, 330, 110, -1, 329, 346, -1, 109, 330,954 110, 346, -1, 109, 331, 110, 347, -1, 109, 331,955 110, -1, 329, 109, 134, 261, 135, 110, -1, 109,956 330, 110, 109, 134, 261, 135, 110, -1, 109, 332,957 110, -1, 316, 309, -1, 334, -1, 335, 309, -1,958 336, 309, -1, 119, 333, -1, 119, 226, 333, -1,959 1 09, 334, 110, -1, 316, 352, -1, 109, 334, 110,960 346, -1, 109, 335, 110, 347, -1, 109, 335, 110,961 -1, 316, 109, 134, 261, 135, 110, -1, 109, 334,962 110, 109, 134, 261, 135, 110, -1, 109, 336, 110,963 -1, 338, 309, -1, 339, -1, 340, 309, -1, 341,964 3 09, -1, 74, -1, 75, -1, 119, 337, -1, 119,965 226, 337, -1, 109, 339, 110, -1, 338, 352, -1,966 109, 339, 110, 352, -1, 338, 109, 134, 261, 135,967 1 10, -1, 109, 339, 110, 109, 134, 261, 135, 110,968 -1, 343, -1, 344, 309, -1, 345, 309, -1, 119,969 -1, 119, 226, -1, 119, 342, -1, 119, 226, 342,970 -1, 1 09, 343, 110, -1, 346, -1, 109, 343, 110,971 346, -1, 109, 344, 110, 347, -1, 109, 344, 110,972 -1, 109, 134, 261, 135, 110, -1, 109, 343, 110,973 109, 134, 261, 135, 110, -1, 109, 345, 110, -1,974 1 11, 112, -1, 111, 112, 347, -1, 347, -1, 111,975 134, 163, 135, 112, -1, 111, 134, 119, 135, 112,976 -1, 347, 111, 134, 163, 135, 112, -1, 347, 111,977 1 34, 119, 135, 112, -1, 349, -1, 350, 309, -1,978 351, 309, -1, 119, -1, 119, 226, -1, 119, 348,979 -1, 119, 226, 348, -1, 109, 349, 110, -1, 352,980 -1, 109, 349, 110, 352, -1, 109, 350, 110, 347,981 -1, 109, 350, 110, -1, 109, 134, 261, 135, 110,982 -1, 109, 349, 110, 109, 134, 261, 135, 110, -1,983 109, 351, 110, -1, 353, -1, 353, 347, -1, 347,984 -1, 111, 112, -1, 111, 134, 226, 119, 135, 112,985 -1, 111, 134, 226, 135, 112, -1, 111, 134, 226,986 163, 135, 112, -1, 111, 134, 7, 225, 163, 135,987 112, -1, 111, 134, 226, 7, 163, 135, 112, -1,988 355, -1, 356, 309, -1, 357, 309, -1, 119, -1,989 119, 226, -1, 119, 354, -1, 119, 226, 354, -1,990 1 09, 355, 110, -1, 346, -1, 109, 355, 110, 346,991 -1, 109, 356, 110, 347, -1, 109, 356, 110, -1,992 109, 35 5, 110, 109, 134, 261, 135, 110, -1, 109,993 357, 110, -1, 359, -1, 367, -1, 226, 367, -1,994 360, -1, 361, -1, 119, 224, -1, 226, 119, 224,995 -1, 119, 368, -1, 226, 119, 368, -1, 119, 358,996 -1, 226, 119, 358, -1, 111, 112, 224, -1, 362,997 224, -1, 111, 112, 347, 224, -1, 362, 347, 224,998 -1, 3 47, 224, -1, 111, 112, 360, -1, 362, 360,999 -1, 111, 112, 347, 360, -1, 362, 347, 360, -1,1000 3 47, 360, -1, 111, 134, 226, 119, 135, 112, -1,1001 11 1, 134, 226, 163, 135, 112, -1, 111, 134, 230,1002 163, 135, 112, -1, 111, 134, 230, 226, 163, 135,1003 112, -1, 367, -1, 226, 367, -1, 364, -1, 365,1004 -1, 366, -1, 119, 224, -1, 226, 119, 224, -1,1005 119, 368, -1, 226, 119, 368, -1, 119, 363, -1,1006 226, 119, 363, -1, 111, 112, 224, -1, 111, 112,1007 347, 224, -1, 347, 224, -1, 111, 112, 365, -1,1008 111, 112, 3 47, 365, -1, 347, 365, -1, 111, 134,1009 260, 135, 112, -1, 111, 112, 109, 257, 110, -1,1010 367, 109, 134, 257, 135, 110, -1, 217, 109, 134,1011 257, 135, 110, -1, -1, 116, -1, -1, 131, 163,1012 -1 868 255, -1, 246, 114, 247, 115, -1, 246, 273, -1, 869 -1, 246, 273, 245, 114, 247, 115, -1, 246, 109, 870 291, 110, 114, 247, 115, -1, 246, 284, -1, 31, 871 311, -1, 32, 311, -1, 248, -1, 247, 248, -1, 872 249, 132, -1, 40, 249, 132, -1, 250, 132, -1, 873 40, 250, 132, -1, 365, -1, 365, 273, -1, 249, 874 116, 273, -1, 249, 116, -1, 224, 251, -1, 250, 875 116, 311, 251, -1, -1, 253, -1, 317, 252, -1, 876 330, 252, -1, 356, -1, -1, 253, -1, 117, 162, 877 -1, 30, 311, -1, 254, 114, 257, 371, 115, -1, 878 254, 273, -1, -1, 254, 273, 256, 114, 257, 371, 879 115, -1, 273, 258, -1, 257, 116, 273, 258, -1, 880 -1, 131, 162, -1, -1, 260, -1, 262, -1, 261, 881 -1, 261, 135, 116, 134, 262, -1, 262, 135, 116, 882 134, 96, -1, 261, 135, 116, 134, 96, -1, 266, 883 -1, 262, 135, 116, 134, 266, -1, 261, 135, 116, 884 134, 266, -1, 261, 135, 116, 134, 262, 135, 116, 885 134, 266, -1, 267, -1, 262, 135, 116, 134, 267, 886 -1, -1, 264, -1, 265, -1, 265, 135, 116, 134, 887 96, -1, 269, -1, 268, -1, 265, 135, 116, 134, 888 269, -1, 265, 135, 116, 134, 268, -1, 268, -1, 889 361, 271, 372, -1, 369, 271, 372, -1, 226, 369, 890 271, 372, -1, 216, -1, 269, -1, 361, -1, 369, 891 -1, 226, 369, -1, 370, -1, 223, 335, 372, -1, 892 223, 339, 372, -1, 223, -1, 223, 350, -1, 139, 893 -1, 270, 116, 139, -1, 137, -1, 74, -1, 75, 894 -1, 138, -1, 74, -1, 75, -1, 139, -1, 74, 895 -1, 75, -1, 365, -1, 224, -1, 224, 356, -1, 896 365, -1, 370, -1, 224, -1, 224, 344, -1, -1, 897 131, 277, -1, 107, 277, -1, 163, -1, 114, 278, 898 371, 115, -1, -1, 277, -1, 279, 277, -1, 278, 899 116, 277, -1, 278, 116, 279, 277, -1, 280, 117, 900 -1, 273, 117, -1, 281, -1, 280, 281, -1, 80, 901 -1, 113, 273, -1, 111, 134, 163, 135, 112, -1, 902 111, 134, 309, 135, 112, -1, 111, 134, 162, 96, 903 162, 135, 112, -1, 113, 111, 134, 146, 135, 112, 904 -1, 283, -1, 230, 283, -1, 282, 232, -1, 282, 905 232, 226, -1, 284, -1, 226, 284, -1, 283, 227, 906 -1, 75, 109, 291, 110, -1, 286, 372, -1, 285, 907 116, 286, 372, -1, -1, 288, 273, 287, 289, -1, 908 224, 335, -1, 33, -1, 35, -1, 34, -1, -1, 909 289, 290, -1, 129, 273, 109, 291, 110, -1, 129, 910 114, 134, 297, 115, -1, 129, 109, 134, 285, 135, 911 110, 114, 134, 297, 115, 109, 291, 110, -1, 275, 912 -1, 163, -1, 291, 116, 275, -1, 291, 116, 163, 913 -1, 33, 293, -1, 231, 33, 293, -1, 292, 116, 914 293, -1, 294, 289, -1, 294, 289, 131, 275, -1, 915 273, -1, 272, 109, 134, 285, 135, 110, -1, 36, 916 273, 109, 134, 285, 135, 110, 114, 115, -1, -1, 917 36, 273, 109, 134, 285, 135, 110, 114, 296, 297, 918 115, -1, 298, -1, 297, 134, 298, -1, 299, 135, 919 132, -1, 300, 135, 132, -1, 214, -1, 216, -1, 920 299, 135, 116, 134, 271, -1, 224, 308, -1, 300, 921 135, 116, 134, 308, -1, -1, 302, -1, 304, -1, 922 302, 134, 304, -1, -1, 302, -1, 211, -1, 306, 923 -1, 197, -1, -1, 5, 82, 305, 114, 303, 115, 924 -1, 40, 304, -1, 307, -1, 322, 172, -1, 326, 925 134, 206, 172, -1, 215, 172, -1, 223, 322, 172, 926 -1, 226, 322, 172, -1, 230, 322, 172, -1, 230, 927 226, 322, 172, -1, 223, 326, 134, 206, 172, -1, 928 226, 326, 134, 206, 172, -1, 230, 326, 134, 206, 929 172, -1, 230, 226, 326, 134, 206, 172, -1, 317, 930 -1, 322, -1, 330, -1, 162, 123, 162, -1, -1, 931 64, 109, 141, 110, 311, -1, -1, 312, -1, 313, 932 -1, 312, 313, -1, 39, 109, 109, 314, 110, 110, 933 -1, 315, -1, 314, 116, 315, -1, -1, 316, -1, 934 316, 109, 169, 110, -1, 271, -1, 233, -1, 234, 935 -1, 227, -1, 318, 311, -1, 319, -1, 320, 311, 936 -1, 321, 311, -1, 137, -1, 109, 318, 110, -1, 937 119, 317, -1, 119, 226, 317, -1, 109, 319, 110, 938 -1, 318, 348, -1, 109, 319, 110, 348, -1, 109, 939 320, 110, 349, -1, 109, 320, 110, -1, 109, 319, 940 110, 109, 134, 263, 135, 110, -1, 109, 321, 110, 941 -1, 323, 311, -1, 324, -1, 325, 311, -1, 318, 942 109, 134, 263, 135, 110, -1, 109, 324, 110, 109, 943 134, 263, 135, 110, -1, 109, 323, 110, -1, 119, 944 322, -1, 119, 226, 322, -1, 109, 324, 110, -1, 945 109, 324, 110, 348, -1, 109, 325, 110, 349, -1, 946 109, 325, 110, -1, 327, -1, 328, -1, 329, -1, 947 318, 109, 270, 110, -1, 109, 328, 110, 109, 270, 948 110, -1, 109, 327, 110, -1, 119, 326, -1, 119, 949 226, 326, -1, 109, 328, 110, -1, 109, 328, 110, 950 348, -1, 109, 329, 110, 349, -1, 109, 329, 110, 951 -1, 331, 311, -1, 332, -1, 333, 311, -1, 334, 952 311, -1, 340, -1, 109, 331, 110, -1, 119, 330, 953 -1, 119, 226, 330, -1, 109, 332, 110, -1, 331, 954 348, -1, 109, 332, 110, 348, -1, 109, 333, 110, 955 349, -1, 109, 333, 110, -1, 331, 109, 134, 263, 956 135, 110, -1, 109, 332, 110, 109, 134, 263, 135, 957 110, -1, 109, 334, 110, -1, 318, 311, -1, 336, 958 -1, 337, 311, -1, 338, 311, -1, 119, 335, -1, 959 119, 226, 335, -1, 109, 336, 110, -1, 318, 354, 960 -1, 109, 336, 110, 348, -1, 109, 337, 110, 349, 961 -1, 109, 337, 110, -1, 318, 109, 134, 263, 135, 962 110, -1, 109, 336, 110, 109, 134, 263, 135, 110, 963 -1, 109, 338, 110, -1, 340, 311, -1, 341, -1, 964 342, 311, -1, 343, 311, -1, 74, -1, 75, -1, 965 119, 339, -1, 119, 226, 339, -1, 109, 341, 110, 966 -1, 340, 354, -1, 109, 341, 110, 354, -1, 340, 967 109, 134, 263, 135, 110, -1, 109, 341, 110, 109, 968 134, 263, 135, 110, -1, 345, -1, 346, 311, -1, 969 347, 311, -1, 119, -1, 119, 226, -1, 119, 344, 970 -1, 119, 226, 344, -1, 109, 345, 110, -1, 348, 971 -1, 109, 345, 110, 348, -1, 109, 346, 110, 349, 972 -1, 109, 346, 110, -1, 109, 134, 263, 135, 110, 973 -1, 109, 345, 110, 109, 134, 263, 135, 110, -1, 974 109, 347, 110, -1, 111, 112, -1, 111, 112, 349, 975 -1, 349, -1, 111, 134, 163, 135, 112, -1, 111, 976 134, 119, 135, 112, -1, 349, 111, 134, 163, 135, 977 112, -1, 349, 111, 134, 119, 135, 112, -1, 351, 978 -1, 352, 311, -1, 353, 311, -1, 119, -1, 119, 979 226, -1, 119, 350, -1, 119, 226, 350, -1, 109, 980 351, 110, -1, 354, -1, 109, 351, 110, 354, -1, 981 109, 352, 110, 349, -1, 109, 352, 110, -1, 109, 982 134, 263, 135, 110, -1, 109, 351, 110, 109, 134, 983 263, 135, 110, -1, 109, 353, 110, -1, 355, -1, 984 355, 349, -1, 349, -1, 111, 112, -1, 111, 134, 985 226, 119, 135, 112, -1, 111, 134, 226, 135, 112, 986 -1, 111, 134, 226, 163, 135, 112, -1, 111, 134, 987 7, 225, 163, 135, 112, -1, 111, 134, 226, 7, 988 163, 135, 112, -1, 357, -1, 358, 311, -1, 359, 989 311, -1, 119, -1, 119, 226, -1, 119, 356, -1, 990 119, 226, 356, -1, 109, 357, 110, -1, 348, -1, 991 109, 357, 110, 348, -1, 109, 358, 110, 349, -1, 992 109, 358, 110, -1, 109, 357, 110, 109, 134, 263, 993 135, 110, -1, 109, 359, 110, -1, 361, -1, 369, 994 -1, 226, 369, -1, 362, -1, 363, -1, 119, 224, 995 -1, 226, 119, 224, -1, 119, 370, -1, 226, 119, 996 370, -1, 119, 360, -1, 226, 119, 360, -1, 111, 997 112, 224, -1, 364, 224, -1, 111, 112, 349, 224, 998 -1, 364, 349, 224, -1, 349, 224, -1, 111, 112, 999 362, -1, 364, 362, -1, 111, 112, 349, 362, -1, 1000 364, 349, 362, -1, 349, 362, -1, 111, 134, 226, 1001 119, 135, 112, -1, 111, 134, 226, 163, 135, 112, 1002 -1, 111, 134, 230, 163, 135, 112, -1, 111, 134, 1003 230, 226, 163, 135, 112, -1, 369, -1, 226, 369, 1004 -1, 366, -1, 367, -1, 368, -1, 119, 224, -1, 1005 226, 119, 224, -1, 119, 370, -1, 226, 119, 370, 1006 -1, 119, 365, -1, 226, 119, 365, -1, 111, 112, 1007 224, -1, 111, 112, 349, 224, -1, 349, 224, -1, 1008 111, 112, 367, -1, 111, 112, 349, 367, -1, 349, 1009 367, -1, 111, 134, 262, 135, 112, -1, 111, 112, 1010 109, 259, 110, -1, 369, 109, 134, 259, 135, 110, 1011 -1, 217, 109, 134, 259, 135, 110, -1, -1, 116, 1012 -1, -1, 131, 163, -1 1013 1013 }; 1014 1014 … … 1052 1052 1368, 1374, 1375, 1377, 1379, 1384, 1386, 1388, 1390, 1395, 1053 1053 1396, 1398, 1400, 1405, 1406, 1408, 1413, 1414, 1416, 1418, 1054 1423, 1425, 1427, 1432, 1433, 1437, 1439, 144 1, 1443, 1445,1055 1450, 145 2, 1457, 1459, 1464, 1465, 1467, 1468, 1473, 1474,1056 147 6, 1478, 1483, 1485, 1491, 1492, 1494, 1497, 1500, 1505,1057 15 06, 1511, 1516, 1520, 1522, 1524, 1529, 1531, 1537, 1538,1058 154 6, 1547, 1551, 1552, 1553, 1555, 1557, 1564, 1565, 1567,1059 15 69, 1574, 1575, 1581, 1582, 1586, 1587, 1592, 1593, 1594,1060 1 596, 1604, 1605, 1607, 1610, 1612, 1616, 1617, 1618, 1620,1061 162 2, 1626, 1631, 1639, 1640, 1649, 1651, 1656, 1657, 1658,1062 166 2, 1663, 1664, 1668, 1669, 1670, 1674, 1675, 1676, 1681,1063 168 2, 1683, 1684, 1690, 1691, 1693, 1698, 1699, 1704, 1705,1064 17 06, 1707, 1708, 1723, 1724, 1729, 1730, 1738, 1740, 1742,1065 17 45, 1747, 1749, 1772, 1773, 1775, 1777, 1782, 1783, 1785,1066 179 0, 1795, 1796, 1802, 1801, 1805, 1809, 1811, 1813, 1819,1067 182 0, 1825, 1830, 1832, 1837, 1839, 1840, 1842, 1847, 1849,1068 185 1, 1856, 1858, 1863, 1868, 1876, 1882, 1881, 1895, 1896,1069 190 1, 1902, 1906, 1911, 1916, 1924, 1929, 1940, 1941, 1952,1070 195 3, 1959, 1960, 1964, 1965, 1966, 1969, 1968, 1979, 1984,1071 1989, 199 5, 2004, 2010, 2016, 2022, 2028, 2036, 2042, 2050,1072 205 6, 2065, 2066, 2067, 2071, 2075, 2077, 2082, 2083, 2087,1073 20 88, 2093, 2099, 2100, 2103, 2105, 2106, 2110, 2111, 2112,1074 21 13, 2147, 2149, 2150, 2152, 2157, 2162, 2167, 2169, 2171,1075 217 6, 2178, 2180, 2182, 2187, 2189, 2199, 2201, 2202, 2207,1076 22 09, 2211, 2216, 2218, 2220, 2225, 2227, 2229, 2238, 2239,1077 224 0, 2244, 2246, 2248, 2253, 2255, 2257, 2262, 2264, 2266,1078 22 81, 2283, 2284, 2286, 2291, 2292, 2297, 2299, 2301, 2306,1079 23 08, 2310, 2312, 2317, 2319, 2321, 2331, 2333, 2334, 2336,1080 234 1, 2343, 2345, 2350, 2352, 2354, 2356, 2361, 2363, 2365,1081 23 96, 2398, 2399, 2401, 2406, 2411, 2419, 2421, 2423, 2428,1082 243 0, 2435, 2437, 2451, 2452, 2454, 2459, 2461, 2463, 2465,1083 24 67, 2472, 2473, 2475, 2477, 2482, 2484, 2486, 2492, 2494,1084 2 496, 2500, 2502, 2504, 2506, 2520, 2521, 2523, 2528, 2530,1085 253 2, 2534, 2536, 2541, 2542, 2544, 2546, 2551, 2553, 2555,1086 256 1, 2562, 2564, 2573, 2576, 2578, 2581, 2583, 2585, 2598,1087 259 9, 2601, 2606, 2608, 2610, 2612, 2614, 2619, 2620, 2622,1088 26 24, 2629, 2631, 2639, 2640, 2641, 2646, 2647, 2651, 2653,1089 26 55, 2657, 2659, 2661, 2668, 2670, 2672, 2674, 2676, 2678,1090 268 0, 2682, 2684, 2686, 2691, 2693, 2695, 2700, 2726, 2727,1091 27 29, 2733, 2734, 2738, 2740, 2742, 2744, 2746, 2748, 2755,1092 275 7, 2759, 2761, 2763, 2765, 2770, 2775, 2777, 2779, 2797,1093 27 99, 2804, 28051054 1423, 1425, 1427, 1432, 1433, 1437, 1439, 1445, 1444, 1448, 1055 1450, 1455, 1457, 1462, 1464, 1469, 1470, 1472, 1473, 1478, 1056 1479, 1481, 1483, 1488, 1490, 1496, 1497, 1499, 1502, 1505, 1057 1510, 1511, 1516, 1521, 1525, 1527, 1533, 1532, 1539, 1541, 1058 1547, 1548, 1556, 1557, 1561, 1562, 1563, 1565, 1567, 1574, 1059 1575, 1577, 1579, 1584, 1585, 1591, 1592, 1596, 1597, 1602, 1060 1603, 1604, 1606, 1614, 1615, 1617, 1620, 1622, 1626, 1627, 1061 1628, 1630, 1632, 1636, 1641, 1649, 1650, 1659, 1661, 1666, 1062 1667, 1668, 1672, 1673, 1674, 1678, 1679, 1680, 1684, 1685, 1063 1686, 1691, 1692, 1693, 1694, 1700, 1701, 1703, 1708, 1709, 1064 1714, 1715, 1716, 1717, 1718, 1733, 1734, 1739, 1740, 1748, 1065 1750, 1752, 1755, 1757, 1759, 1782, 1783, 1785, 1787, 1792, 1066 1793, 1795, 1800, 1805, 1806, 1812, 1811, 1815, 1819, 1821, 1067 1823, 1829, 1830, 1835, 1840, 1842, 1847, 1849, 1850, 1852, 1068 1857, 1859, 1861, 1866, 1868, 1873, 1878, 1886, 1892, 1891, 1069 1905, 1906, 1911, 1912, 1916, 1921, 1926, 1934, 1939, 1950, 1070 1951, 1962, 1963, 1969, 1970, 1974, 1975, 1976, 1979, 1978, 1071 1989, 1994, 1999, 2005, 2014, 2020, 2026, 2032, 2038, 2046, 1072 2052, 2060, 2066, 2075, 2076, 2077, 2081, 2085, 2087, 2092, 1073 2093, 2097, 2098, 2103, 2109, 2110, 2113, 2115, 2116, 2120, 1074 2121, 2122, 2123, 2157, 2159, 2160, 2162, 2167, 2172, 2177, 1075 2179, 2181, 2186, 2188, 2190, 2192, 2197, 2199, 2209, 2211, 1076 2212, 2217, 2219, 2221, 2226, 2228, 2230, 2235, 2237, 2239, 1077 2248, 2249, 2250, 2254, 2256, 2258, 2263, 2265, 2267, 2272, 1078 2274, 2276, 2291, 2293, 2294, 2296, 2301, 2302, 2307, 2309, 1079 2311, 2316, 2318, 2320, 2322, 2327, 2329, 2331, 2341, 2343, 1080 2344, 2346, 2351, 2353, 2355, 2360, 2362, 2364, 2366, 2371, 1081 2373, 2375, 2406, 2408, 2409, 2411, 2416, 2421, 2429, 2431, 1082 2433, 2438, 2440, 2445, 2447, 2461, 2462, 2464, 2469, 2471, 1083 2473, 2475, 2477, 2482, 2483, 2485, 2487, 2492, 2494, 2496, 1084 2502, 2504, 2506, 2510, 2512, 2514, 2516, 2530, 2531, 2533, 1085 2538, 2540, 2542, 2544, 2546, 2551, 2552, 2554, 2556, 2561, 1086 2563, 2565, 2571, 2572, 2574, 2583, 2586, 2588, 2591, 2593, 1087 2595, 2608, 2609, 2611, 2616, 2618, 2620, 2622, 2624, 2629, 1088 2630, 2632, 2634, 2639, 2641, 2649, 2650, 2651, 2656, 2657, 1089 2661, 2663, 2665, 2667, 2669, 2671, 2678, 2680, 2682, 2684, 1090 2686, 2688, 2690, 2692, 2694, 2696, 2701, 2703, 2705, 2710, 1091 2736, 2737, 2739, 2743, 2744, 2748, 2750, 2752, 2754, 2756, 1092 2758, 2765, 2767, 2769, 2771, 2773, 2775, 2780, 2785, 2787, 1093 2789, 2807, 2809, 2814, 2815 1094 1094 }; 1095 1095 #endif … … 1156 1156 "sue_declaration_specifier", "sue_type_specifier", 1157 1157 "typedef_declaration_specifier", "typedef_type_specifier", 1158 "elaborated_type_name", "aggregate_name", " aggregate_key",1158 "elaborated_type_name", "aggregate_name", "$@2", "aggregate_key", 1159 1159 "field_declaration_list", "field_declaration", 1160 1160 "new_field_declaring_list", "field_declaring_list", "field_declarator", 1161 1161 "bit_subrange_size_opt", "bit_subrange_size", "enum_key", "enum_name", 1162 " enumerator_list", "enumerator_value_opt", "new_parameter_type_list_opt",1163 "new_parameter_type_list ", "new_parameter_list",1164 "new_ abstract_parameter_list", "parameter_type_list_opt",1165 "parameter_type_list ", "parameter_list", "new_parameter_declaration",1166 "new_ abstract_parameter_declaration", "parameter_declaration",1167 " abstract_parameter_declaration", "identifier_list",1168 "identifier_ or_type_name", "no_01_identifier_or_type_name",1169 "no_ attr_identifier_or_type_name", "type_name_no_function", "type_name",1170 " initializer_opt", "initializer", "initializer_list", "designation",1171 " designator_list", "designator", "typegen_declaration_specifier",1172 "typegen_ type_specifier", "typegen_name", "type_parameter_list",1173 "type _parameter", "$@2", "type_class", "assertion_list_opt", "assertion",1174 "type_ name_list", "type_declaring_list", "type_declarator",1175 "type_declar ator_name", "trait_specifier", "$@3",1176 "trait_ declaration_list", "trait_declaration",1162 "$@3", "enumerator_list", "enumerator_value_opt", 1163 "new_parameter_type_list_opt", "new_parameter_type_list", 1164 "new_parameter_list", "new_abstract_parameter_list", 1165 "parameter_type_list_opt", "parameter_type_list", "parameter_list", 1166 "new_parameter_declaration", "new_abstract_parameter_declaration", 1167 "parameter_declaration", "abstract_parameter_declaration", 1168 "identifier_list", "identifier_or_type_name", 1169 "no_01_identifier_or_type_name", "no_attr_identifier_or_type_name", 1170 "type_name_no_function", "type_name", "initializer_opt", "initializer", 1171 "initializer_list", "designation", "designator_list", "designator", 1172 "typegen_declaration_specifier", "typegen_type_specifier", 1173 "typegen_name", "type_parameter_list", "type_parameter", "$@4", 1174 "type_class", "assertion_list_opt", "assertion", "type_name_list", 1175 "type_declaring_list", "type_declarator", "type_declarator_name", 1176 "trait_specifier", "$@5", "trait_declaration_list", "trait_declaration", 1177 1177 "new_trait_declaring_list", "trait_declaring_list", "translation_unit", 1178 1178 "external_definition_list", "external_definition_list_opt", 1179 "external_definition", "$@ 4", "external_function_definition",1179 "external_definition", "$@6", "external_function_definition", 1180 1180 "function_definition", "declarator", "subrange", "asm_name_opt", 1181 1181 "attribute_list_opt", "attribute_list", "attribute", … … 1269 1269 236, 237, 237, 237, 237, 238, 238, 238, 238, 239, 1270 1270 239, 239, 239, 240, 240, 240, 241, 241, 241, 241, 1271 242, 242, 242, 243, 243, 244, 244, 24 4, 244, 244,1272 24 5, 245, 246, 246, 247, 247, 247, 247, 248, 248,1273 24 8, 248, 249, 249, 250, 250, 250, 250, 250, 251,1274 25 1, 252, 253, 254, 254, 254, 255, 255, 256, 256,1275 25 7, 257, 258, 258, 258, 258, 258, 259, 259, 259,1276 2 59, 260, 260, 261, 261, 262, 262, 263, 263, 263,1277 26 3, 264, 264, 264, 264, 264, 265, 265, 265, 265,1278 26 5, 266, 266, 267, 267, 268, 268, 269, 269, 269,1279 27 0, 270, 270, 271, 271, 271, 272, 272, 272, 273,1280 27 3, 273, 273, 274, 274, 274, 275, 275, 276, 276,1281 27 6, 276, 276, 277, 277, 278, 278, 279, 279, 279,1282 2 79, 279, 279, 280, 280, 280, 280, 281, 281, 281,1283 28 2, 283, 283, 285, 284, 284, 286, 286, 286, 287,1284 28 7, 288, 288, 288, 289, 289, 289, 289, 290, 290,1285 29 0, 291, 291, 292, 292, 293, 294, 293, 295, 295,1286 29 6, 296, 297, 297, 297, 298, 298, 299, 299, 300,1287 30 0, 301, 301, 302, 302, 302, 303, 302, 302, 304,1288 304, 30 4, 305, 305, 305, 305, 305, 305, 305, 305,1289 30 5, 306, 306, 306, 307, 308, 308, 309, 309, 310,1290 31 0, 311, 312, 312, 313, 313, 313, 314, 314, 314,1291 31 4, 315, 315, 315, 315, 316, 316, 317, 317, 317,1292 31 8, 318, 318, 318, 319, 319, 320, 320, 320, 321,1293 32 1, 321, 322, 322, 322, 323, 323, 323, 324, 324,1294 32 4, 325, 325, 325, 326, 326, 326, 327, 327, 327,1295 32 8, 328, 328, 328, 329, 329, 330, 330, 330, 331,1296 33 1, 331, 331, 332, 332, 332, 333, 333, 333, 333,1297 33 4, 334, 334, 335, 335, 335, 335, 336, 336, 336,1298 33 7, 337, 337, 337, 338, 338, 339, 339, 339, 340,1299 34 0, 341, 341, 342, 342, 342, 343, 343, 343, 343,1300 34 3, 344, 344, 344, 344, 345, 345, 345, 346, 346,1301 34 6, 347, 347, 347, 347, 348, 348, 348, 349, 349,1302 3 49, 349, 349, 350, 350, 350, 350, 351, 351, 351,1303 35 2, 352, 352, 353, 353, 353, 353, 353, 353, 354,1304 35 4, 354, 355, 355, 355, 355, 355, 356, 356, 356,1305 35 6, 357, 357, 358, 358, 358, 359, 359, 360, 360,1306 36 0, 360, 360, 360, 361, 361, 361, 361, 361, 361,1307 36 1, 361, 361, 361, 362, 362, 362, 362, 363, 363,1308 36 3, 364, 364, 365, 365, 365, 365, 365, 365, 366,1309 36 6, 366, 366, 366, 366, 367, 368, 368, 368, 369,1310 3 69, 370, 3701271 242, 242, 242, 243, 243, 244, 244, 245, 244, 244, 1272 244, 246, 246, 247, 247, 248, 248, 248, 248, 249, 1273 249, 249, 249, 250, 250, 251, 251, 251, 251, 251, 1274 252, 252, 253, 254, 255, 255, 256, 255, 257, 257, 1275 258, 258, 259, 259, 260, 260, 260, 260, 260, 261, 1276 261, 261, 261, 262, 262, 263, 263, 264, 264, 265, 1277 265, 265, 265, 266, 266, 266, 266, 266, 267, 267, 1278 267, 267, 267, 268, 268, 269, 269, 270, 270, 271, 1279 271, 271, 272, 272, 272, 273, 273, 273, 274, 274, 1280 274, 275, 275, 275, 275, 276, 276, 276, 277, 277, 1281 278, 278, 278, 278, 278, 279, 279, 280, 280, 281, 1282 281, 281, 281, 281, 281, 282, 282, 282, 282, 283, 1283 283, 283, 284, 285, 285, 287, 286, 286, 288, 288, 1284 288, 289, 289, 290, 290, 290, 291, 291, 291, 291, 1285 292, 292, 292, 293, 293, 294, 294, 295, 296, 295, 1286 297, 297, 298, 298, 299, 299, 299, 300, 300, 301, 1287 301, 302, 302, 303, 303, 304, 304, 304, 305, 304, 1288 304, 306, 306, 306, 307, 307, 307, 307, 307, 307, 1289 307, 307, 307, 308, 308, 308, 309, 310, 310, 311, 1290 311, 312, 312,&nbs