Changes in / [036dd5f:aeec6b7]


Ignore:
Files:
15 edited

Legend:

Unmodified
Added
Removed
  • Jenkins/FullBuild

    r036dd5f raeec6b7  
    2121                                        gcc_5_x64: { trigger_build( 'gcc-5',   'x64', false ) },
    2222                                        gcc_5_x86: { trigger_build( 'gcc-5',   'x86', false ) },
    23                                         gcc_4_x64: { trigger_build( 'gcc-4.9', 'x64', false ) },
    24                                         gcc_4_x86: { trigger_build( 'gcc-4.9', 'x86', false ) },
    2523                                        clang_x64: { trigger_build( 'clang',   'x64', false ) },
    2624                                        clang_x86: { trigger_build( 'clang',   'x86', false ) },
  • doc/LaTeXmacros/common.tex

    r036dd5f raeec6b7  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Mon Mar 19 17:18:23 2018
    14 %% Update Count     : 379
     13%% Last Modified On : Mon Jul  9 08:28:05 2018
     14%% Update Count     : 380
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    5555\setlength{\parindentlnth}{\parindent}
    5656
     57\newcommand{\LstBasicStyle}[1]{{\lst@basicstyle{#1}}}
    5758\newcommand{\LstKeywordStyle}[1]{{\lst@basicstyle{\lst@keywordstyle{#1}}}}
    5859\newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}}
  • doc/papers/general/.gitignore

    r036dd5f raeec6b7  
    44*.ps
    55
    6 Paper.tex.plain
    76mail
    87Paper.out.ps
  • doc/papers/general/Paper.tex

    r036dd5f raeec6b7  
    226226The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from hobby projects to commercial operating-systems.
    227227This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more.
    228 The TIOBE~\cite{TIOBE} ranks the top 5 most \emph{popular} programming languages as: Java 15\%, \Textbf{C 12\%}, \Textbf{\CC 5.5\%}, Python 5\%, \Csharp 4.5\% = 42\%, where the next 50 languages are less than 4\% each with a long tail.
     228The TIOBE index~\cite{TIOBE} ranks the top 5 most \emph{popular} programming languages as: Java 15\%, \Textbf{C 12\%}, \Textbf{\CC 5.5\%}, Python 5\%, \Csharp 4.5\% = 42\%, where the next 50 languages are less than 4\% each, with a long tail.
    229229The top 3 rankings over the past 30 years are:
    230230\begin{center}
     
    250250(4) Extensions introduced by \CFA must be translated in the most efficient way possible.
    251251These goals ensure existing C code-bases can be converted to \CFA incrementally with minimal effort, and C programmers can productively generate \CFA code without training beyond the features being used.
    252 \CC is used similarly, but has the disadvantages of multiple legacy design-choices that cannot be updated and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project.
     252\CC is used similarly, but has the disadvantages of multiple legacy design-choices that cannot be updated, and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project.
    253253
    254254All languages features discussed in this paper are working, except some advanced exception-handling features.
     
    10961096
    10971097
    1098 \subsection{\texorpdfstring{\protect\lstinline{if} Statement}{if Statement}}
     1098\subsection{\texorpdfstring{\protect\lstinline@if@ Statement}{if Statement}}
    10991099
    11001100The @if@ expression allows declarations, similar to @for@ declaration expression:
     
    11081108
    11091109
    1110 \subsection{\texorpdfstring{\protect\lstinline{switch} Statement}{switch Statement}}
     1110\subsection{\texorpdfstring{\protect\lstinline@switch@ Statement}{switch Statement}}
    11111111
    11121112There are a number of deficiencies with the C @switch@ statements: enumerating @case@ lists, placement of @case@ clauses, scope of the switch body, and fall through between case clauses.
     
    12631263
    12641264
    1265 \subsection{\texorpdfstring{Labelled \protect\lstinline{continue} / \protect\lstinline{break}}{Labelled continue / break}}
     1265\subsection{\texorpdfstring{Labelled \protect\lstinline@continue@ / \protect\lstinline@break@}{Labelled continue / break}}
    12661266
    12671267While C provides @continue@ and @break@ statements for altering control flow, both are restricted to one level of nesting for a particular control structure.
  • doc/user/user.tex

    r036dd5f raeec6b7  
    1111%% Created On       : Wed Apr  6 14:53:29 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Sun May  6 10:33:53 2018
    14 %% Update Count     : 3319
     13%% Last Modified On : Mon Jul  9 10:49:52 2018
     14%% Update Count     : 3361
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    146146\CFA adds many modern programming-language features that directly lead to increased \emph{\Index{safety}} and \emph{\Index{productivity}}, while maintaining interoperability with existing C programs and achieving similar performance.
    147147Like C, \CFA is a statically typed, procedural (non-\Index{object-oriented}) language with a low-overhead runtime, meaning there is no global \Index{garbage-collection}, but \Index{regional garbage-collection}\index{garbage-collection!regional} is possible.
    148 The primary new features include parametric-polymorphic routines and types, exceptions, concurrency, and modules.
     148The primary new features include polymorphic routines and types, exceptions, concurrency, and modules.
    149149
    150150One of the main design philosophies of \CFA is to ``\Index{describe not prescribe}'', which means \CFA tries to provide a pathway from low-level C programming to high-level \CFA programming, but it does not force programmers to ``do the right thing''.
     
    155155As well, new programs can be written in \CFA using a combination of C and \CFA features.
    156156
    157 \Index*[C++]{\CC{}} had a similar goal 30 years ago, allowing object-oriented programming to be incrementally added to C.
    158 However, \CC currently has the disadvantages of a strong object-oriented bias, multiple legacy design-choices that cannot be updated, and active divergence of the language model from C, all of which requires significant effort and training to incrementally add \CC to a C-based project.
     157\Index*[C++]{\CC{}}~\cite{c++:v1} had a similar goal 30 years ago, allowing object-oriented programming to be incrementally added to C.
     158However, \CC currently has the disadvantages of a strong object-oriented bias, multiple legacy design-choices that cannot be updated, and active divergence of the language model from C, requiring significant effort and training to incrementally add \CC to a C-based project.
    159159In contrast, \CFA has 30 years of hindsight and a clean starting point.
    160160
    161161Like \Index*[C++]{\CC{}}, there may be both an old and new ways to achieve the same effect.
    162 For example, the following programs compare the \CFA, C, and \CC I/O mechanisms, where the programs output the same result.
    163 \begin{cquote}
     162For example, the following programs compare the C, \CFA, and \CC I/O mechanisms, where the programs output the same result.
     163\begin{center}
    164164\begin{tabular}{@{}l@{\hspace{1.5em}}l@{\hspace{1.5em}}l@{}}
    165165\multicolumn{1}{c@{\hspace{1.5em}}}{\textbf{C}} & \multicolumn{1}{c}{\textbf{\CFA}}     & \multicolumn{1}{c}{\textbf{\CC}}      \\
     
    191191\end{cfa}
    192192\end{tabular}
    193 \end{cquote}
     193\end{center}
    194194While the \CFA I/O looks similar to the \Index*[C++]{\CC{}} output style, there are important differences, such as automatic spacing between variables as in \Index*{Python} (see~\VRef{s:IOLibrary}).
    195195
     
    197197
    198198This document is a programmer reference-manual for the \CFA programming language.
    199 The manual covers the core features of the language and runtime-system, with simple examples illustrating syntax and semantics of each feature.
     199The manual covers the core features of the language and runtime-system, with simple examples illustrating syntax and semantics of features.
    200200The manual does not teach programming, \ie how to combine the new constructs to build complex programs.
    201 A reader should already have an intermediate knowledge of control flow, data structures, and concurrency issues to understand the ideas presented, as well as some experience programming in C/\CC.
     201The reader must have an intermediate knowledge of control flow, data structures, and concurrency issues to understand the ideas presented, as well as some experience programming in C/\CC.
    202202Implementers should refer to the \CFA Programming Language Specification for details about the language syntax and semantics.
    203203Changes to the syntax and additional features are expected to be included in later revisions.
     
    206206\section{Why fix C?}
    207207
    208 The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from commercial operating-systems (especially UNIX systems) to hobby projects.
     208The C programming language is a foundational technology for modern computing with millions of lines of code implementing everything from hobby projects to commercial operating-systems.
    209209This installation base and the programmers producing it represent a massive software-engineering investment spanning decades and likely to continue for decades more.
    210210Even with all its problems, C continues to be popular because it allows writing software at virtually any level in a computer system without restriction.
    211211For system programming, where direct access to hardware, storage management, and real-time issues are a requirement, C is usually the only language of choice.
    212 The TIOBE index~\cite{TIOBE} for March 2016 showed the following programming-language popularity: \Index*{Java} 20.5\%, C 14.5\%, \Index*[C++]{\CC{}} 6.7\%, \Csharp 4.3\%, \Index*{Python} 4.3\%, where the next 50 languages are less than 3\% each with a long tail.
    213 As well, for 30 years, C has been the number 1 and 2 most popular programming language:
     212The TIOBE index~\cite{TIOBE} for July 2018 ranks the top 5 most \emph{popular} programming languages as: \Index*{Java} 16\%, C 14\%, \Index*[C++]{\CC{}} 7.5\%, Python 6\%, Visual Basic 4\% = 47.5\%, where the next 50 languages are less than 4\% each, with a long tail.
     213The top 3 rankings over the past 30 years are:
    214214\begin{center}
    215 \setlength{\tabcolsep}{1.5ex}
    216 \begin{tabular}{@{}r|c|c|c|c|c|c|c@{}}
    217 Ranking & 2016  & 2011  & 2006  & 2001  & 1996  & 1991  & 1986          \\
    218 \hline
    219 Java    & 1             & 1             & 1             & 3             & 29    & -             & -                     \\
    220 \hline
    221 \R{C}   & \R{2} & \R{2} & \R{2} & \R{1} & \R{1} & \R{1} & \R{1}         \\
    222 \hline
    223 \CC             & 3             & 3             & 3             & 2             & 2             & 2             & 7                     \\
     215\setlength{\tabcolsep}{10pt}
     216\begin{tabular}{@{}rccccccc@{}}
     217                & 2018  & 2013  & 2008  & 2003  & 1998  & 1993  & 1988  \\ \hline
     218Java    & 1             & 2             & 1             & 1             & 16    & -             & -             \\
     219\R{C}   & \R{2} & \R{1} & \R{2} & \R{2} & \R{1} & \R{1} & \R{1} \\
     220\CC             & 3             & 4             & 3             & 3             & 2             & 2             & 5             \\
    224221\end{tabular}
    225222\end{center}
    226223Hence, C is still an extremely important programming language, with double the usage of \Index*[C++]{\CC{}}; in many cases, \CC is often used solely as a better C.
    227224Love it or hate it, C has been an important and influential part of computer science for 40 years and its appeal is not diminishing.
    228 Unfortunately, C has many problems and omissions that make it an unacceptable programming language for modern needs.
     225Nevertheless, C has many problems and omissions that make it an unacceptable programming language for modern needs.
    229226
    230227As stated, the goal of the \CFA project is to engineer modern language-features into C in an evolutionary rather than revolutionary way.
     
    236233These languages have different syntax and semantics from C, do not interoperate directly with C, and are not systems languages because of restrictive memory-management or garbage collection.
    237234As a result, there is a significant learning curve to move to these languages, and C legacy-code must be rewritten.
    238 These costs can be prohibitive for many companies with a large software-base in C/\CC, and a significant number of programmers require retraining to the new programming language.
    239 
    240 The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fixes many of the well known C problems while containing modern language-features.
    241 Without significant extension to the C programming language, it is becoming unable to cope with the needs of modern programming problems and programmers;
     235These costs can be prohibitive for many companies with a large software-base in C/\CC, and a significant number of programmers require retraining in the new programming language.
     236
     237The result of this project is a language that is largely backwards compatible with \Index*[C11]{\Celeven{}}~\cite{C11}, but fixes many of the well known C problems while adding modern language-features.
     238To achieve these goals required a significant engineering exercise, where we had to ``think inside the existing C box''.
     239Without these significant extension to C, it is unable to cope with the needs of modern programming problems and programmers;
    242240as a result, it will fade into disuse.
    243241Considering the large body of existing C code and programmers, there is significant impetus to ensure C is transformed into a modern programming language.
     
    255253\begin{lstlisting}
    256254®forall( otype T )® T identity( T val ) { return val; }
    257 int forty_two = identity( 42 );                 §\C{// T is bound to int, forty\_two == 42}§
     255int forty_two = identity( 42 );                         §\C{// T is bound to int, forty\_two == 42}§
    258256\end{lstlisting}
    259257% extending the C type system with parametric polymorphism and overloading, as opposed to the \Index*[C++]{\CC{}} approach of object-oriented extensions.
     
    307305\begin{lstlisting}
    308306forall( dtype T | sized(T) ) T * malloc( void ) { return (T *)malloc( sizeof(T) ); }
    309 int * ip = malloc();                                    §\C{// select type and size from left-hand side}§
     307int * ip = malloc();                                            §\C{// select type and size from left-hand side}§
    310308double * dp = malloc();
    311309struct S {...} * sp = malloc();
     
    318316Whereas, \CFA wraps each of these routines into ones with the overloaded name ©abs©:
    319317\begin{cfa}
    320 char abs( char );
    321 ®extern "C" {® int abs( int ); ®}®              §\C{// use default C routine for int}§
    322 long int abs( long int );
    323 long long int abs( long long int );
    324 float abs( float );
    325 double abs( double );
    326 long double abs( long double );
    327 float _Complex abs( float _Complex );
    328 double _Complex abs( double _Complex );
    329 long double _Complex abs( long double _Complex );
     318char ®abs®( char );
     319extern "C" { int ®abs®( int ); }                        §\C{// use default C routine for int}§
     320long int ®abs®( long int );
     321long long int ®abs®( long long int );
     322float ®abs®( float );
     323double ®abs®( double );
     324long double ®abs®( long double );
     325float _Complex ®abs®( float _Complex );
     326double _Complex ®abs®( double _Complex );
     327long double _Complex ®abs®( long double _Complex );
    330328\end{cfa}
    331329The problem is the name clash between the library routine ©abs© and the \CFA names ©abs©.
    332330Hence, names appearing in an ©extern "C"© block have \newterm*{C linkage}.
    333331Then overloading polymorphism uses a mechanism called \newterm{name mangling}\index{mangling!name} to create unique names that are different from C names, which are not mangled.
    334 Hence, there is the same need as in \CC, to know if a name is a C or \CFA name, so it can be correctly formed.
    335 There is no way around this problem, other than C's approach of creating unique names for each pairing of operation and type.
     332Hence, there is the same need, as in \CC, to know if a name is a C or \CFA name, so it can be correctly formed.
     333There is no way around this problem, other than C's approach of creating unique names for each pairing of operation and types.
    336334
    337335This example strongly illustrates a core idea in \CFA: \emph{the \Index{power of a name}}.
     
    350348\begin{description}
    351349\item
    352 \Indexc{-std=gnu99}\index{compilation option!-std=gnu99@{©-std=gnu99©}}
    353 The 1999 C standard plus GNU extensions.
     350\Indexc{-std=gnu11}\index{compilation option!-std=gnu11@{©-std=gnu11©}}
     351The 2011 C standard plus GNU extensions.
    354352\item
    355353\Indexc[deletekeywords=inline]{-fgnu89-inline}\index{compilation option!-fgnu89-inline@{\lstinline[deletekeywords=inline]@-fgnu89-inline@}}
    356 Use the traditional GNU semantics for inline routines in C99 mode, which allows inline routines in header files.
     354Use the traditional GNU semantics for inline routines in C11 mode, which allows inline routines in header files.
    357355\end{description}
    358356The following new \CFA options are available:
     
    427425\begin{cfa}
    428426#ifndef __CFORALL__
    429 #include <stdio.h>§\indexc{stdio.h}§    §\C{// C header file}§
     427#include <stdio.h>§\indexc{stdio.h}§            §\C{// C header file}§
    430428#else
    431 #include <fstream>§\indexc{fstream}§    §\C{// \CFA header file}§
     429#include <fstream>§\indexc{fstream}§            §\C{// \CFA header file}§
    432430#endif
    433431\end{cfa}
     
    435433
    436434
     435\section{Backquote Identifiers}
     436\label{s:BackquoteIdentifiers}
     437
     438\CFA introduces several new keywords (see \VRef{s:CFAKeywords}) that can clash with existing C variable-names in legacy code.
     439Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism:
     440\begin{cfa}
     441int ®`®otype®`® = 3;                                            §\C{// make keyword an identifier}§
     442double ®`®forall®`® = 3.5;
     443\end{cfa}
     444
     445Existing C programs with keyword clashes can be converted by enclosing keyword identifiers in backquotes, and eventually the identifier name can be changed to a non-keyword name.
     446\VRef[Figure]{f:HeaderFileInterposition} shows how clashes in existing C header-files (see~\VRef{s:StandardHeaders}) can be handled using preprocessor \newterm{interposition}: ©#include_next© and ©-I filename©.
     447Several common C header-files with keyword clashes are fixed in the standard \CFA header-library, so there is a seamless programming-experience.
     448
     449\begin{figure}
     450\begin{cfa}
     451// include file uses the CFA keyword "with".
     452#if ! defined( with )                                           §\C{// nesting ?}§
     453#define with ®`®with®`®                                         §\C{// make keyword an identifier}§
     454#define __CFA_BFD_H__
     455#endif
     456
     457®#include_next <bfdlink.h>                                      §\C{// must have internal check for multiple expansion}§
     458®
     459#if defined( with ) && defined( __CFA_BFD_H__ ) §\C{// reset only if set}§
     460#undef with
     461#undef __CFA_BFD_H__
     462#endif
     463\end{cfa}
     464\caption{Header-File Interposition}
     465\label{f:HeaderFileInterposition}
     466\end{figure}
     467
     468
    437469\section{Constant Underscores}
    438470
    439471Numeric constants are extended to allow \Index{underscore}s\index{constant!underscore}, \eg:
    440472\begin{cfa}
    441 2®_®147®_®483®_®648;                                    §\C{// decimal constant}§
    442 56®_®ul;                                                                §\C{// decimal unsigned long constant}§
    443 0®_®377;                                                                §\C{// octal constant}§
    444 0x®_®ff®_®ff;                                                   §\C{// hexadecimal constant}§
    445 0x®_®ef3d®_®aa5c;                                               §\C{// hexadecimal constant}§
    446 3.141®_®592®_®654;                                              §\C{// floating constant}§
    447 10®_®e®_®+1®_®00;                                               §\C{// floating constant}§
    448 0x®_®ff®_®ff®_®p®_®3;                                   §\C{// hexadecimal floating}§
    449 0x®_®1.ffff®_®ffff®_®p®_®128®_®l;               §\C{// hexadecimal floating long constant}§
     4732®_®147®_®483®_®648;                                            §\C{// decimal constant}§
     47456®_®ul;                                                                        §\C{// decimal unsigned long constant}§
     4750®_®377;                                                                        §\C{// octal constant}§
     4760x®_®ff®_®ff;                                                           §\C{// hexadecimal constant}§
     4770x®_®ef3d®_®aa5c;                                                       §\C{// hexadecimal constant}§
     4783.141®_®592®_®654;                                                      §\C{// floating constant}§
     47910®_®e®_®+1®_®00;                                                       §\C{// floating constant}§
     4800x®_®ff®_®ff®_®p®_®3;                                           §\C{// hexadecimal floating}§
     4810x®_®1.ffff®_®ffff®_®p®_®128®_®l;                       §\C{// hexadecimal floating long constant}§
    450482L®_®§"\texttt{\textbackslash{x}}§®_®§\texttt{ff}§®_®§\texttt{ee}"§;     §\C{// wide character constant}§
    451483\end{cfa}
     
    469501
    470502
    471 \section{Backquote Identifiers}
    472 \label{s:BackquoteIdentifiers}
    473 
    474 \CFA introduces several new keywords (see \VRef{s:CFAKeywords}) that can clash with existing C variable-names in legacy code.
    475 Keyword clashes are accommodated by syntactic transformations using the \CFA backquote escape-mechanism:
    476 \begin{cfa}
    477 int ®`®otype®`® = 3;                    §\C{// make keyword an identifier}§
    478 double ®`®forall®`® = 3.5;
    479 \end{cfa}
    480 
    481 Existing C programs with keyword clashes can be converted by enclosing keyword identifiers in backquotes, and eventually the identifier name can be changed to a non-keyword name.
    482 \VRef[Figure]{f:HeaderFileInterposition} shows how clashes in existing C header-files (see~\VRef{s:StandardHeaders}) can be handled using preprocessor \newterm{interposition}: ©#include_next© and ©-I filename©.
    483 Several common C header-files with keyword clashes are fixed in the standard \CFA header-library, so there is a seamless programming-experience.
    484 
    485 \begin{figure}
    486 \begin{cfa}
    487 // include file uses the CFA keyword "with".
    488 #if ! defined( with )                   §\C{// nesting ?}§
    489 #define with ®`®with®`®                 §\C{// make keyword an identifier}§
    490 #define __CFA_BFD_H__
    491 #endif
    492 
    493 ®#include_next <bfdlink.h>              §\C{// must have internal check for multiple expansion}§
    494 ®
    495 #if defined( with ) && defined( __CFA_BFD_H__ ) §\C{// reset only if set}§
    496 #undef with
    497 #undef __CFA_BFD_H__
    498 #endif
    499 \end{cfa}
    500 \caption{Header-File Interposition}
    501 \label{f:HeaderFileInterposition}
    502 \end{figure}
    503 
    504 
    505503\section{Exponentiation Operator}
    506504
     
    518516256 64 -64 0.015625 -0.015625 18.3791736799526 0.264715-1.1922i
    519517\end{cfa}
    520 Parenthesis are necessary for the complex constants or the expresion is parsed as ©1.0f+(2.0fi \ 3.0f)+2.0fi©.
     518Parenthesis are necessary for the complex constants or the expression is parsed as ©1.0f+(2.0fi \ 3.0f)+2.0fi©.
    521519The exponentiation operator is available for all the basic types, but for user-defined types, only the integral-computation versions are available.
    522520For returning an integral value, the user type ©T© must define multiplication, ©*©, and one, ©1©;
     
    524522
    525523
    526 \section{\texorpdfstring{Labelled \protect\lstinline@continue@ / \protect\lstinline@break@}{Labelled continue / break}}
     524\section{Control Structures}
     525
     526\CFA identifies inconsistent, problematic, and missing control structures in C, and extends, modifies, and adds control structures to increase functionality and safety.
     527
     528
     529%\subsection{\texorpdfstring{\protect\lstinline@if@ Statement}{if Statement}}
     530\subsection{\texorpdfstring{\LstKeywordStyle{if} Statement}{if Statement}}
     531
     532The ©if© expression allows declarations, similar to ©for© declaration expression:
     533\begin{cfa}
     534if ( int x = f() ) ...                                          §\C{// x != 0}§
     535if ( int x = f(), y = g() ) ...                         §\C{// x != 0 \&\& y != 0}§
     536if ( int x = f(), y = g(); ®x < y® ) ...        §\C{// relational expression}§
     537\end{cfa}
     538Unless a relational expression is specified, each variable is compared not equal to 0, which is the standard semantics for the ©if© expression, and the results are combined using the logical ©&&© operator.\footnote{\CC only provides a single declaration always compared not equal to 0.}
     539The scope of the declaration(s) is local to the @if@ statement but exist within both the ``then'' and ``else'' clauses.
     540
     541
     542%\section{\texorpdfstring{\protect\lstinline@switch@ Statement}{switch Statement}}
     543\subsection{\texorpdfstring{\LstKeywordStyle{switch} Statement}{switch Statement}}
     544
     545C allows a number of questionable forms for the ©switch© statement:
     546\begin{enumerate}
     547\item
     548By default, the end of a ©case© clause\footnote{
     549In this section, the term \emph{case clause} refers to either a ©case© or ©default© clause.}
     550\emph{falls through} to the next ©case© clause in the ©switch© statement;
     551to exit a ©switch© statement from a ©case© clause requires explicitly terminating the clause with a transfer statement, most commonly ©break©:
     552\begin{cfa}
     553switch ( i ) {
     554  case 1:
     555        ...
     556        // fall-through
     557  case 2:
     558        ...
     559        break;  // exit switch statement
     560}
     561\end{cfa}
     562The ability to fall-through to the next clause \emph{is} a useful form of control flow, specifically when a sequence of case actions compound:
     563\begin{cquote}
     564\begin{tabular}{@{}l@{\hspace{3em}}l@{}}
     565\begin{cfa}
     566switch ( argc ) {
     567  case 3:
     568        // open output file
     569        // fall-through
     570  case 2:
     571        // open input file
     572        break;  // exit switch statement
     573  default:
     574        // usage message
     575}
     576\end{cfa}
     577&
     578\begin{cfa}
     579
     580if ( argc == 3 ) {
     581        // open output file
     582        ®// open input file
     583®} else if ( argc == 2 ) {
     584        ®// open input file (duplicate)
     585
     586®} else {
     587        // usage message
     588}
     589\end{cfa}
     590\end{tabular}
     591\end{cquote}
     592In this example, case 2 is always done if case 3 is done.
     593This control flow is difficult to simulate with if statements or a ©switch© statement without fall-through as code must be duplicated or placed in a separate routine.
     594C also uses fall-through to handle multiple case-values resulting in the same action:
     595\begin{cfa}
     596switch ( i ) {
     597  ®case 1: case 3: case 5:®     // odd values
     598        // odd action
     599        break;
     600  ®case 2: case 4: case 6:®     // even values
     601        // even action
     602        break;
     603}
     604\end{cfa}
     605However, this situation is handled in other languages without fall-through by allowing a list of case values.
     606While fall-through itself is not a problem, the problem occurs when fall-through is the default, as this semantics is unintuitive to many programmers and is different from virtually all other programming languages with a ©switch© statement.
     607Hence, default fall-through semantics results in a large number of programming errors as programmers often \emph{forget} the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through.
     608
     609\item
     610It is possible to place ©case© clauses on statements nested \emph{within} the body of the ©switch© statement:
     611\begin{cfa}
     612switch ( i ) {
     613  case 0:
     614        if ( j < k ) {
     615                ...
     616          ®case 1:®             // transfer into "if" statement
     617                ...
     618        } // if
     619  case 2:
     620        while ( j < 5 ) {
     621                ...
     622          ®case 3:®             // transfer into "while" statement
     623                ...
     624        } // while
     625} // switch
     626\end{cfa}
     627The problem with this usage is branching into control structures, which is known to cause both comprehension and technical difficulties.
     628The comprehension problem occurs from the inability to determine how control reaches a particular point due to the number of branches leading to it.
     629The technical problem results from the inability to ensure declaration and initialization of variables when blocks are not entered at the beginning.
     630There are no positive arguments for this kind of control flow, and therefore, there is a strong impetus to eliminate it.
     631Nevertheless, C does have an idiom where this capability is used, known as ``\Index*{Duff's device}''~\cite{Duff83}:
     632\begin{cfa}
     633register int n = (count + 7) / 8;
     634switch ( count % 8 ) {
     635case 0: do{ *to = *from++;
     636case 7:         *to = *from++;
     637case 6:         *to = *from++;
     638case 5:         *to = *from++;
     639case 4:         *to = *from++;
     640case 3:         *to = *from++;
     641case 2:         *to = *from++;
     642case 1:         *to = *from++;
     643                } while ( --n > 0 );
     644}
     645\end{cfa}
     646which unrolls a loop N times (N = 8 above) and uses the ©switch© statement to deal with any iterations not a multiple of N.
     647While efficient, this sort of special purpose usage is questionable:
     648\begin{quote}
     649Disgusting, no? But it compiles and runs just fine. I feel a combination of pride and revulsion at this
     650discovery.~\cite{Duff83}
     651\end{quote}
     652\item
     653It is possible to place the ©default© clause anywhere in the list of labelled clauses for a ©switch© statement, rather than only at the end.
     654Virtually all programming languages with a ©switch© statement require the ©default© clause to appear last in the case-clause list.
     655The logic for this semantics is that after checking all the ©case© clauses without success, the ©default© clause is selected;
     656hence, physically placing the ©default© clause at the end of the ©case© clause list matches with this semantics.
     657This physical placement can be compared to the physical placement of an ©else© clause at the end of a series of connected ©if©/©else© statements.
     658
     659\item
     660It is possible to place unreachable code at the start of a ©switch© statement, as in:
     661\begin{cfa}
     662switch ( x ) {
     663        ®int y = 1;®                                                    §\C{// unreachable initialization}§
     664        ®x = 7;®                                                                §\C{// unreachable code without label/branch}§
     665  case 0: ...
     666        ...
     667        ®int z = 0;®                                                    §\C{// unreachable initialization, cannot appear after case}§
     668        z = 2;
     669  case 1:
     670        ®x = z;®                                                                §\C{// without fall through, z is uninitialized}§
     671}
     672\end{cfa}
     673While the declaration of the local variable ©y© is useful with a scope across all ©case© clauses, the initialization for such a variable is defined to never be executed because control always transfers over it.
     674Furthermore, any statements before the first ©case© clause can only be executed if labelled and transferred to using a ©goto©, either from outside or inside of the ©switch©, both of which are problematic.
     675As well, the declaration of ©z© cannot occur after the ©case© because a label can only be attached to a statement, and without a fall through to case 3, ©z© is uninitialized.
     676The key observation is that the ©switch© statement branches into control structure, \ie there are multiple entry points into its statement body.
     677\end{enumerate}
     678
     679Before discussing potential language changes to deal with these problems, it is worth observing that in a typical C program:
     680\begin{itemize}
     681\item
     682the number of ©switch© statements is small,
     683\item
     684most ©switch© statements are well formed (\ie no \Index*{Duff's device}),
     685\item
     686the ©default© clause is usually written as the last case-clause,
     687\item
     688and there is only a medium amount of fall-through from one ©case© clause to the next, and most of these result from a list of case values executing common code, rather than a sequence of case actions that compound.
     689\end{itemize}
     690These observations put into perspective the \CFA changes to the ©switch©.
     691\begin{enumerate}
     692\item
     693Eliminating default fall-through has the greatest potential for affecting existing code.
     694However, even if fall-through is removed, most ©switch© statements would continue to work because of the explicit transfers already present at the end of each ©case© clause, the common placement of the ©default© clause at the end of the case list, and the most common use of fall-through, \ie a list of ©case© clauses executing common code, \eg:
     695\begin{cfa}
     696case 1:  case 2:  case 3: ...
     697\end{cfa}
     698still works.
     699Nevertheless, reversing the default action would have a non-trivial effect on case actions that compound, such as the above example of processing shell arguments.
     700Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called ©choose©, with no implicit fall-through semantics and an explicit fall-through if the last statement of a case-clause ends with the new keyword ©fallthrough©/©fallthru©, \eg:
     701\begin{cfa}
     702®choose® ( i ) {
     703  case 1:  case 2:  case 3:
     704        ...
     705        ®// implicit end of switch (break)
     706  ®case 5:
     707        ...
     708        ®fallthru®;                                                             §\C{// explicit fall through}§
     709  case 7:
     710        ...
     711        ®break®                                                                 §\C{// explicit end of switch (redundant)}§
     712  default:
     713        j = 3;
     714}
     715\end{cfa}
     716Like the ©switch© statement, the ©choose© statement retains the fall-through semantics for a list of ©case© clauses;
     717An implicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause.
     718An explicit ©fallthru© is retained because it is a C-idiom most C programmers expect, and its absence might discourage programmers from using the ©choose© statement.
     719As well, allowing an explicit ©break© from the ©choose© is a carry over from the ©switch© statement, and expected by C programmers.
     720\item
     721\Index*{Duff's device} is eliminated from both ©switch© and ©choose© statements, and only invalidates a small amount of very questionable code.
     722Hence, the ©case© clause must appear at the same nesting level as the ©switch©/©choose© body, as is done in most other programming languages with ©switch© statements.
     723\item
     724The issue of ©default© at locations other than at the end of the cause clause can be solved by using good programming style, and there are a few reasonable situations involving fall-through where the ©default© clause needs to appear is locations other than at the end.
     725Therefore, no change is made for this issue.
     726\item
     727Dealing with unreachable code in a ©switch©/©choose© body is solved by restricting declarations and associated initialization to the start of statement body, which is executed \emph{before} the transfer to the appropriate ©case© clause\footnote{
     728Essentially, these declarations are hoisted before the ©switch©/©choose© statement and both declarations and statement are surrounded by a compound statement.} and precluding statements before the first ©case© clause.
     729Further declarations at the same nesting level as the statement body are disallowed to ensure every transfer into the body is sound.
     730\begin{cfa}
     731switch ( x ) {
     732        ®int i = 0;®                                                    §\C{// allowed only at start}§
     733  case 0:
     734        ...
     735        ®int j = 0;®                                                    §\C{// disallowed}§
     736  case 1:
     737        {
     738                ®int k = 0;®                                            §\C{// allowed at different nesting levels}§
     739                ...
     740          ®case 2:®                                                             §\C{// disallow case in nested statements}§
     741        }
     742  ...
     743}
     744\end{cfa}
     745\end{enumerate}
     746
     747
     748%\section{\texorpdfstring{\protect\lstinline@case@ Clause}{case Clause}}
     749\subsection{\texorpdfstring{\LstKeywordStyle{case} Statement}{case Statement}}
     750
     751C restricts the ©case© clause of a ©switch© statement to a single value.
     752For multiple ©case© clauses associated with the same statement, it is necessary to have multiple ©case© clauses rather than multiple values.
     753Requiring a ©case© clause for each value does not seem to be in the spirit of brevity normally associated with C.
     754Therefore, the ©case© clause is extended with a list of values, as in:
     755\begin{cquote}
     756\begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}}
     757\multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}} \\
     758\begin{cfa}
     759switch ( i ) {
     760  case ®1, 3, 5®:
     761        ...
     762  case ®2, 4, 6®:
     763        ...
     764}
     765\end{cfa}
     766&
     767\begin{cfa}
     768switch ( i ) {
     769  case 1: case 3 : case 5:
     770        ...
     771  case 2: case 4 : case 6:
     772        ...
     773}
     774\end{cfa}
     775&
     776\begin{cfa}
     777
     778// odd values
     779
     780// even values
     781
     782
     783\end{cfa}
     784\end{tabular}
     785\end{cquote}
     786In addition, subranges are allowed to specify case values.\footnote{
     787gcc has the same mechanism but awkward syntax, \lstinline@2 ...42@, because a space is required after a number, otherwise the period is a decimal point.}
     788\begin{cfa}
     789switch ( i ) {
     790  case ®1~5:®                                   §\C{// 1, 2, 3, 4, 5}§
     791        ...
     792  case ®10~15:®                                 §\C{// 10, 11, 12, 13, 14, 15}§
     793        ...
     794}
     795\end{cfa}
     796Lists of subranges are also allowed.
     797\begin{cfa}
     798case ®1~5, 12~21, 35~42®:
     799\end{cfa}
     800
     801
     802%\subsection{\texorpdfstring{Labelled \protect\lstinline@continue@ / \protect\lstinline@break@}{Labelled continue / break}}
     803\subsection{\texorpdfstring{Labelled \LstKeywordStyle{continue} / \LstKeywordStyle{break} Statement}{Labelled continue / break Statement}}
    527804
    528805While C provides ©continue© and ©break© statements for altering control flow, both are restricted to one level of nesting for a particular control structure.
     
    626903With ©goto©, the label is at the end of the control structure, which fails to convey this important clue early enough to the reader.
    627904Finally, using an explicit target for the transfer instead of an implicit target allows new constructs to be added or removed without affecting existing constructs.
    628 The implicit targets of the current ©continue© and ©break©, \ie the closest enclosing loop or ©switch©, change as certain constructs are added or removed.
    629 
    630 
    631 \section{\texorpdfstring{\protect\lstinline@switch@ Statement}{switch Statement}}
    632 
    633 C allows a number of questionable forms for the ©switch© statement:
    634 \begin{enumerate}
    635 \item
    636 By default, the end of a ©case© clause\footnote{
    637 In this section, the term \emph{case clause} refers to either a ©case© or ©default© clause.}
    638 \emph{falls through} to the next ©case© clause in the ©switch© statement;
    639 to exit a ©switch© statement from a ©case© clause requires explicitly terminating the clause with a transfer statement, most commonly ©break©:
    640 \begin{cfa}
    641 switch ( i ) {
    642   case 1:
    643         ...
    644         // fall-through
    645   case 2:
    646         ...
    647         break;  // exit switch statement
    648 }
    649 \end{cfa}
    650 The ability to fall-through to the next clause \emph{is} a useful form of control flow, specifically when a sequence of case actions compound:
    651 \begin{cquote}
    652 \begin{tabular}{@{}l@{\hspace{3em}}l@{}}
    653 \begin{cfa}
    654 switch ( argc ) {
    655   case 3:
    656         // open output file
    657         // fall-through
    658   case 2:
    659         // open input file
    660         break;  // exit switch statement
    661   default:
    662         // usage message
    663 }
    664 \end{cfa}
    665 &
    666 \begin{cfa}
    667 
    668 if ( argc == 3 ) {
    669         // open output file
    670         ®// open input file
    671 ®} else if ( argc == 2 ) {
    672         ®// open input file (duplicate)
    673 
    674 ®} else {
    675         // usage message
    676 }
    677 \end{cfa}
    678 \end{tabular}
    679 \end{cquote}
    680 In this example, case 2 is always done if case 3 is done.
    681 This control flow is difficult to simulate with if statements or a ©switch© statement without fall-through as code must be duplicated or placed in a separate routine.
    682 C also uses fall-through to handle multiple case-values resulting in the same action:
    683 \begin{cfa}
    684 switch ( i ) {
    685   ®case 1: case 3: case 5:®     // odd values
    686         // odd action
    687         break;
    688   ®case 2: case 4: case 6:®     // even values
    689         // even action
    690         break;
    691 }
    692 \end{cfa}
    693 However, this situation is handled in other languages without fall-through by allowing a list of case values.
    694 While fall-through itself is not a problem, the problem occurs when fall-through is the default, as this semantics is unintuitive to many programmers and is different from virtually all other programming languages with a ©switch© statement.
    695 Hence, default fall-through semantics results in a large number of programming errors as programmers often \emph{forget} the ©break© statement at the end of a ©case© clause, resulting in inadvertent fall-through.
    696 
    697 \item
    698 It is possible to place ©case© clauses on statements nested \emph{within} the body of the ©switch© statement:
    699 \begin{cfa}
    700 switch ( i ) {
    701   case 0:
    702         if ( j < k ) {
    703                 ...
    704           ®case 1:®             // transfer into "if" statement
    705                 ...
    706         } // if
    707   case 2:
    708         while ( j < 5 ) {
    709                 ...
    710           ®case 3:®             // transfer into "while" statement
    711                 ...
    712         } // while
    713 } // switch
    714 \end{cfa}
    715 The problem with this usage is branching into control structures, which is known to cause both comprehension and technical difficulties.
    716 The comprehension problem occurs from the inability to determine how control reaches a particular point due to the number of branches leading to it.
    717 The technical problem results from the inability to ensure declaration and initialization of variables when blocks are not entered at the beginning.
    718 There are no positive arguments for this kind of control flow, and therefore, there is a strong impetus to eliminate it.
    719 Nevertheless, C does have an idiom where this capability is used, known as ``\Index*{Duff's device}''~\cite{Duff83}:
    720 \begin{cfa}
    721 register int n = (count + 7) / 8;
    722 switch ( count % 8 ) {
    723 case 0: do{ *to = *from++;
    724 case 7:         *to = *from++;
    725 case 6:         *to = *from++;
    726 case 5:         *to = *from++;
    727 case 4:         *to = *from++;
    728 case 3:         *to = *from++;
    729 case 2:         *to = *from++;
    730 case 1:         *to = *from++;
    731                 } while ( --n > 0 );
    732 }
    733 \end{cfa}
    734 which unrolls a loop N times (N = 8 above) and uses the ©switch© statement to deal with any iterations not a multiple of N.
    735 While efficient, this sort of special purpose usage is questionable:
    736 \begin{quote}
    737 Disgusting, no? But it compiles and runs just fine. I feel a combination of pride and revulsion at this
    738 discovery.~\cite{Duff83}
    739 \end{quote}
    740 \item
    741 It is possible to place the ©default© clause anywhere in the list of labelled clauses for a ©switch© statement, rather than only at the end.
    742 Virtually all programming languages with a ©switch© statement require the ©default© clause to appear last in the case-clause list.
    743 The logic for this semantics is that after checking all the ©case© clauses without success, the ©default© clause is selected;
    744 hence, physically placing the ©default© clause at the end of the ©case© clause list matches with this semantics.
    745 This physical placement can be compared to the physical placement of an ©else© clause at the end of a series of connected ©if©/©else© statements.
    746 
    747 \item
    748 It is possible to place unreachable code at the start of a ©switch© statement, as in:
    749 \begin{cfa}
    750 switch ( x ) {
    751         ®int y = 1;®                            §\C{// unreachable initialization}§
    752         ®x = 7;®                                        §\C{// unreachable code without label/branch}§
    753   case 0: ...
    754         ...
    755         ®int z = 0;®                            §\C{// unreachable initialization, cannot appear after case}§
    756         z = 2;
    757   case 1:
    758         ®x = z;®                                        §\C{// without fall through, z is uninitialized}§
    759 }
    760 \end{cfa}
    761 While the declaration of the local variable ©y© is useful with a scope across all ©case© clauses, the initialization for such a variable is defined to never be executed because control always transfers over it.
    762 Furthermore, any statements before the first ©case© clause can only be executed if labelled and transferred to using a ©goto©, either from outside or inside of the ©switch©, both of which are problematic.
    763 As well, the declaration of ©z© cannot occur after the ©case© because a label can only be attached to a statement, and without a fall through to case 3, ©z© is uninitialized.
    764 The key observation is that the ©switch© statement branches into control structure, \ie there are multiple entry points into its statement body.
    765 \end{enumerate}
    766 
    767 Before discussing potential language changes to deal with these problems, it is worth observing that in a typical C program:
    768 \begin{itemize}
    769 \item
    770 the number of ©switch© statements is small,
    771 \item
    772 most ©switch© statements are well formed (\ie no \Index*{Duff's device}),
    773 \item
    774 the ©default© clause is usually written as the last case-clause,
    775 \item
    776 and there is only a medium amount of fall-through from one ©case© clause to the next, and most of these result from a list of case values executing common code, rather than a sequence of case actions that compound.
    777 \end{itemize}
    778 These observations put into perspective the \CFA changes to the ©switch©.
    779 \begin{enumerate}
    780 \item
    781 Eliminating default fall-through has the greatest potential for affecting existing code.
    782 However, even if fall-through is removed, most ©switch© statements would continue to work because of the explicit transfers already present at the end of each ©case© clause, the common placement of the ©default© clause at the end of the case list, and the most common use of fall-through, \ie a list of ©case© clauses executing common code, \eg:
    783 \begin{cfa}
    784 case 1:  case 2:  case 3: ...
    785 \end{cfa}
    786 still works.
    787 Nevertheless, reversing the default action would have a non-trivial effect on case actions that compound, such as the above example of processing shell arguments.
    788 Therefore, to preserve backwards compatibility, it is necessary to introduce a new kind of ©switch© statement, called ©choose©, with no implicit fall-through semantics and an explicit fall-through if the last statement of a case-clause ends with the new keyword ©fallthrough©/©fallthru©, \eg:
    789 \begin{cfa}
    790 ®choose® ( i ) {
    791   case 1:  case 2:  case 3:
    792         ...
    793         ®// implicit end of switch (break)
    794   ®case 5:
    795         ...
    796         ®fallthru®;                                     §\C{// explicit fall through}§
    797   case 7:
    798         ...
    799         ®break®                                         §\C{// explicit end of switch (redundant)}§
    800   default:
    801         j = 3;
    802 }
    803 \end{cfa}
    804 Like the ©switch© statement, the ©choose© statement retains the fall-through semantics for a list of ©case© clauses;
    805 An implicit ©break© is applied only at the end of the \emph{statements} following a ©case© clause.
    806 An explicit ©fallthru© is retained because it is a C-idiom most C programmers expect, and its absence might discourage programmers from using the ©choose© statement.
    807 As well, allowing an explicit ©break© from the ©choose© is a carry over from the ©switch© statement, and expected by C programmers.
    808 \item
    809 \Index*{Duff's device} is eliminated from both ©switch© and ©choose© statements, and only invalidates a small amount of very questionable code.
    810 Hence, the ©case© clause must appear at the same nesting level as the ©switch©/©choose© body, as is done in most other programming languages with ©switch© statements.
    811 \item
    812 The issue of ©default© at locations other than at the end of the cause clause can be solved by using good programming style, and there are a few reasonable situations involving fall-through where the ©default© clause needs to appear is locations other than at the end.
    813 Therefore, no change is made for this issue.
    814 \item
    815 Dealing with unreachable code in a ©switch©/©choose© body is solved by restricting declarations and associated initialization to the start of statement body, which is executed \emph{before} the transfer to the appropriate ©case© clause\footnote{
    816 Essentially, these declarations are hoisted before the ©switch©/©choose© statement and both declarations and statement are surrounded by a compound statement.} and precluding statements before the first ©case© clause.
    817 Further declarations at the same nesting level as the statement body are disallowed to ensure every transfer into the body is sound.
    818 \begin{cfa}
    819 switch ( x ) {
    820         ®int i = 0;®                            §\C{// allowed only at start}§
    821   case 0:
    822         ...
    823         ®int j = 0;®                            §\C{// disallowed}§
    824   case 1:
    825         {
    826                 ®int k = 0;®                    §\C{// allowed at different nesting levels}§
    827                 ...
    828           ®case 2:®                                     §\C{// disallow case in nested statements}§
    829         }
    830   ...
    831 }
    832 \end{cfa}
    833 \end{enumerate}
    834 
    835 
    836 \section{\texorpdfstring{\protect\lstinline@case@ Clause}{case Clause}}
    837 
    838 C restricts the ©case© clause of a ©switch© statement to a single value.
    839 For multiple ©case© clauses associated with the same statement, it is necessary to have multiple ©case© clauses rather than multiple values.
    840 Requiring a ©case© clause for each value does not seem to be in the spirit of brevity normally associated with C.
    841 Therefore, the ©case© clause is extended with a list of values, as in:
    842 \begin{cquote}
    843 \begin{tabular}{@{}l@{\hspace{3em}}l@{\hspace{2em}}l@{}}
    844 \multicolumn{1}{c@{\hspace{3em}}}{\textbf{\CFA}}        & \multicolumn{1}{c@{\hspace{2em}}}{\textbf{C}} \\
    845 \begin{cfa}
    846 switch ( i ) {
    847   case ®1, 3, 5®:
    848         ...
    849   case ®2, 4, 6®:
    850         ...
    851 }
    852 \end{cfa}
    853 &
    854 \begin{cfa}
    855 switch ( i ) {
    856   case 1: case 3 : case 5:
    857         ...
    858   case 2: case 4 : case 6:
    859         ...
    860 }
    861 \end{cfa}
    862 &
    863 \begin{cfa}
    864 
    865 // odd values
    866 
    867 // even values
    868 
    869 
    870 \end{cfa}
    871 \end{tabular}
    872 \end{cquote}
    873 In addition, subranges are allowed to specify case values.\footnote{
    874 gcc has the same mechanism but awkward syntax, \lstinline@2 ...42@, because a space is required after a number, otherwise the period is a decimal point.}
    875 \begin{cfa}
    876 switch ( i ) {
    877   case ®1~5:®                                   §\C{// 1, 2, 3, 4, 5}§
    878         ...
    879   case ®10~15:®                                 §\C{// 10, 11, 12, 13, 14, 15}§
    880         ...
    881 }
    882 \end{cfa}
    883 Lists of subranges are also allowed.
    884 \begin{cfa}
    885 case ®1~5, 12~21, 35~42®:
    886 \end{cfa}
    887 
    888 
    889 \section{\texorpdfstring{\protect\lstinline@with@ Statement}{with Statement}}
     905Otherwise, the implicit targets of the current ©continue© and ©break©, \ie the closest enclosing loop or ©switch©, change as certain constructs are added or removed.
     906
     907
     908%\section{\texorpdfstring{\protect\lstinline@with@ Statement}{with Statement}}
     909\section{\texorpdfstring{\LstKeywordStyle{with} Statement}{with Statement}}
    890910\label{s:WithStatement}
    891911
     
    902922\begin{cfa}
    903923void f( S s ) {
    904         `s.`c; `s.`i; `s.`d;                                    §\C{// access containing fields}§
     924        ®s.®c; ®s.®i; ®s.®d;                                    §\C{// access containing fields}§
    905925}
    906926\end{cfa}
     
    913933        double d;
    914934        void f() {                                                              §\C{// implicit ``this'' aggregate}§
    915                 `this->`c; `this->`i; `this->`d;        §\C{// access containing fields}§
     935                ®this->®c; ®this->®i; ®this->®d;        §\C{// access containing fields}§
    916936        }
    917937}
    918938\end{C++}
    919 Object-oriented nesting of member functions in a \lstinline[language=C++]@class/struct@ allows eliding \lstinline[language=C++]$this->$ because of lexical scoping.
     939Object-oriented nesting of member functions in a \lstinline[language=C++]@class/struct@ allows eliding \lstinline[language=C++]@this->@ because of lexical scoping.
    920940However, for other aggregate parameters, qualification is necessary:
    921941\begin{cfa}
     
    923943int S::f( T & t ) {                                                     §\C{// multiple aggregate parameters}§
    924944        c; i; d;                                                                §\C{\color{red}// this--{\textgreater}.c, this--{\textgreater}.i, this--{\textgreater}.d}§
    925         `t.`m; `t.`n;                                                   §\C{// must qualify}§
    926 }
    927 \end{cfa}
    928 
    929 To simplify the programmer experience, \CFA provides a @with@ statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate qualification to fields by opening a scope containing the field identifiers.
     945        ®t.®m; ®t.®n;                                                   §\C{// must qualify}§
     946}
     947\end{cfa}
     948
     949To simplify the programmer experience, \CFA provides a ©with© statement (see Pascal~\cite[\S~4.F]{Pascal}) to elide aggregate qualification to fields by opening a scope containing the field identifiers.
    930950Hence, the qualified fields become variables with the side-effect that it is easier to optimizing field references in a block.
    931951\begin{cfa}
    932 void f( S & this ) `with ( this )` {            §\C{// with statement}§
     952void f( S & this ) ®with ( this )® {            §\C{// with statement}§
    933953        c; i; d;                                                                §\C{\color{red}// this.c, this.i, this.d}§
    934954}
     
    936956with the generality of opening multiple aggregate-parameters:
    937957\begin{cfa}
    938 void f( S & s, T & t ) `with ( s, t )` {                §\C{// multiple aggregate parameters}§
     958void f( S & s, T & t ) ®with ( s, t )® {        §\C{// multiple aggregate parameters}§
    939959        c; i; d;                                                                §\C{\color{red}// s.c, s.i, s.d}§
    940960        m; n;                                                                   §\C{\color{red}// t.m, t.n}§
     
    942962\end{cfa}
    943963
    944 In detail, the @with@ statement has the form:
     964In detail, the ©with© statement has the form:
    945965\begin{cfa}
    946966§\emph{with-statement}§:
     
    957977The difference between parallel and nesting occurs for fields with the same name and type:
    958978\begin{cfa}
    959 struct S { int `i`; int j; double m; } s, w;
    960 struct T { int `i`; int k; int m; } t, w;
     979struct S { int ®i®; int j; double m; } s, w;
     980struct T { int ®i®; int k; int m; } t, w;
    961981with ( s, t ) {
    962982        j + k;                                                                  §\C{// unambiguous, s.j + t.k}§
     
    969989}
    970990\end{cfa}
    971 For parallel semantics, both @s.i@ and @t.i@ are visible, so @i@ is ambiguous without qualification;
    972 for nested semantics, @t.i@ hides @s.i@, so @i@ implies @t.i@.
     991For parallel semantics, both ©s.i© and ©t.i© are visible, so ©i© is ambiguous without qualification;
     992for nested semantics, ©t.i© hides ©s.i©, so ©i© implies ©t.i©.
    973993\CFA's ability to overload variables means fields with the same name but different types are automatically disambiguated, eliminating most qualification when opening multiple aggregates.
    974994Qualification or a cast is used to disambiguate.
    975995
    976 There is an interesting problem between parameters and the function-body @with@, \eg:
     996There is an interesting problem between parameters and the function-body ©with©, \eg:
    977997\begin{cfa}
    978998void ?{}( S & s, int i ) with ( s ) {           §\C{// constructor}§
    979         `s.i = i;`  j = 3;  m = 5.5;                    §\C{// initialize fields}§
    980 }
    981 \end{cfa}
    982 Here, the assignment @s.i = i@ means @s.i = s.i@, which is meaningless, and there is no mechanism to qualify the parameter @i@, making the assignment impossible using the function-body @with@.
     999        ®s.i = i;®  j = 3;  m = 5.5;                    §\C{// initialize fields}§
     1000}
     1001\end{cfa}
     1002Here, the assignment ©s.i = i© means ©s.i = s.i©, which is meaningless, and there is no mechanism to qualify the parameter ©i©, making the assignment impossible using the function-body ©with©.
    9831003To solve this problem, parameters are treated like an initialized aggregate:
    9841004\begin{cfa}
     
    9901010and implicitly opened \emph{after} a function-body open, to give them higher priority:
    9911011\begin{cfa}
    992 void ?{}( S & s, int `i` ) with ( s ) `with( §\emph{\color{red}params}§ )` {
    993         s.i = `i`; j = 3; m = 5.5;
    994 }
    995 \end{cfa}
    996 Finally, a cast may be used to disambiguate among overload variables in a @with@ expression:
     1012void ?{}( S & s, int ®i® ) with ( s ) ®with( §\emph{\color{red}params}§ )® {
     1013        s.i = ®i®; j = 3; m = 5.5;
     1014}
     1015\end{cfa}
     1016Finally, a cast may be used to disambiguate among overload variables in a ©with© expression:
    9971017\begin{cfa}
    9981018with ( w ) { ... }                                                      §\C{// ambiguous, same name and no context}§
    9991019with ( (S)w ) { ... }                                           §\C{// unambiguous, cast}§
    10001020\end{cfa}
    1001 and @with@ expressions may be complex expressions with type reference (see Section~\ref{s:References}) to aggregate:
     1021and ©with© expressions may be complex expressions with type reference (see Section~\ref{s:References}) to aggregate:
    10021022% \begin{cfa}
    10031023% struct S { int i, j; } sv;
     
    10191039class C {
    10201040        int i, j;
    1021         int mem() {                                     §\C{\color{red}// implicit "this" parameter}§
    1022                 i = 1;                                  §\C{\color{red}// this->i}§
    1023                 j = 2;                                  §\C{\color{red}// this->j}§
     1041        int mem() {                                                             §\C{\color{red}// implicit "this" parameter}§
     1042                i = 1;                                                          §\C{\color{red}// this->i}§
     1043                j = 2;                                                          §\C{\color{red}// this->j}§
    10241044        }
    10251045}
     
    10281048\begin{cfa}
    10291049struct S { int i, j; };
    1030 int mem( S & ®this® ) {                 §\C{// explicit "this" parameter}§
    1031         ®this.®i = 1;                           §\C{// "this" is not elided}§
     1050int mem( S & ®this® ) {                                         §\C{// explicit "this" parameter}§
     1051        ®this.®i = 1;                                                   §\C{// "this" is not elided}§
    10321052        ®this.®j = 2;
    10331053}
     
    10371057\CFA provides a ©with© clause/statement (see Pascal~\cite[\S~4.F]{Pascal}) to elided the "©this.©" by opening a scope containing field identifiers, changing the qualified fields into variables and giving an opportunity for optimizing qualified references.
    10381058\begin{cfa}
    1039 int mem( S & this ) ®with( this )® { §\C{// with clause}§
    1040         i = 1;                                          §\C{\color{red}// this.i}§
    1041         j = 2;                                          §\C{\color{red}// this.j}§
     1059int mem( S & this ) ®with( this )® {            §\C{// with clause}§
     1060        i = 1;                                                                  §\C{\color{red}// this.i}§
     1061        j = 2;                                                                  §\C{\color{red}// this.j}§
    10421062}
    10431063\end{cfa}
     
    10561076        struct S1 { ... } s1;
    10571077        struct S2 { ... } s2;
    1058         ®with( s1 )® {                          §\C{// with statement}§
     1078        ®with( s1 )® {                                                  §\C{// with statement}§
    10591079                // access fields of s1 without qualification
    1060                 ®with s2® {                             §\C{// nesting}§
     1080                ®with s2® {                                                     §\C{// nesting}§
    10611081                        // access fields of s1 and s2 without qualification
    10621082                }
     
    11131133Non-local transfer can cause stack unwinding, \ie non-local routine termination, depending on the kind of raise.
    11141134\begin{cfa}
    1115 exception_t E {};                               §\C{// exception type}§
     1135exception_t E {};                                                       §\C{// exception type}§
    11161136void f(...) {
    1117         ... throw E{}; ...                      §\C{// termination}§
    1118         ... throwResume E{}; ...        §\C{// resumption}§
     1137        ... throw E{}; ...                                              §\C{// termination}§
     1138        ... throwResume E{}; ...                                §\C{// resumption}§
    11191139}
    11201140try {
    11211141        f(...);
    1122 } catch( E e ; §boolean-predicate§ ) {                  §\C[8cm]{// termination handler}§
     1142} catch( E e ; §boolean-predicate§ ) {          §\C[8cm]{// termination handler}§
    11231143        // recover and continue
    1124 } catchResume( E e ; §boolean-predicate§ ) {    §\C{// resumption handler}\CRT§
     1144} catchResume( E e ; §boolean-predicate§ ) { §\C{// resumption handler}\CRT§
    11251145        // repair and return
    11261146} finally {
     
    16421662\begin{itemize}
    16431663\item
    1644 if ©R© is an \Index{rvalue} of type ©T &$_1$...&$_r$© where $r \ge 1$ references (©&© symbols) then ©&R© has type ©T ®*®&$_{\color{red}2}$...&$_{\color{red}r}$©, \ie ©T© pointer with $r-1$ references (©&© symbols).
    1645 
    1646 \item
    1647 if ©L© is an \Index{lvalue} of type ©T &$_1$...&$_l$© where $l \ge 0$ references (©&© symbols) then ©&L© has type ©T ®*®&$_{\color{red}1}$...&$_{\color{red}l}$©, \ie ©T© pointer with $l$ references (©&© symbols).
     1664if ©R© is an \Index{rvalue} of type ©T &©$_1\cdots$ ©&©$_r$, where $r \ge 1$ references (©&© symbols), than ©&R© has type ©T ®*®&©$_{\color{red}2}\cdots$ ©&©$_{\color{red}r}$, \ie ©T© pointer with $r-1$ references (©&© symbols).
     1665
     1666\item
     1667if ©L© is an \Index{lvalue} of type ©T &©$_1\cdots$ ©&©$_l$, where $l \ge 0$ references (©&© symbols), than ©&L© has type ©T ®*®&©$_{\color{red}1}\cdots$ ©&©$_{\color{red}l}$, \ie ©T© pointer with $l$ references (©&© symbols).
    16481668\end{itemize}
    16491669The following example shows the first rule applied to different \Index{rvalue} contexts:
     
    59996019
    60006020
    6001 \subsection{Conversion}
     6021\subsection{String to Value Conversion}
    60026022
    60036023\leavevmode
     
    60696089\leavevmode
    60706090\begin{cfa}[aboveskip=0pt,belowskip=0pt]
    6071 void rand48seed( long int s );§\indexc{rand48seed}§
    6072 char rand48();§\indexc{rand48}§
    6073 int rand48();
    6074 unsigned int rand48();
    6075 long int rand48();
    6076 unsigned long int rand48();
    6077 float rand48();
    6078 double rand48();
    6079 float _Complex rand48();
    6080 double _Complex rand48();
    6081 long double _Complex rand48();
     6091void srandom( unsigned int seed );§\indexc{srandom}§
     6092char random( void );§\indexc{random}§
     6093char random( char u );                                          §\C{// [0,u)}§
     6094char random( char l, char u );                          §\C{// [l,u)}§
     6095int random( void );
     6096int random( int u );                                            §\C{// [0,u)}§
     6097int random( int l, int u );                                     §\C{// [l,u)}§
     6098unsigned int random( void );
     6099unsigned int random( unsigned int u );          §\C{// [0,u)}§
     6100unsigned int random( unsigned int l, unsigned int u ); §\C{// [l,u)}§
     6101long int random( void );
     6102long int random( long int u );                          §\C{// [0,u)}§
     6103long int random( long int l, long int u );      §\C{// [l,u)}§
     6104unsigned long int random( void );
     6105unsigned long int random( unsigned long int u ); §\C{// [0,u)}§
     6106unsigned long int random( unsigned long int l, unsigned long int u ); §\C{// [l,u)}§
     6107float random( void );                                            §\C{// [0.0, 1.0)}§
     6108double random( void );                                           §\C{// [0.0, 1.0)}§
     6109float _Complex random( void );                           §\C{// [0.0, 1.0)+[0.0, 1.0)i}§
     6110double _Complex random( void );                          §\C{// [0.0, 1.0)+[0.0, 1.0)i}§
     6111long double _Complex random( void );             §\C{// [0.0, 1.0)+[0.0, 1.0)i}§
    60826112\end{cfa}
    60836113
     
    64586488
    64596489
    6460 \section{Time}
    6461 \label{s:TimeLib}
     6490\section{Time Keeping}
     6491\label{s:TimeKeeping}
    64626492
    64636493
    64646494%\subsection{\texorpdfstring{\protect\lstinline@Duration@}{Duration}}
    6465 \subsection{\texorpdfstring{\LstKeywordStyle{\textmd{Duration}}}{Duration}}
     6495\subsection{\texorpdfstring{\LstBasicStyle{Duration}}{Duration}}
    64666496\label{s:Duration}
    64676497
     
    65126542
    65136543Duration abs( Duration rhs );
    6514 
    6515 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Duration dur );
    65166544
    65176545Duration ?`ns( int64_t nsec );
     
    65376565int64_t ?`d( Duration dur );
    65386566int64_t ?`w( Duration dur );
     6567
     6568Duration max( Duration lhs, Duration rhs );
     6569Duration min( Duration lhs, Duration rhs );
    65396570\end{cfa}
    65406571
    65416572
    65426573%\subsection{\texorpdfstring{\protect\lstinline@\timeval@}{timeval}}
    6543 \subsection{\texorpdfstring{\LstKeywordStyle{\textmd{timeval}}}{timeval}}
     6574\subsection{\texorpdfstring{\LstBasicStyle{timeval}}{timeval}}
    65446575\label{s:timeval}
    65456576
     
    65606591
    65616592
    6562 \subsection{\texorpdfstring{\protect\lstinline@timespec@}{timespec}}
     6593%\subsection{\texorpdfstring{\protect\lstinline@timespec@}{timespec}}
     6594\subsection{\texorpdfstring{\LstBasicStyle{timespec}}{timespec}}
    65636595\label{s:timespec}
    65646596
     
    65796611
    65806612
    6581 \subsection{\texorpdfstring{\protect\lstinline@itimerval@}{itimerval}}
     6613%\subsection{\texorpdfstring{\protect\lstinline@itimerval@}{itimerval}}
     6614\subsection{\texorpdfstring{\LstBasicStyle{itimerval}}{itimerval}}
    65826615\label{s:itimerval}
    65836616
     
    65896622
    65906623
    6591 \subsection{\texorpdfstring{\protect\lstinline@Time@}{Time}}
     6624%\subsection{\texorpdfstring{\protect\lstinline@Time@}{Time}}
     6625\subsection{\texorpdfstring{\LstBasicStyle{Time}}{Time}}
    65926626\label{s:Time}
    65936627
     
    66006634void ?{}( Time & time );
    66016635void ?{}( Time & time, zero_t );
    6602 void ?{}( Time & time, int year, int month = 0, int day = 0, int hour = 0, int min = 0, int sec = 0, int nsec = 0 );
     6636
    66036637Time ?=?( Time & time, zero_t );
    66046638
     
    66096643Time ?=?( Time & time, timespec t );
    66106644
    6611 Time ?+?( Time & lhs, Duration rhs ) { return (Time)@{ lhs.tv + rhs.tv }; }
    6612 Time ?+?( Duration lhs, Time rhs ) { return rhs + lhs; }
    6613 Time ?+=?( Time & lhs, Duration rhs ) { lhs = lhs + rhs; return lhs; }
    6614 
    6615 Duration ?-?( Time lhs, Time rhs ) { return (Duration)@{ lhs.tv - rhs.tv }; }
    6616 Time ?-?( Time lhs, Duration rhs ) { return (Time)@{ lhs.tv - rhs.tv }; }
    6617 Time ?-=?( Time & lhs, Duration rhs ) { lhs = lhs - rhs; return lhs; }
    6618 _Bool ?==?( Time lhs, Time rhs ) { return lhs.tv == rhs.tv; }
    6619 _Bool ?!=?( Time lhs, Time rhs ) { return lhs.tv != rhs.tv; }
    6620 _Bool ?<?( Time lhs, Time rhs ) { return lhs.tv < rhs.tv; }
    6621 _Bool ?<=?( Time lhs, Time rhs ) { return lhs.tv <= rhs.tv; }
    6622 _Bool ?>?( Time lhs, Time rhs ) { return lhs.tv > rhs.tv; }
    6623 _Bool ?>=?( Time lhs, Time rhs ) { return lhs.tv >= rhs.tv; }
    6624 
    6625 forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Time time );
     6645Time ?+?( Time & lhs, Duration rhs );
     6646Time ?+?( Duration lhs, Time rhs );
     6647Time ?+=?( Time & lhs, Duration rhs );
     6648
     6649Duration ?-?( Time lhs, Time rhs );
     6650Time ?-?( Time lhs, Duration rhs );
     6651Time ?-=?( Time & lhs, Duration rhs );
     6652_Bool ?==?( Time lhs, Time rhs );
     6653_Bool ?!=?( Time lhs, Time rhs );
     6654_Bool ?<?( Time lhs, Time rhs );
     6655_Bool ?<=?( Time lhs, Time rhs );
     6656_Bool ?>?( Time lhs, Time rhs );
     6657_Bool ?>=?( Time lhs, Time rhs );
    66266658
    66276659char * yy_mm_dd( Time time, char * buf );
     
    66416673
    66426674size_t strftime( char * buf, size_t size, const char * fmt, Time time );
     6675forall( dtype ostype | ostream( ostype ) ) ostype & ?|?( ostype & os, Time time );
    66436676\end{cfa}
    66446677
     
    66616694
    66626695%\subsection{\texorpdfstring{\protect\lstinline@Clock@}{Clock}}
    6663 \subsection{\texorpdfstring{\LstKeywordStyle{\textmd{Clock}}}{Clock}}
     6696\subsection{\texorpdfstring{\LstBasicStyle{Clock}}{Clock}}
    66646697\label{s:Clock}
    66656698
     
    66756708void ?{}( Clock & clk );
    66766709void ?{}( Clock & clk, Duration adj );
    6677 Duration getRes();
     6710
     6711Duration getResNsec();                                  §\C{// with nanoseconds}§
     6712Duration getRes();                                              §\C{// without nanoseconds}§
     6713
    66786714Time getTimeNsec();                                             §\C{// with nanoseconds}§
    66796715Time getTime();                                                 §\C{// without nanoseconds}§
  • src/Common/ScopedMap.h

    r036dd5f raeec6b7  
    2222#include <vector>
    2323
     24/// Default (empty) ScopedMap note type
     25struct EmptyNote {};
     26
    2427/// A map where the items are placed into nested scopes;
    25 /// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward
    26 template<typename Key, typename Value>
     28/// inserted items are placed into the innermost scope, lookup looks from the innermost scope outward.
     29/// Scopes may be annotated with a value; the annotation defaults to empty
     30template<typename Key, typename Value, typename Note = EmptyNote>
    2731class ScopedMap {
    28         typedef std::map< Key, Value > Scope;
     32        typedef std::map< Key, Value > MapType;
     33        struct Scope {
     34                MapType map;
     35                Note note;
     36
     37                template<typename N>
     38                Scope(N&& n) : map(), note(std::forward<N>(n)) {}
     39               
     40                Scope() = default;
     41                Scope(const Scope&) = default;
     42                Scope(Scope&&) = default;
     43                Scope& operator= (const Scope&) = default;
     44                Scope& operator= (Scope&&) = default;
     45        };
    2946        typedef std::vector< Scope > ScopeList;
    3047
    3148        ScopeList scopes; ///< scoped list of maps
    3249public:
    33         typedef typename Scope::key_type key_type;
    34         typedef typename Scope::mapped_type mapped_type;
    35         typedef typename Scope::value_type value_type;
     50        typedef typename MapType::key_type key_type;
     51        typedef typename MapType::mapped_type mapped_type;
     52        typedef typename MapType::value_type value_type;
    3653        typedef typename ScopeList::size_type size_type;
    3754        typedef typename ScopeList::difference_type difference_type;
    38         typedef typename Scope::reference reference;
    39         typedef typename Scope::const_reference const_reference;
    40         typedef typename Scope::pointer pointer;
    41         typedef typename Scope::const_pointer const_pointer;
     55        typedef typename MapType::reference reference;
     56        typedef typename MapType::const_reference const_reference;
     57        typedef typename MapType::pointer pointer;
     58        typedef typename MapType::const_pointer const_pointer;
    4259
    4360        class iterator : public std::iterator< std::bidirectional_iterator_tag,
     
    4562        friend class ScopedMap;
    4663        friend class const_iterator;
    47                 typedef typename std::map< Key, Value >::iterator wrapped_iterator;
    48                 typedef typename std::vector< std::map< Key, Value > > scope_list;
     64                typedef typename ScopedMap::MapType::iterator wrapped_iterator;
     65                typedef typename ScopedMap::ScopeList scope_list;
    4966                typedef typename scope_list::size_type size_type;
    5067
    5168                /// Checks if this iterator points to a valid item
    5269                bool is_valid() const {
    53                         return it != (*scopes)[level].end();
     70                        return it != (*scopes)[level].map.end();
    5471                }
    5572
     
    7996
    8097                iterator& operator++ () {
    81                         if ( it == (*scopes)[level].end() ) {
     98                        if ( it == (*scopes)[level].map.end() ) {
    8299                                if ( level == 0 ) return *this;
    83100                                --level;
    84                                 it = (*scopes)[level].begin();
     101                                it = (*scopes)[level].map.begin();
    85102                        } else {
    86103                                ++it;
     
    92109                iterator& operator-- () {
    93110                        // may fail if this is the begin iterator; allowed by STL spec
    94                         if ( it == (*scopes)[level].begin() ) {
     111                        if ( it == (*scopes)[level].map.begin() ) {
    95112                                ++level;
    96                                 it = (*scopes)[level].end();
     113                                it = (*scopes)[level].map.end();
    97114                        }
    98115                        --it;
     
    107124
    108125                size_type get_level() const { return level; }
     126
     127                Note& get_note() { return (*scopes)[level].note; }
     128                const Note& get_note() const { return (*scopes)[level].note; }
    109129
    110130        private:
     
    117137                                                     value_type > {
    118138        friend class ScopedMap;
    119                 typedef typename std::map< Key, Value >::iterator wrapped_iterator;
    120                 typedef typename std::map< Key, Value >::const_iterator wrapped_const_iterator;
    121                 typedef typename std::vector< std::map< Key, Value > > scope_list;
     139                typedef typename ScopedMap::MapType::iterator wrapped_iterator;
     140                typedef typename ScopedMap::MapType::const_iterator wrapped_const_iterator;
     141                typedef typename ScopedMap::ScopeList scope_list;
    122142                typedef typename scope_list::size_type size_type;
    123143
    124144                /// Checks if this iterator points to a valid item
    125145                bool is_valid() const {
    126                         return it != (*scopes)[level].end();
     146                        return it != (*scopes)[level].map.end();
    127147                }
    128148
     
    157177
    158178                const_iterator& operator++ () {
    159                         if ( it == (*scopes)[level].end() ) {
     179                        if ( it == (*scopes)[level].map.end() ) {
    160180                                if ( level == 0 ) return *this;
    161181                                --level;
    162                                 it = (*scopes)[level].begin();
     182                                it = (*scopes)[level].map.begin();
    163183                        } else {
    164184                                ++it;
     
    170190                const_iterator& operator-- () {
    171191                        // may fail if this is the begin iterator; allowed by STL spec
    172                         if ( it == (*scopes)[level].begin() ) {
     192                        if ( it == (*scopes)[level].map.begin() ) {
    173193                                ++level;
    174                                 it = (*scopes)[level].end();
     194                                it = (*scopes)[level].map.end();
    175195                        }
    176196                        --it;
     
    185205
    186206                size_type get_level() const { return level; }
     207
     208                const Note& get_note() const { return (*scopes)[level].note; }
    187209
    188210        private:
     
    197219        }
    198220
     221        // Starts a new scope with the given note
     222        template<typename N>
     223        void beginScope( N&& n ) {
     224                scopes.emplace_back( std::forward<N>(n) );
     225        }
     226
    199227        /// Ends a scope; invalidates any iterators pointing to elements of that scope
    200228        void endScope() {
     
    204232
    205233        /// Default constructor initializes with one scope
    206         ScopedMap() { beginScope(); }
    207 
    208         iterator begin() { return iterator(scopes, scopes.back().begin(), currentScope()).next_valid(); }
    209         const_iterator begin() const { return const_iterator(scopes, scopes.back().begin(), currentScope()).next_valid(); }
    210         const_iterator cbegin() const { return const_iterator(scopes, scopes.back().begin(), currentScope()).next_valid(); }
    211         iterator end() { return iterator(scopes, scopes[0].end(), 0); }
    212         const_iterator end() const { return const_iterator(scopes, scopes[0].end(), 0); }
    213         const_iterator cend() const { return const_iterator(scopes, scopes[0].end(), 0); }
     234        ScopedMap() : scopes() { beginScope(); }
     235
     236        /// Constructs with a given note on the outermost scope
     237        template<typename N>
     238        ScopedMap( N&& n ) : scopes() { beginScope(std::forward<N>(n)); }
     239
     240        iterator begin() { return iterator(scopes, scopes.back().map.begin(), currentScope()).next_valid(); }
     241        const_iterator begin() const { return const_iterator(scopes, scopes.back().map.begin(), currentScope()).next_valid(); }
     242        const_iterator cbegin() const { return const_iterator(scopes, scopes.back().map.begin(), currentScope()).next_valid(); }
     243        iterator end() { return iterator(scopes, scopes[0].map.end(), 0); }
     244        const_iterator end() const { return const_iterator(scopes, scopes[0].map.end(), 0); }
     245        const_iterator cend() const { return const_iterator(scopes, scopes[0].map.end(), 0); }
    214246
    215247        /// Gets the index of the current scope (counted from 1)
    216248        size_type currentScope() const { return scopes.size() - 1; }
     249
     250        /// Gets the note at the given scope
     251        Note& getNote( size_type i ) { return scopes[i].note; }
     252        const Note& getNote( size_type i ) const { return scopes[i].note; }
    217253
    218254        /// Finds the given key in the outermost scope it occurs; returns end() for none such
    219255        iterator find( const Key &key ) {
    220256                for ( size_type i = scopes.size() - 1; ; --i ) {
    221                         typename Scope::iterator val = scopes[i].find( key );
    222                         if ( val != scopes[i].end() ) return iterator( scopes, val, i );
     257                        typename MapType::iterator val = scopes[i].map.find( key );
     258                        if ( val != scopes[i].map.end() ) return iterator( scopes, val, i );
    223259                        if ( i == 0 ) break;
    224260                }
     
    226262        }
    227263        const_iterator find( const Key &key ) const {
    228                         return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->find( key ) );
     264                        return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->find( key ) );
    229265        }
    230266
    231267        /// Finds the given key in the provided scope; returns end() for none such
    232268        iterator findAt( size_type scope, const Key& key ) {
    233                 typename Scope::iterator val = scopes[scope].find( key );
    234                 if ( val != scopes[scope].end() ) return iterator( scopes, val, scope );
     269                typename MapType::iterator val = scopes[scope].map.find( key );
     270                if ( val != scopes[scope].map.end() ) return iterator( scopes, val, scope );
    235271                return end();
    236272        }
    237273        const_iterator findAt( size_type scope, const Key& key ) const {
    238                 return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->findAt( scope, key ) );
     274                return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->findAt( scope, key ) );
    239275        }
    240276
     
    243279                if ( it.level == 0 ) return end();
    244280                for ( size_type i = it.level - 1; ; --i ) {
    245                         typename Scope::iterator val = scopes[i].find( key );
    246                         if ( val != scopes[i].end() ) return iterator( scopes, val, i );
     281                        typename MapType::iterator val = scopes[i].map.find( key );
     282                        if ( val != scopes[i].map.end() ) return iterator( scopes, val, i );
    247283                        if ( i == 0 ) break;
    248284                }
     
    250286        }
    251287        const_iterator findNext( const_iterator &it, const Key &key ) const {
    252                         return const_iterator( const_cast< ScopedMap< Key, Value >* >(this)->findNext( it, key ) );
     288                        return const_iterator( const_cast< ScopedMap< Key, Value, Note >* >(this)->findNext( it, key ) );
    253289        }
    254290
     
    256292        template< typename value_type_t >
    257293        std::pair< iterator, bool > insert( value_type_t&& value ) {
    258                 std::pair< typename Scope::iterator, bool > res = scopes.back().insert( std::forward<value_type_t>( value ) );
     294                std::pair< typename MapType::iterator, bool > res = scopes.back().map.insert( std::forward<value_type_t>( value ) );
    259295                return std::make_pair( iterator(scopes, std::move( res.first ), scopes.size()-1), std::move( res.second ) );
    260296        }
     
    262298        template< typename value_type_t >
    263299        std::pair< iterator, bool > insert( iterator at, value_type_t&& value ) {
    264                 Scope& scope = (*at.scopes) [ at.level ];
    265                 std::pair< typename Scope::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) );
     300                MapType& scope = (*at.scopes)[ at.level ].map;
     301                std::pair< typename MapType::iterator, bool > res = scope.insert( std::forward<value_type_t>( value ) );
    266302                return std::make_pair( iterator(scopes, std::move( res.first ), at.level), std::move( res.second ) );
    267303        }
     
    272308        template< typename value_type_t >
    273309        std::pair< iterator, bool > insertAt( size_type scope, value_type_t&& value ) {
    274                 std::pair< typename Scope::iterator, bool > res = scopes.at(scope).insert( std::forward<value_type_t>( value ) );
     310                std::pair< typename MapType::iterator, bool > res = scopes.at(scope).map.insert( std::forward<value_type_t>( value ) );
    275311                return std::make_pair( iterator(scopes, std::move( res.first ), scope), std::move( res.second ) );
    276312        }
     
    288324
    289325        iterator erase( iterator pos ) {
    290                 Scope& scope = (*pos.scopes) [ pos.level ];
     326                MapType& scope = (*pos.scopes)[ pos.level ].map;
    291327                const typename iterator::wrapped_iterator& new_it = scope.erase( pos.it );
    292328                iterator it( *pos.scopes, new_it, pos.level );
  • src/Parser/TypedefTable.cc

    r036dd5f raeec6b7  
    9191
    9292void TypedefTable::enterScope() {
    93         kindTable.beginScope();
     93        kindTable.beginScope(0);
    9494        debugPrint( cerr << "Entering scope " << kindTable.currentScope() << endl; print() );
    9595} // TypedefTable::enterScope
  • src/Parser/TypedefTable.h

    r036dd5f raeec6b7  
    2323
    2424class TypedefTable {
    25         typedef ScopedMap< std::string, int > KindTable;
     25        typedef ScopedMap< std::string, int, int > KindTable;
    2626        KindTable kindTable;   
    27         unsigned int level = 0;
     27        unsigned int level;
    2828  public:
     29    TypedefTable() : kindTable{0}, level{0} {}
    2930        ~TypedefTable();
    3031
  • src/Parser/lex.ll

    r036dd5f raeec6b7  
    464464void yyerror( const char * errmsg ) {
    465465        SemanticErrorThrow = true;
    466         cout << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1
     466        cerr << (yyfilename ? yyfilename : "*unknown file*") << ':' << yylineno << ':' << column - yyleng + 1
    467467                 << ": " << ErrorHelpers::error_str() << errmsg << " at token \"" << (yytext[0] == '\0' ? "EOF" : yytext) << '"' << endl;
    468468}
  • src/prelude/Makefile.am

    r036dd5f raeec6b7  
    4343
    4444prelude.cf : prelude-gen.cc
    45         ${AM_V_GEN}${CXX} ${AM_CXXFLAGS} ${CXXFLAGS} ${<} -o prelude-gen
     45        ${AM_V_GEN}${CXX} ${AM_CXXFLAGS} ${CXXFLAGS} ${<} -o prelude-gen -Wall -Wextra -O2 -g -std=c++14
    4646        @./prelude-gen > $@
    4747        @rm ./prelude-gen
     
    6767        rm -rf $(DEPDIR)
    6868
    69 MAINTAINERCLEANFILES = gcc-builtins.c gcc-builtins.cf builtins.cf extras.cf bootloader.c ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}}
     69MAINTAINERCLEANFILES = gcc-builtins.c gcc-builtins.cf builtins.cf extras.cf bootloader.c prelude.cf ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}}
  • src/prelude/Makefile.in

    r036dd5f raeec6b7  
    281281cfalib_DATA = gcc-builtins.cf builtins.cf extras.cf prelude.cf bootloader.c
    282282noinst_DATA = ../libcfa/libcfa-prelude.c
    283 MAINTAINERCLEANFILES = gcc-builtins.c gcc-builtins.cf builtins.cf extras.cf bootloader.c ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}}
     283MAINTAINERCLEANFILES = gcc-builtins.c gcc-builtins.cf builtins.cf extras.cf bootloader.c prelude.cf ${addprefix ${libdir}/,${cfalib_DATA}} ${addprefix ${libdir}/,${lib_LIBRARIES}}
    284284all: all-am
    285285
     
    512512
    513513prelude.cf : prelude-gen.cc
    514         ${AM_V_GEN}${CXX} ${AM_CXXFLAGS} ${CXXFLAGS} ${<} -o prelude-gen
     514        ${AM_V_GEN}${CXX} ${AM_CXXFLAGS} ${CXXFLAGS} ${<} -o prelude-gen -Wall -Wextra -O2 -g -std=c++14
    515515        @./prelude-gen > $@
    516516        @rm ./prelude-gen
  • src/prelude/prelude-gen.cc

    r036dd5f raeec6b7  
    121121                if(mask & (1 << i)) {
    122122                        result += name;
     123                } else {
     124                        result.append(name.size(), ' ');
    123125                }
    124126                i++;
     
    148150        cout << endl;
    149151
    150         cout << "void   ?{}( zero_t & );" << endl;
    151         cout << "void   ?{}( one_t & );" << endl;
    152         cout << "void   ?{}( zero_t &, zero_t );" << endl;
    153         cout << "void   ?{}( one_t &, one_t );" << endl;
    154         cout << "void   ^?{}( zero_t & );" << endl;
    155         cout << "void   ^?{}( one_t & );" << endl;
    156         cout << "zero_t                 ?=?( zero_t &, zero_t );" << endl;
    157         cout << "one_t                  ?=?( one_t &, one_t );" << endl;
    158152        cout << "signed int ?==?( zero_t, zero_t ),                                                     ?!=?( zero_t, zero_t );" << endl;
    159153        cout << "signed int ?==?( one_t, one_t ),                                                       ?!=?( one_t, one_t );" << endl;
    160 
    161154        cout << "signed int ?==?( _Bool, _Bool ),                                                       ?!=?( _Bool, _Bool );" << endl;
    162         cout << "void   ?{}( _Bool & );" << endl;
    163         cout << "void   ?{}( _Bool &, _Bool );" << endl;
    164         cout << "void   ^?{}( _Bool & );" << endl;
    165         cout << "_Bool                  ?=?( _Bool &, _Bool ),                                  ?=?( volatile _Bool &, _Bool );" << endl;
    166155        cout << "signed int     !?( _Bool );" << endl;
    167 
    168         cout << "void   ^?{}( char & );" << endl;
    169         cout << "void   ^?{}( char unsigned & );" << endl;
    170         cout << "void   ^?{}( char signed & );" << endl;
    171         cout << "void   ?{}( char &, char );" << endl;
    172         cout << "void   ?{}( unsigned char &, unsigned char );" << endl;
    173         cout << "void   ?{}( char signed &, char signed );" << endl;
    174         cout << "void   ?{}( char & );" << endl;
    175         cout << "void   ?{}( unsigned char & );" << endl;
    176         cout << "void   ?{}( char signed & );" << endl;
    177         cout << "char                   ?=?( char &, char ),                                    ?=?( volatile char &, char );" << endl;
    178         cout << "char signed            ?=?( char signed &, char signed ),                      ?=?( volatile char signed &, char signed );" << endl;
    179         cout << "char unsigned          ?=?( char unsigned &, char unsigned ),                  ?=?( volatile char unsigned &, char unsigned );" << endl;
    180 
    181156
    182157        for (auto op : arithmeticOperators) {
     
    213188        cout << "// Arithmetic Constructors //" << endl;
    214189        cout << "/////////////////////////////" << endl;
     190        auto otype = [](const std::string & type, bool do_volatile = false) {
     191                cout << "void \t?{} ( " << type << " & );" << endl;
     192                cout << "void \t?{} ( " << type << " &, " << type << " );" << endl;
     193                cout << type << " \t?=? ( " << type << " &, " << type << " )";
     194                if( do_volatile ) {
     195                        cout << ", \t?=?( volatile " << type << " &, " << type << " )";
     196                }
     197                cout << ";" << endl;
     198                cout << "void \t^?{}( " << type << " & );" << endl;
     199        };
     200
     201        otype("zero_t");
     202        otype("one_t");
     203        otype("_Bool", true);
     204        otype("char", true);
     205        otype("signed char", true);
     206        otype("unsigned char", true);
     207
    215208        for (auto type : basicTypes) {
    216209                cout << "void  ?{}(" << type.name << " &);" << endl;
     
    227220        cout << "forall(ftype FT) void  ?{}( FT * volatile &, FT * );" << endl;
    228221
    229         // generate qualifiers for first and second parameters of copy constructors
     222        // generate qualifiers
     223        vector<string> qualifiersSingle;
    230224        vector<pair<const string, const string>> qualifiersPair;
    231225        const unsigned int NQ = 2;
    232226        for(unsigned int lhs = 0; lhs < (1<<NQ); lhs++) {
     227                // for parameter of default constructor and destructor
     228                qualifiersSingle.push_back(mask2string(lhs, make_array("const "s, "volatile "s)));
     229
     230                // for first and second parameters of copy constructors
    233231                for(unsigned int rhs = 0; rhs < (1<<NQ); rhs++) {
    234232                        if((lhs & rhs) == rhs) {
     
    241239        }
    242240
    243         for (auto type : { "DT", "void" }) {
    244                 for (auto q : qualifiersPair) {
    245                         cout << "forall(dtype DT) void  ?{}(" << q.first << type << " *&, " << q.second << "DT *);" << endl;
    246                 }
    247         }
    248 
    249 
    250         // generate qualifiers for parameter of default constructor and destructor
    251         vector<string> qualifiersSingle;
    252         for (unsigned int lhs = 0; lhs < (1<<NQ); lhs++) {
    253                 qualifiersSingle.push_back(mask2string(lhs, make_array("const "s, "volatile "s)));
    254         }
    255 
    256         for (auto type : { "DT", "void" }) {
    257                 for (auto q : qualifiersSingle) {
    258                         cout << "forall(dtype DT) void  ?{}(" << q << type << " *&);" << endl;
    259                         cout << "forall(dtype DT) void ^?{}(" << q << type << " *&);" << endl;
    260                 }
    261         }
    262         cout << endl;
    263 
    264         cout << "forall(dtype DT) void ?{}(                 DT *          &, zero_t );" << endl;
    265         cout << "forall(dtype DT) void ?{}(                 DT * volatile &, zero_t );" << endl;
    266         cout << "forall(dtype DT) void ?{}( const           DT *          &, zero_t );" << endl;
    267         cout << "forall(dtype DT) void ?{}( volatile        DT *          &, zero_t );" << endl;
    268         cout << "forall(dtype DT) void ?{}( volatile        DT * volatile &, zero_t );" << endl;
    269         cout << "forall(dtype DT) void ?{}( const volatile DT *   &, zero_t );" << endl;
     241        for (auto type : { "  DT", "void" }) {
     242                for (auto cvq : qualifiersPair) {
     243                        for (auto is_vol : { "        ", "volatile" }) {
     244                                cout << "forall(dtype DT) void  ?{}(" << cvq.first << type << " * " << is_vol << " &, " << cvq.second << "DT *);" << endl;
     245                        }
     246                }
     247                for (auto cvq : qualifiersSingle) {
     248                        for (auto is_vol : { "        ", "volatile" }) {
     249                                cout << "forall(dtype DT) void  ?{}(" << cvq << type << " * " << is_vol << " &);" << endl;
     250                        }
     251                        for (auto is_vol : { "        ", "volatile" }) {
     252                                cout << "forall(dtype DT) void ^?{}(" << cvq << type << " * " << is_vol << " &);" << endl;
     253                        }
     254                }
     255        }
     256
     257        {
     258                auto type = "  DT";
     259                for (auto is_vol : { "        ", "volatile" }) {
     260                        for (auto cvq : qualifiersSingle) {
     261                                cout << "forall(dtype DT) void ?{}( " << cvq << type << " * " << is_vol << " &, zero_t);" << endl;
     262                        }
     263                }
     264        }
     265
     266        cout << endl;
     267
    270268        cout << "forall(ftype FT) void  ?{}( FT *          &, zero_t ); " << endl;
     269        cout << "forall(ftype FT) FT *                  ?=?( FT *          &, zero_t );" << endl;
     270        cout << "forall(ftype FT) FT *                  ?=?( FT * volatile &, zero_t );" << endl;
    271271        cout << "forall( ftype FT ) void        ?{}( FT *          & );" << endl;
    272272        cout << "forall( ftype FT ) void        ^?{}( FT *         & );" << endl;
     
    285285
    286286
    287         cout << "forall( dtype DT ) void *               ?=?(                void *          &,                 DT * );" << endl;
    288         cout << "forall( dtype DT ) void *               ?=?(                void * volatile &,                 DT * );" << endl;
    289         cout << "forall( dtype DT ) const void *                 ?=?( const          void *          &,                 DT * );" << endl;
    290         cout << "forall( dtype DT ) const void *                 ?=?( const          void * volatile &,                 DT * );" << endl;
    291         cout << "forall( dtype DT ) const void *                 ?=?( const          void *          &, const           DT * );" << endl;
    292         cout << "forall( dtype DT ) const void *                 ?=?( const          void * volatile &, const           DT * );" << endl;
    293         cout << "forall( dtype DT ) volatile void *      ?=?(       volatile void *          &,                 DT * );" << endl;
    294         cout << "forall( dtype DT ) volatile void *      ?=?(       volatile void * volatile &,                 DT * );" << endl;
    295         cout << "forall( dtype DT ) volatile void *      ?=?(       volatile void *          &,       volatile  DT * );" << endl;
    296         cout << "forall( dtype DT ) volatile void *      ?=?(       volatile void * volatile &,       volatile  DT * );" << endl;
    297         cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void *         &,                 DT * );" << endl;
    298         cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &,                        DT * );" << endl;
    299         cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void *         &, const           DT * );" << endl;
    300         cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &, const          DT * );" << endl;
    301         cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void *         &,       volatile  DT * );" << endl;
    302         cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &,              volatile  DT * );" << endl;
    303         cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void *         &, const volatile  DT * );" << endl;
    304         cout << "forall( dtype DT ) const volatile void * ?=?( const volatile void * volatile &, const volatile DT * );" << endl;
    305 
    306287        for (auto op : pointerOperators) {
     288                auto forall = [&op]() {
     289                        cout << "forall(dtype DT" << op.sized << ") ";
     290                };
    307291                for (auto type : { "DT"/*, "void"*/ } ) {
    308292                        auto operands = count(op.name.begin(), op.name.end(), '?');
     
    313297                                                if (operands == 1) {
    314298                                                        for (auto q : qualifiersSingle){
    315                                                                 for (auto q2 : { " ", " volatile " }) {
    316                                                                         cout << "forall(dtype DT" << op.sized <<  ") ";
     299                                                                for (auto q2 : { "        ", "volatile" }) {
     300                                                                        forall();
    317301                                                                        cout << q << type << " * " << op.name << "(";
    318                                                                         cout << q << type << " *" << q2 << "&";
     302                                                                        cout << q << type << " * " << q2 << " &";
    319303                                                                        cout << ");" << endl;
    320304                                                                }
     
    322306                                                } else {
    323307                                                        for (auto q : qualifiersPair){
    324                                                                 for (auto q2 : { " ", " volatile " }) {
    325                                                                         cout << "forall(dtype DT" << op.sized <<  ") ";
     308                                                                for (auto q2 : { "        ", "volatile" }) {
     309                                                                        forall();
    326310                                                                        cout << q.first << type << " * " << op.name << "(";
    327                                                                         cout << q.first << type << " *" << q2 << "&";
     311                                                                        cout << q.first << type << " * " << q2 << " &";
    328312
    329313                                                                        for (int i = 1; i < operands; ++i) {
     
    337321                                        case PtrDiff:
    338322                                                for (auto q : qualifiersSingle){
    339                                                         for (auto q2 : { " ", " volatile " }) {
    340                                                                 cout << "forall(dtype DT" << op.sized << ") ";
     323                                                        for (auto q2 : { "        ", "volatile" }) {
     324                                                                forall();
    341325                                                                cout << q << type << " * " << op.name << "(";
    342                                                                 cout << q << type << " *" << q2 << "&";
     326                                                                cout << q << type << " * " << q2 << " &";
    343327
    344328                                                                for (int i = 1; i < operands; ++i) {
     
    353337                                        }
    354338                        } else {
     339                                auto name_and_arg1 = [&op, &type](const std::string & q) {
     340                                        if (op.diffReturn == "&") cout << q << type << " &"; // -- qualifiers
     341                                        else if (op.diffReturn != "") cout << op.diffReturn;
     342                                        else cout << q << type << " *";
     343                                        cout << " " << op.name << "(";
     344                                };
    355345                                switch(op.diffArg2) {
    356346                                        case Normal:
    357347                                                for (auto q : qualifiersSingle) {
    358                                                         cout << "forall(dtype DT" << op.sized << ") ";
    359                                                         if (op.diffReturn == "&") cout << q << type << " &"; // -- qualifiers
    360                                                         else if (op.diffReturn != "") cout << op.diffReturn;
    361                                                         else cout << q << type << " *";
    362                                                         cout << " " << op.name << "(";
     348                                                        forall();
     349                                                        name_and_arg1( q );
    363350                                                        for (int i = 0; i < operands; ++i) {
    364351                                                                cout << q << type << " *";
     
    370357                                        case CommPtrDiff:
    371358                                                for (auto q : qualifiersSingle) {
    372                                                         cout << "forall(dtype DT" << op.sized << ") ";
    373                                                         if (op.diffReturn == "&") cout << q << type << " &"; // -- qualifiers
    374                                                         else if (op.diffReturn != "") cout << op.diffReturn;
    375                                                         else cout << q << type << " *";
    376                                                         cout << " " << op.name << "(ptrdiff_t, " << q << type << " *);" << endl;
     359                                                        forall();
     360                                                        name_and_arg1( q );
     361                                                        cout << "ptrdiff_t, " << q << type << " *);" << endl;
    377362                                                }
    378363                                                // fallthrough
    379364                                        case PtrDiff:
    380365                                                for (auto q : qualifiersSingle) {
    381                                                         cout << "forall(dtype DT" << op.sized << ") ";
    382                                                         if (op.diffReturn == "&") cout << q << type << " &"; // -- qualifiers
    383                                                         else if (op.diffReturn != "") cout << op.diffReturn;
    384                                                         else cout << q << type << " *";
    385                                                         cout << " " << op.name << "(" << q << type << " *, ptrdiff_t);" << endl;
     366                                                        forall();
     367                                                        name_and_arg1( q );
     368                                                        cout << q << type << " *, ptrdiff_t);" << endl;
    386369                                                }
    387370                                                break;
     
    393376        cout << endl;
    394377
    395         cout << "forall(dtype DT) DT *                  ?=?(                DT *          &, zero_t );" << endl;
    396         cout << "forall(dtype DT) DT *                  ?=?(                DT * volatile &, zero_t );" << endl;
    397         cout << "forall(dtype DT) const DT *            ?=?( const          DT *          &, zero_t );" << endl;
    398         cout << "forall(dtype DT) const DT *            ?=?( const          DT * volatile &, zero_t );" << endl;
    399         cout << "forall(dtype DT) volatile DT * ?=?( volatile       DT *          &, zero_t );" << endl;
    400         cout << "forall(dtype DT) volatile DT * ?=?( volatile       DT * volatile &, zero_t );" << endl;
    401         cout << "forall(dtype DT) const volatile DT *   ?=?( const volatile DT *          &, zero_t );" << endl;
    402         cout << "forall(dtype DT) const volatile DT *   ?=?( const volatile DT * volatile &, zero_t );" << endl;
    403         cout << "forall(ftype FT) FT *                  ?=?( FT *          &, zero_t );" << endl;
    404         cout << "forall(ftype FT) FT *                  ?=?( FT * volatile &, zero_t );" << endl;
     378        for (auto is_vol : { "        ", "volatile" }) {
     379                for (auto cvq : qualifiersPair) {
     380                                cout << "forall(dtype DT) " << cvq.first << "void * ?=?( " << cvq.first << "void * " << is_vol << " &, " << cvq.second << "DT *);" << endl;
     381                }
     382                for (auto cvq : qualifiersSingle) {
     383                        cout << "forall(dtype DT) " << cvq <<   "  DT * ?=?( " << cvq << "  DT * " << is_vol << " &, zero_t);" << endl;
     384                }
     385        }
     386        cout << endl;
    405387}
    406388
  • src/tests/.expect/attributes.x86.txt

    r036dd5f raeec6b7  
     1signed int __la__Fi___1(){
     2    __attribute__ ((unused)) signed int ___retval_la__i_1;
     3    L: __attribute__ ((unused)) ((void)1);
     4}
     5struct __attribute__ ((unused)) __anonymous0 {
     6};
     7static inline void ___constructor__F_13s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1);
     8static inline void ___constructor__F_13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
     9static inline void ___destructor__F_13s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1);
     10static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1);
     11static inline void ___constructor__F_13s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1){
     12}
     13static inline void ___constructor__F_13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){
     14}
     15static inline void ___destructor__F_13s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1){
     16}
     17static inline struct __anonymous0 ___operator_assign__F13s__anonymous0_13s__anonymous013s__anonymous0_autogen___1(struct __anonymous0 *___dst__13s__anonymous0_1, struct __anonymous0 ___src__13s__anonymous0_1){
     18    struct __anonymous0 ___ret__13s__anonymous0_1;
     19    ((void)___constructor__F_13s__anonymous013s__anonymous0_autogen___1((&___ret__13s__anonymous0_1), (*___dst__13s__anonymous0_1)));
     20    return ___ret__13s__anonymous0_1;
     21}
     22struct __attribute__ ((unused)) Agn1;
     23struct __attribute__ ((unused)) Agn2 {
     24};
     25static inline void ___constructor__F_5sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1);
     26static inline void ___constructor__F_5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1, struct Agn2 ___src__5sAgn2_1);
     27static inline void ___destructor__F_5sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1);
     28static inline struct Agn2 ___operator_assign__F5sAgn2_5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1, struct Agn2 ___src__5sAgn2_1);
     29static inline void ___constructor__F_5sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1){
     30}
     31static inline void ___constructor__F_5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1, struct Agn2 ___src__5sAgn2_1){
     32}
     33static inline void ___destructor__F_5sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1){
     34}
     35static inline struct Agn2 ___operator_assign__F5sAgn2_5sAgn25sAgn2_autogen___1(struct Agn2 *___dst__5sAgn2_1, struct Agn2 ___src__5sAgn2_1){
     36    struct Agn2 ___ret__5sAgn2_1;
     37    ((void)___constructor__F_5sAgn25sAgn2_autogen___1((&___ret__5sAgn2_1), (*___dst__5sAgn2_1)));
     38    return ___ret__5sAgn2_1;
     39}
     40enum __attribute__ ((unused)) __anonymous1 {
     41    __E1__C13e__anonymous1_1,
     42};
     43enum __attribute__ ((unused)) Agn3;
     44enum __attribute__ ((packed)) Agn3 {
     45    __E2__C5eAgn3_1,
     46};
     47struct __attribute__ ((unused)) __anonymous2 {
     48};
     49static inline void ___constructor__F_13s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1);
     50static inline void ___constructor__F_13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
     51static inline void ___destructor__F_13s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1);
     52static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1);
     53static inline void ___constructor__F_13s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1){
     54}
     55static inline void ___constructor__F_13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1){
     56}
     57static inline void ___destructor__F_13s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1){
     58}
     59static inline struct __anonymous2 ___operator_assign__F13s__anonymous2_13s__anonymous213s__anonymous2_autogen___1(struct __anonymous2 *___dst__13s__anonymous2_1, struct __anonymous2 ___src__13s__anonymous2_1){
     60    struct __anonymous2 ___ret__13s__anonymous2_1;
     61    ((void)___constructor__F_13s__anonymous213s__anonymous2_autogen___1((&___ret__13s__anonymous2_1), (*___dst__13s__anonymous2_1)));
     62    return ___ret__13s__anonymous2_1;
     63}
     64struct __attribute__ ((unused)) Agn4 {
     65};
     66static inline void ___constructor__F_5sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1);
     67static inline void ___constructor__F_5sAgn45sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1, struct Agn4 ___src__5sAgn4_1);
     68static inline void ___destructor__F_5sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1);
     69static inline struct Agn4 ___operator_assign__F5sAgn4_5sAgn45sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1, struct Agn4 ___src__5sAgn4_1);
     70static inline void ___constructor__F_5sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1){
     71}
     72static inline void ___constructor__F_5sAgn45sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1, struct Agn4 ___src__5sAgn4_1){
     73}
     74static inline void ___destructor__F_5sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1){
     75}
     76static inline struct Agn4 ___operator_assign__F5sAgn4_5sAgn45sAgn4_autogen___1(struct Agn4 *___dst__5sAgn4_1, struct Agn4 ___src__5sAgn4_1){
     77    struct Agn4 ___ret__5sAgn4_1;
     78    ((void)___constructor__F_5sAgn45sAgn4_autogen___1((&___ret__5sAgn4_1), (*___dst__5sAgn4_1)));
     79    return ___ret__5sAgn4_1;
     80}
     81struct Fdl {
     82    __attribute__ ((unused)) signed int __f1__i_1;
     83    __attribute__ ((unused)) signed int __f2__i_1;
     84    __attribute__ ((unused,unused)) signed int __f3__i_1;
     85    __attribute__ ((unused)) signed int __f4__i_1;
     86    __attribute__ ((unused,unused)) signed int __f5__i_1;
     87    __attribute__ ((used,packed)) signed int __f6__i_1;
     88    __attribute__ ((used,unused,unused)) signed int __f7__i_1;
     89    __attribute__ ((used,used,unused)) signed int __f8__i_1;
     90    __attribute__ ((unused)) signed int __anonymous_object0;
     91    __attribute__ ((unused,unused)) signed int *__f9__Pi_1;
     92};
     93static inline void ___constructor__F_4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1);
     94static inline void ___constructor__F_4sFdl4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1, struct Fdl ___src__4sFdl_1);
     95static inline void ___destructor__F_4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1);
     96static inline struct Fdl ___operator_assign__F4sFdl_4sFdl4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1, struct Fdl ___src__4sFdl_1);
     97static inline void ___constructor__F_4sFdli_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1);
     98static inline void ___constructor__F_4sFdlii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1);
     99static inline void ___constructor__F_4sFdliii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1);
     100static inline void ___constructor__F_4sFdliiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1);
     101static inline void ___constructor__F_4sFdliiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1);
     102static inline void ___constructor__F_4sFdliiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1);
     103static inline void ___constructor__F_4sFdliiiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1);
     104static inline void ___constructor__F_4sFdliiiiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1, __attribute__ ((unused)) signed int __f8__i_1);
     105static inline void ___constructor__F_4sFdliiiiiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1, __attribute__ ((unused)) signed int __f8__i_1, __attribute__ ((unused)) signed int __anonymous_object1);
     106static inline void ___constructor__F_4sFdliiiiiiiiiPi_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1, __attribute__ ((unused)) signed int __f8__i_1, __attribute__ ((unused)) signed int __anonymous_object2, __attribute__ ((unused,unused)) signed int *__f9__Pi_1);
     107static inline void ___constructor__F_4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1){
     108    ((void)((*___dst__4sFdl_1).__f1__i_1) /* ?{} */);
     109    ((void)((*___dst__4sFdl_1).__f2__i_1) /* ?{} */);
     110    ((void)((*___dst__4sFdl_1).__f3__i_1) /* ?{} */);
     111    ((void)((*___dst__4sFdl_1).__f4__i_1) /* ?{} */);
     112    ((void)((*___dst__4sFdl_1).__f5__i_1) /* ?{} */);
     113    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ?{} */);
     114    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
     115    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
     116    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
     117    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
     118}
     119static inline void ___constructor__F_4sFdl4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1, struct Fdl ___src__4sFdl_1){
     120    ((void)((*___dst__4sFdl_1).__f1__i_1=___src__4sFdl_1.__f1__i_1) /* ?{} */);
     121    ((void)((*___dst__4sFdl_1).__f2__i_1=___src__4sFdl_1.__f2__i_1) /* ?{} */);
     122    ((void)((*___dst__4sFdl_1).__f3__i_1=___src__4sFdl_1.__f3__i_1) /* ?{} */);
     123    ((void)((*___dst__4sFdl_1).__f4__i_1=___src__4sFdl_1.__f4__i_1) /* ?{} */);
     124    ((void)((*___dst__4sFdl_1).__f5__i_1=___src__4sFdl_1.__f5__i_1) /* ?{} */);
     125    ((void)((*___dst__4sFdl_1).__f6__i_1=___src__4sFdl_1.__f6__i_1) /* ?{} */);
     126    ((void)((*___dst__4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1) /* ?{} */);
     127    ((void)((*___dst__4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1) /* ?{} */);
     128    ((void)((*___dst__4sFdl_1).__anonymous_object0=___src__4sFdl_1.__anonymous_object0) /* ?{} */);
     129    ((void)((*___dst__4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1) /* ?{} */);
     130}
     131static inline void ___destructor__F_4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1){
     132    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ^?{} */);
     133    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ^?{} */);
     134    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ^?{} */);
     135    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ^?{} */);
     136    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ^?{} */);
     137    ((void)((*___dst__4sFdl_1).__f5__i_1) /* ^?{} */);
     138    ((void)((*___dst__4sFdl_1).__f4__i_1) /* ^?{} */);
     139    ((void)((*___dst__4sFdl_1).__f3__i_1) /* ^?{} */);
     140    ((void)((*___dst__4sFdl_1).__f2__i_1) /* ^?{} */);
     141    ((void)((*___dst__4sFdl_1).__f1__i_1) /* ^?{} */);
     142}
     143static inline struct Fdl ___operator_assign__F4sFdl_4sFdl4sFdl_autogen___1(struct Fdl *___dst__4sFdl_1, struct Fdl ___src__4sFdl_1){
     144    struct Fdl ___ret__4sFdl_1;
     145    ((void)((*___dst__4sFdl_1).__f1__i_1=___src__4sFdl_1.__f1__i_1));
     146    ((void)((*___dst__4sFdl_1).__f2__i_1=___src__4sFdl_1.__f2__i_1));
     147    ((void)((*___dst__4sFdl_1).__f3__i_1=___src__4sFdl_1.__f3__i_1));
     148    ((void)((*___dst__4sFdl_1).__f4__i_1=___src__4sFdl_1.__f4__i_1));
     149    ((void)((*___dst__4sFdl_1).__f5__i_1=___src__4sFdl_1.__f5__i_1));
     150    ((void)((*___dst__4sFdl_1).__f6__i_1=___src__4sFdl_1.__f6__i_1));
     151    ((void)((*___dst__4sFdl_1).__f7__i_1=___src__4sFdl_1.__f7__i_1));
     152    ((void)((*___dst__4sFdl_1).__f8__i_1=___src__4sFdl_1.__f8__i_1));
     153    ((void)((*___dst__4sFdl_1).__anonymous_object0=___src__4sFdl_1.__anonymous_object0));
     154    ((void)((*___dst__4sFdl_1).__f9__Pi_1=___src__4sFdl_1.__f9__Pi_1));
     155    ((void)___constructor__F_4sFdl4sFdl_autogen___1((&___ret__4sFdl_1), (*___dst__4sFdl_1)));
     156    return ___ret__4sFdl_1;
     157}
     158static inline void ___constructor__F_4sFdli_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1){
     159    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
     160    ((void)((*___dst__4sFdl_1).__f2__i_1) /* ?{} */);
     161    ((void)((*___dst__4sFdl_1).__f3__i_1) /* ?{} */);
     162    ((void)((*___dst__4sFdl_1).__f4__i_1) /* ?{} */);
     163    ((void)((*___dst__4sFdl_1).__f5__i_1) /* ?{} */);
     164    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ?{} */);
     165    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
     166    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
     167    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
     168    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
     169}
     170static inline void ___constructor__F_4sFdlii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1){
     171    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
     172    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
     173    ((void)((*___dst__4sFdl_1).__f3__i_1) /* ?{} */);
     174    ((void)((*___dst__4sFdl_1).__f4__i_1) /* ?{} */);
     175    ((void)((*___dst__4sFdl_1).__f5__i_1) /* ?{} */);
     176    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ?{} */);
     177    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
     178    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
     179    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
     180    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
     181}
     182static inline void ___constructor__F_4sFdliii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1){
     183    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
     184    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
     185    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
     186    ((void)((*___dst__4sFdl_1).__f4__i_1) /* ?{} */);
     187    ((void)((*___dst__4sFdl_1).__f5__i_1) /* ?{} */);
     188    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ?{} */);
     189    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
     190    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
     191    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
     192    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
     193}
     194static inline void ___constructor__F_4sFdliiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1){
     195    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
     196    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
     197    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
     198    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
     199    ((void)((*___dst__4sFdl_1).__f5__i_1) /* ?{} */);
     200    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ?{} */);
     201    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
     202    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
     203    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
     204    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
     205}
     206static inline void ___constructor__F_4sFdliiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1){
     207    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
     208    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
     209    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
     210    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
     211    ((void)((*___dst__4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);
     212    ((void)((*___dst__4sFdl_1).__f6__i_1) /* ?{} */);
     213    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
     214    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
     215    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
     216    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
     217}
     218static inline void ___constructor__F_4sFdliiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1){
     219    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
     220    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
     221    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
     222    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
     223    ((void)((*___dst__4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);
     224    ((void)((*___dst__4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */);
     225    ((void)((*___dst__4sFdl_1).__f7__i_1) /* ?{} */);
     226    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
     227    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
     228    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
     229}
     230static inline void ___constructor__F_4sFdliiiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1){
     231    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
     232    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
     233    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
     234    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
     235    ((void)((*___dst__4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);
     236    ((void)((*___dst__4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */);
     237    ((void)((*___dst__4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
     238    ((void)((*___dst__4sFdl_1).__f8__i_1) /* ?{} */);
     239    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
     240    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
     241}
     242static inline void ___constructor__F_4sFdliiiiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1, __attribute__ ((unused)) signed int __f8__i_1){
     243    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
     244    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
     245    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
     246    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
     247    ((void)((*___dst__4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);
     248    ((void)((*___dst__4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */);
     249    ((void)((*___dst__4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
     250    ((void)((*___dst__4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */);
     251    ((void)((*___dst__4sFdl_1).__anonymous_object0) /* ?{} */);
     252    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
     253}
     254static inline void ___constructor__F_4sFdliiiiiiiii_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1, __attribute__ ((unused)) signed int __f8__i_1, __attribute__ ((unused)) signed int __anonymous_object3){
     255    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
     256    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
     257    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
     258    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
     259    ((void)((*___dst__4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);
     260    ((void)((*___dst__4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */);
     261    ((void)((*___dst__4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
     262    ((void)((*___dst__4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */);
     263    ((void)((*___dst__4sFdl_1).__anonymous_object0=__anonymous_object3) /* ?{} */);
     264    ((void)((*___dst__4sFdl_1).__f9__Pi_1) /* ?{} */);
     265}
     266static inline void ___constructor__F_4sFdliiiiiiiiiPi_autogen___1(struct Fdl *___dst__4sFdl_1, __attribute__ ((unused)) signed int __f1__i_1, __attribute__ ((unused)) signed int __f2__i_1, __attribute__ ((unused,unused)) signed int __f3__i_1, __attribute__ ((unused)) signed int __f4__i_1, __attribute__ ((unused,unused)) signed int __f5__i_1, signed int __f6__i_1, __attribute__ ((unused,unused)) signed int __f7__i_1, __attribute__ ((unused)) signed int __f8__i_1, __attribute__ ((unused)) signed int __anonymous_object4, __attribute__ ((unused,unused)) signed int *__f9__Pi_1){
     267    ((void)((*___dst__4sFdl_1).__f1__i_1=__f1__i_1) /* ?{} */);
     268    ((void)((*___dst__4sFdl_1).__f2__i_1=__f2__i_1) /* ?{} */);
     269    ((void)((*___dst__4sFdl_1).__f3__i_1=__f3__i_1) /* ?{} */);
     270    ((void)((*___dst__4sFdl_1).__f4__i_1=__f4__i_1) /* ?{} */);
     271    ((void)((*___dst__4sFdl_1).__f5__i_1=__f5__i_1) /* ?{} */);
     272    ((void)((*___dst__4sFdl_1).__f6__i_1=__f6__i_1) /* ?{} */);
     273    ((void)((*___dst__4sFdl_1).__f7__i_1=__f7__i_1) /* ?{} */);
     274    ((void)((*___dst__4sFdl_1).__f8__i_1=__f8__i_1) /* ?{} */);
     275    ((void)((*___dst__4sFdl_1).__anonymous_object0=__anonymous_object4) /* ?{} */);
     276    ((void)((*___dst__4sFdl_1).__f9__Pi_1=__f9__Pi_1) /* ?{} */);
     277}
     278__attribute__ ((unused)) signed int __f__Fi___1() asm ( "xyz" );
     279__attribute__ ((used,used)) const signed int __vd1__Ci_1;
     280__attribute__ ((used,unused)) const signed int __vd2__Ci_1;
     281__attribute__ ((used,used,used,used)) const signed int *__vd3__PCi_1;
     282__attribute__ ((used,used,unused,used,unused)) const signed int *__vd4__PCi_1;
     283__attribute__ ((used,used,used)) const signed int __vd5__A0Ci_1[((unsigned int )5)];
     284__attribute__ ((used,used,unused,used)) const signed int __vd6__A0Ci_1[((unsigned int )5)];
     285__attribute__ ((used,used,used,used)) const signed int (*__vd7__Fi___1)();
     286__attribute__ ((used,used,unused,used,used)) const signed int (*__vd8__Fi___1)();
     287__attribute__ ((unused,used)) signed int __f1__Fi___1();
     288__attribute__ ((unused)) signed int __f1__Fi___1(){
     289    __attribute__ ((unused)) signed int ___retval_f1__i_1;
     290}
     291__attribute__ ((unused,unused,unused,used)) signed int **const __f2__FPPi___1();
     292__attribute__ ((unused,unused,unused)) signed int **const __f2__FPPi___1(){
     293    __attribute__ ((unused)) signed int **const ___retval_f2__CPPi_1;
     294}
     295__attribute__ ((unused,used,unused)) signed int (*__f3__FPA0i_i__1(signed int __anonymous_object5))[];
     296__attribute__ ((unused,unused)) signed int (*__f3__FPA0i_i__1(signed int __p__i_1))[]{
     297    __attribute__ ((unused)) signed int (*___retval_f3__PA0i_1)[];
     298}
     299__attribute__ ((unused,used,unused)) signed int (*__f4__FFi_i____1())(signed int __anonymous_object6);
     300__attribute__ ((unused,unused)) signed int (*__f4__FFi_i____1())(signed int __anonymous_object7){
     301    __attribute__ ((unused)) signed int (*___retval_f4__Fi_i__1)(signed int __anonymous_object8);
     302}
     303signed int __vtr__Fi___1(){
     304    __attribute__ ((unused)) signed int ___retval_vtr__i_1;
     305    __attribute__ ((unused,unused,used)) signed int __t1__i_2;
     306    __attribute__ ((unused,unused,unused,unused,unused)) signed int **__t2__PPi_2;
     307    __attribute__ ((unused,unused,unused)) signed int __t3__A0i_2[((unsigned int )5)];
     308    __attribute__ ((unused,unused,unused,unused,unused)) signed int **__t4__A0PPi_2[((unsigned int )5)];
     309    __attribute__ ((unused,unused,unused)) signed int __t5__Fi___2();
     310    __attribute__ ((unused,unused,unused,unused)) signed int *__t6__FPi___2();
     311}
     312signed int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) signed int __p__i_1, __attribute__ ((unused,unused,unused)) signed int __q__i_1);
     313signed int __ipd1__Fi_ii__1(__attribute__ ((unused,unused,unused)) signed int __p__i_1, __attribute__ ((unused,unused,unused)) signed int __q__i_1){
     314    __attribute__ ((unused)) signed int ___retval_ipd1__i_1;
     315}
     316signed int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) signed int *__p__Pi_1, __attribute__ ((unused,unused,unused)) signed int *__q__Pi_1);
     317signed int __ipd2__Fi_PiPi__1(__attribute__ ((unused,unused,unused,unused)) signed int *__p__Pi_1, __attribute__ ((unused,unused,unused)) signed int *__q__Pi_1){
     318    __attribute__ ((unused)) signed int ___retval_ipd2__i_1;
     319}
     320signed int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__p__Pi_1, __attribute__ ((unused,unused,unused)) signed int *__q__Pi_1);
     321signed int __ipd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__p__Pi_1, __attribute__ ((unused,unused,unused)) signed int *__q__Pi_1){
     322    __attribute__ ((unused)) signed int ___retval_ipd3__i_1;
     323}
     324signed int __ipd4__Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__p__Fi___1)(), __attribute__ ((unused,unused,unused)) signed int (*__q__Fi___1)());
     325signed int __ipd4__Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__p__Fi___1)(), __attribute__ ((unused,unused,unused)) signed int (*__q__Fi___1)()){
     326    __attribute__ ((unused)) signed int ___retval_ipd4__i_1;
     327}
     328signed int __tpr1__Fi_i__1(__attribute__ ((unused,unused,unused)) signed int __Foo__i_1);
     329signed int __tpr2__Fi_PPi__1(__attribute__ ((unused,unused,unused,unused,unused,unused)) signed int **__Foo__PPi_1);
     330signed int __tpr3__Fi_Pi__1(__attribute__ ((unused,unused,unused)) signed int *__Foo__Pi_1);
     331signed int __tpr4__Fi_Fi_Pi___1(__attribute__ ((unused,unused)) signed int (*__anonymous_object9)(__attribute__ ((unused,unused)) signed int __anonymous_object10[((unsigned int )5)]));
     332signed int __tpr5__Fi_Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__Fi___1)());
     333signed int __tpr6__Fi_Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__Foo__Fi___1)());
     334signed int __tpr7__Fi_Fi_Fi_i____1(__attribute__ ((unused,unused)) signed int (*__anonymous_object11)(__attribute__ ((unused)) signed int (*__anonymous_object12)(__attribute__ ((unused,unused)) signed int __anonymous_object13)));
     335signed int __ad__Fi___1(){
     336    __attribute__ ((unused)) signed int ___retval_ad__i_1;
     337    __attribute__ ((used,unused)) signed int __ad1__i_2;
     338    __attribute__ ((unused,unused,unused)) signed int *__ad2__Pi_2;
     339    __attribute__ ((unused,unused,unused)) signed int __ad3__A0i_2[((unsigned int )5)];
     340    __attribute__ ((unused,unused,unused,unused,unused)) signed int (*__ad4__PA0i_2)[((unsigned int )10)];
     341    __attribute__ ((unused,unused,unused,unused,used)) signed int __ad5__i_2;
     342    __attribute__ ((unused,unused,unused,unused,unused)) signed int __ad6__Fi___2();
     343    ((void)sizeof(__attribute__ ((unused,unused)) signed int ));
     344    ((void)sizeof(__attribute__ ((unused,unused,unused,unused)) signed int **));
     345    ((void)sizeof(__attribute__ ((unused,unused,unused)) signed int [5]));
     346    ((void)sizeof(__attribute__ ((unused,unused,unused)) signed int (*)[10]));
     347    ((void)sizeof(__attribute__ ((unused,unused,unused)) signed int ()));
     348    struct __attribute__ ((unused)) __anonymous3 {
     349        signed int __i__i_2;
     350    };
     351    inline void ___constructor__F_13s__anonymous3_autogen___2(struct __anonymous3 *___dst__13s__anonymous3_2){
     352        ((void)((*___dst__13s__anonymous3_2).__i__i_2) /* ?{} */);
     353    }
     354    inline void ___constructor__F_13s__anonymous313s__anonymous3_autogen___2(struct __anonymous3 *___dst__13s__anonymous3_2, struct __anonymous3 ___src__13s__anonymous3_2){
     355        ((void)((*___dst__13s__anonymous3_2).__i__i_2=___src__13s__anonymous3_2.__i__i_2) /* ?{} */);
     356    }
     357    inline void ___destructor__F_13s__anonymous3_autogen___2(struct __anonymous3 *___dst__13s__anonymous3_2){
     358        ((void)((*___dst__13s__anonymous3_2).__i__i_2) /* ^?{} */);
     359    }
     360    inline struct __anonymous3 ___operator_assign__F13s__anonymous3_13s__anonymous313s__anonymous3_autogen___2(struct __anonymous3 *___dst__13s__anonymous3_2, struct __anonymous3 ___src__13s__anonymous3_2){
     361        struct __anonymous3 ___ret__13s__anonymous3_2;
     362        ((void)((*___dst__13s__anonymous3_2).__i__i_2=___src__13s__anonymous3_2.__i__i_2));
     363        ((void)___constructor__F_13s__anonymous313s__anonymous3_autogen___2((&___ret__13s__anonymous3_2), (*___dst__13s__anonymous3_2)));
     364        return ___ret__13s__anonymous3_2;
     365    }
     366    inline void ___constructor__F_13s__anonymous3i_autogen___2(struct __anonymous3 *___dst__13s__anonymous3_2, signed int __i__i_2){
     367        ((void)((*___dst__13s__anonymous3_2).__i__i_2=__i__i_2) /* ?{} */);
     368    }
     369    ((void)sizeof(struct __anonymous3 ));
     370    enum __attribute__ ((unused)) __anonymous4 {
     371        __R__C13e__anonymous4_2,
     372    };
     373    inline void ___constructor__F_13e__anonymous4_intrinsic___2(__attribute__ ((unused)) enum __anonymous4 *___dst__13e__anonymous4_2){
     374    }
     375    inline void ___constructor__F_13e__anonymous413e__anonymous4_intrinsic___2(enum __anonymous4 *___dst__13e__anonymous4_2, enum __anonymous4 ___src__13e__anonymous4_2){
     376        ((void)((*___dst__13e__anonymous4_2)=___src__13e__anonymous4_2) /* ?{} */);
     377    }
     378    inline void ___destructor__F_13e__anonymous4_intrinsic___2(__attribute__ ((unused)) enum __anonymous4 *___dst__13e__anonymous4_2){
     379    }
     380    inline enum __anonymous4 ___operator_assign__F13e__anonymous4_13e__anonymous413e__anonymous4_intrinsic___2(enum __anonymous4 *___dst__13e__anonymous4_2, enum __anonymous4 ___src__13e__anonymous4_2){
     381        enum __anonymous4 ___ret__13e__anonymous4_2;
     382        ((void)((*___dst__13e__anonymous4_2)=___src__13e__anonymous4_2));
     383        ((void)(___ret__13e__anonymous4_2=(*___dst__13e__anonymous4_2)) /* ?{} */);
     384        return ___ret__13e__anonymous4_2;
     385    }
     386    ((void)sizeof(enum __anonymous4 ));
     387}
     388signed int __apd1__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object14, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object15);
     389signed int __apd2__Fi_PPiPPi__1(__attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object16, __attribute__ ((unused,unused,unused,unused)) signed int **__anonymous_object17);
     390signed int __apd3__Fi_PiPi__1(__attribute__ ((unused,unused,unused)) signed int *__anonymous_object18, __attribute__ ((unused,unused,unused)) signed int *__anonymous_object19);
     391signed int __apd4__Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object20)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object21)());
     392signed int __apd5__Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object22)(__attribute__ ((unused)) signed int __anonymous_object23), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object24)(__attribute__ ((unused)) signed int __anonymous_object25));
     393signed int __apd6__Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object26)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object27)());
     394signed int __apd7__Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object28)(__attribute__ ((unused)) signed int __anonymous_object29), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object30)(__attribute__ ((unused)) signed int __anonymous_object31));
     395struct Vad {
     396    __attribute__ ((unused)) signed int __anonymous_object32;
     397    __attribute__ ((unused,unused)) signed int *__anonymous_object33;
     398    __attribute__ ((unused,unused)) signed int __anonymous_object34[((unsigned int )10)];
     399    __attribute__ ((unused,unused)) signed int (*__anonymous_object35)();
     400};
     401static inline void ___constructor__F_4sVad_autogen___1(struct Vad *___dst__4sVad_1);
     402static inline void ___constructor__F_4sVad4sVad_autogen___1(struct Vad *___dst__4sVad_1, struct Vad ___src__4sVad_1);
     403static inline void ___destructor__F_4sVad_autogen___1(struct Vad *___dst__4sVad_1);
     404static inline struct Vad ___operator_assign__F4sVad_4sVad4sVad_autogen___1(struct Vad *___dst__4sVad_1, struct Vad ___src__4sVad_1);
     405static inline void ___constructor__F_4sVadi_autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object36);
     406static inline void ___constructor__F_4sVadiPi_autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object37, __attribute__ ((unused,unused)) signed int *__anonymous_object38);
     407static inline void ___constructor__F_4sVadiPiA0i_autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object39, __attribute__ ((unused,unused)) signed int *__anonymous_object40, __attribute__ ((unused,unused)) signed int __anonymous_object41[((unsigned int )10)]);
     408static inline void ___constructor__F_4sVadiPiA0iFi___autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object42, __attribute__ ((unused,unused)) signed int *__anonymous_object43, __attribute__ ((unused,unused)) signed int __anonymous_object44[((unsigned int )10)], __attribute__ ((unused,unused)) signed int (*__anonymous_object45)());
     409static inline void ___constructor__F_4sVad_autogen___1(struct Vad *___dst__4sVad_1){
     410    ((void)((*___dst__4sVad_1).__anonymous_object32) /* ?{} */);
     411    ((void)((*___dst__4sVad_1).__anonymous_object33) /* ?{} */);
     412    {
     413        signed int _index0 = 0;
     414        for (;(_index0<10);((void)(++_index0))) {
     415            ((void)((*___dst__4sVad_1).__anonymous_object34[_index0]) /* ?{} */);
     416        }
     417
     418    }
     419
     420    ((void)((*___dst__4sVad_1).__anonymous_object35) /* ?{} */);
     421}
     422static inline void ___constructor__F_4sVad4sVad_autogen___1(struct Vad *___dst__4sVad_1, struct Vad ___src__4sVad_1){
     423    ((void)((*___dst__4sVad_1).__anonymous_object32=___src__4sVad_1.__anonymous_object32) /* ?{} */);
     424    ((void)((*___dst__4sVad_1).__anonymous_object33=___src__4sVad_1.__anonymous_object33) /* ?{} */);
     425    {
     426        signed int _index1 = 0;
     427        for (;(_index1<10);((void)(++_index1))) {
     428            ((void)((*___dst__4sVad_1).__anonymous_object34[_index1]=___src__4sVad_1.__anonymous_object34[_index1]) /* ?{} */);
     429        }
     430
     431    }
     432
     433    ((void)((*___dst__4sVad_1).__anonymous_object35=___src__4sVad_1.__anonymous_object35) /* ?{} */);
     434}
     435static inline void ___destructor__F_4sVad_autogen___1(struct Vad *___dst__4sVad_1){
     436    ((void)((*___dst__4sVad_1).__anonymous_object35) /* ^?{} */);
     437    {
     438        signed int _index2 = (10-1);
     439        for (;(_index2>=0);((void)(--_index2))) {
     440            ((void)((*___dst__4sVad_1).__anonymous_object34[_index2]) /* ^?{} */);
     441        }
     442
     443    }
     444
     445    ((void)((*___dst__4sVad_1).__anonymous_object33) /* ^?{} */);
     446    ((void)((*___dst__4sVad_1).__anonymous_object32) /* ^?{} */);
     447}
     448static inline struct Vad ___operator_assign__F4sVad_4sVad4sVad_autogen___1(struct Vad *___dst__4sVad_1, struct Vad ___src__4sVad_1){
     449    struct Vad ___ret__4sVad_1;
     450    ((void)((*___dst__4sVad_1).__anonymous_object32=___src__4sVad_1.__anonymous_object32));
     451    ((void)((*___dst__4sVad_1).__anonymous_object33=___src__4sVad_1.__anonymous_object33));
     452    {
     453        signed int _index3 = 0;
     454        for (;(_index3<10);((void)(++_index3))) {
     455            ((void)((*___dst__4sVad_1).__anonymous_object34[_index3]=___src__4sVad_1.__anonymous_object34[_index3]));
     456        }
     457
     458    }
     459
     460    ((void)((*___dst__4sVad_1).__anonymous_object35=___src__4sVad_1.__anonymous_object35));
     461    ((void)___constructor__F_4sVad4sVad_autogen___1((&___ret__4sVad_1), (*___dst__4sVad_1)));
     462    return ___ret__4sVad_1;
     463}
     464static inline void ___constructor__F_4sVadi_autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object46){
     465    ((void)((*___dst__4sVad_1).__anonymous_object32=__anonymous_object46) /* ?{} */);
     466    ((void)((*___dst__4sVad_1).__anonymous_object33) /* ?{} */);
     467    {
     468        signed int _index4 = 0;
     469        for (;(_index4<10);((void)(++_index4))) {
     470            ((void)((*___dst__4sVad_1).__anonymous_object34[_index4]) /* ?{} */);
     471        }
     472
     473    }
     474
     475    ((void)((*___dst__4sVad_1).__anonymous_object35) /* ?{} */);
     476}
     477static inline void ___constructor__F_4sVadiPi_autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object47, __attribute__ ((unused,unused)) signed int *__anonymous_object48){
     478    ((void)((*___dst__4sVad_1).__anonymous_object32=__anonymous_object47) /* ?{} */);
     479    ((void)((*___dst__4sVad_1).__anonymous_object33=__anonymous_object48) /* ?{} */);
     480    {
     481        signed int _index5 = 0;
     482        for (;(_index5<10);((void)(++_index5))) {
     483            ((void)((*___dst__4sVad_1).__anonymous_object34[_index5]) /* ?{} */);
     484        }
     485
     486    }
     487
     488    ((void)((*___dst__4sVad_1).__anonymous_object35) /* ?{} */);
     489}
     490static inline void ___constructor__F_4sVadiPiA0i_autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object49, __attribute__ ((unused,unused)) signed int *__anonymous_object50, __attribute__ ((unused,unused)) signed int __anonymous_object51[((unsigned int )10)]){
     491    ((void)((*___dst__4sVad_1).__anonymous_object32=__anonymous_object49) /* ?{} */);
     492    ((void)((*___dst__4sVad_1).__anonymous_object33=__anonymous_object50) /* ?{} */);
     493    {
     494        signed int _index6 = 0;
     495        for (;(_index6<10);((void)(++_index6))) {
     496            ((void)((*___dst__4sVad_1).__anonymous_object34[_index6]=__anonymous_object51[_index6]) /* ?{} */);
     497        }
     498
     499    }
     500
     501    ((void)((*___dst__4sVad_1).__anonymous_object35) /* ?{} */);
     502}
     503static inline void ___constructor__F_4sVadiPiA0iFi___autogen___1(struct Vad *___dst__4sVad_1, __attribute__ ((unused)) signed int __anonymous_object52, __attribute__ ((unused,unused)) signed int *__anonymous_object53, __attribute__ ((unused,unused)) signed int __anonymous_object54[((unsigned int )10)], __attribute__ ((unused,unused)) signed int (*__anonymous_object55)()){
     504    ((void)((*___dst__4sVad_1).__anonymous_object32=__anonymous_object52) /* ?{} */);
     505    ((void)((*___dst__4sVad_1).__anonymous_object33=__anonymous_object53) /* ?{} */);
     506    {
     507        signed int _index7 = 0;
     508        for (;(_index7<10);((void)(++_index7))) {
     509            ((void)((*___dst__4sVad_1).__anonymous_object34[_index7]=__anonymous_object54[_index7]) /* ?{} */);
     510        }
     511
     512    }
     513
     514    ((void)((*___dst__4sVad_1).__anonymous_object35=__anonymous_object55) /* ?{} */);
     515}
  • src/tests/Makefile.am

    r036dd5f raeec6b7  
    1717debug=yes
    1818
    19 quick_test=avl_test operators numericConstants expression enum array typeof cast dtor-early-exit init_once attributes
     19quick_test=avl_test operators numericConstants expression enum array typeof cast attributes
    2020
    2121if BUILD_CONCURRENCY
  • src/tests/attributes.c

    r036dd5f raeec6b7  
    1010// Created On       : Mon Feb  6 16:07:02 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 21 23:05:52 2017
    13 // Update Count     : 3
     12// Last Modified On : Sun Jul  8 21:12:07 2018
     13// Update Count     : 8
    1414//
    1515
     
    2929enum __attribute__(( packed )) Agn3 { E2 };
    3030#ifdef __CFA__
    31 struct __attribute__(( unused )) ( int ) {};
    32 struct __attribute__(( unused )) ( int ) {};
     31struct __attribute__(( unused )) {} ( int );
     32struct __attribute__(( unused )) Agn4 {} ( int );
    3333#endif // __CFA__
    3434
Note: See TracChangeset for help on using the changeset viewer.