Changeset e02e13f


Ignore:
Timestamp:
Apr 4, 2023, 10:12:57 PM (2 years ago)
Author:
Mike Brooks <mlbrooks@…>
Branches:
ADT, ast-experimental, master
Children:
9bb8ee42
Parents:
ff71057 (diff), bb7422a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
28 edited

Legend:

Unmodified
Added
Removed
  • doc/LaTeXmacros/common.sty

    rff71057 re02e13f  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Fri Feb 10 12:09:30 2023
    14 %% Update Count     : 581
     13%% Last Modified On : Tue Apr  4 12:03:19 2023
     14%% Update Count     : 585
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    266266\newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}}
    267267\newcommand{\LstStringStyle}[1]{{\lst@basicstyle{\lst@stringstyle{#1}}}}
     268\newcommand{\LstNumberStyle}[1]{{\lst@basicstyle{\lst@numberstyle{#1}}}}
    268269
    269270\newlength{\gcolumnposn}                                % temporary hack because lstlisting does not handle tabs correctly
     
    286287columns=fullflexible,
    287288basicstyle=\linespread{0.9}\sf,                 % reduce line spacing and use sanserif font
    288 stringstyle=\tt,                                                % use typewriter font
     289stringstyle=\small\tt,                                  % use typewriter font
    289290tabsize=5,                                                              % N space tabbing
    290291xleftmargin=\parindentlnth,                             % indent code to paragraph indentation
  • doc/LaTeXmacros/common.tex

    rff71057 re02e13f  
    1111%% Created On       : Sat Apr  9 10:06:17 2016
    1212%% Last Modified By : Peter A. Buhr
    13 %% Last Modified On : Fri Feb 17 08:32:47 2023
    14 %% Update Count     : 565
     13%% Last Modified On : Tue Apr  4 12:03:18 2023
     14%% Update Count     : 567
    1515%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    1616
     
    291291columns=fullflexible,
    292292basicstyle=\linespread{0.9}\sf,                 % reduce line spacing and use sanserif font
    293 stringstyle=\tt,                                                % use typewriter font
     293stringstyle=\small\tt,                                  % use typewriter font
    294294tabsize=5,                                                              % N space tabbing
    295295xleftmargin=\parindentlnth,                             % indent code to paragraph indentation
  • doc/theses/colby_parsons_MMAth/Makefile

    rff71057 re02e13f  
    9696
    9797${BASE}.dvi : Makefile ${GRAPHS} ${PROGRAMS} ${PICTURES} ${FIGURES} ${SOURCES} ${DATA} \
    98                 ${Macros}/common.tex ${Macros}/indexstyle local.bib ../../bibliography/pl.bib | ${Build}
     98                style/style.tex ${Macros}/common.tex ${Macros}/indexstyle local.bib ../../bibliography/pl.bib | ${Build}
    9999        # Must have *.aux file containing citations for bibtex
    100100        if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi
  • doc/theses/colby_parsons_MMAth/style/style.tex

    rff71057 re02e13f  
    11\input{common}
     2\CFAStyle                                               % CFA code-style
     3\lstset{language=CFA}                                   % default language
    24
    3 \lstdefinestyle{defaultStyle}{
    4     escapeinside={@@},
    5     %  basicstyle=\linespread{0.9}\tt\footnotesize,             % reduce line spacing and use typewriter font
    6       basicstyle=\linespread{0.9}\sf,           % reduce line spacing and use typewriter font
    7     %  keywordstyle=\bfseries\color{blue},
    8     %  keywordstyle=[2]\bfseries\color{Plum},
    9     %  commentstyle=\sf\itshape\color{OliveGreen},                % green and italic comments
    10     %  identifierstyle=\color{identifierCol},
    11     %  stringstyle=\sf\color{Mahogany},                           % use sanserif font
    12       stringstyle=\tt,                            % use sanserif font
    13       mathescape=true,
    14     %  columns=fixed,
    15       columns=fullflexible,
    16     %  aboveskip=4pt,                                  % spacing above/below code block
    17     %  belowskip=3pt,
    18       keepspaces=true,
    19       tabsize=4,
    20       % frame=lines,
    21       literate=,
    22       showlines=true,                                 % show blank lines at end of code
    23       showspaces=false,
    24       showstringspaces=false,
    25       showlines=true,                                                   % show blank lines at end of code
    26       escapechar=\$,
    27       xleftmargin=\parindentlnth,                     % indent code to paragraph indentation
    28       moredelim=[is][\color{red}\bfseries]{**R**}{**R**},    % red highlighting
    29       morekeywords=[2]{accept, signal, signal_block, wait, waitfor, waituntil},
    30       abovecaptionskip=5pt,
    31 }
    32 
    33 \lstdefinestyle{cfaStyle}{
    34   escapeinside={@@},
    35   basicstyle=\linespread{0.9}\sf,               % reduce line spacing and use typewriter font
    36   stringstyle=\tt,                                % use sanserif font
    37   mathescape=true,
    38   columns=fullflexible,
    39   keepspaces=true,
    40   tabsize=4,
    41   literate=,
    42   showlines=true,                                 % show blank lines at end of code
    43   showspaces=false,
    44   showstringspaces=false,
    45   showlines=true,                                                       % show blank lines at end of code
    46   escapechar=\$,
    47   xleftmargin=\parindentlnth,                     % indent code to paragraph indentation
    48   moredelim=[is][\color{red}\bfseries]{**R**}{**R**},    % red highlighting
    49   morekeywords=[2]{accept, signal, signal_block, wait, waitfor, waituntil},
    50   abovecaptionskip=5pt,
    51 }
    52 
    53 \lstnewenvironment{cfacode}[1][]{
    54   \lstset{
    55     language = CFA,
    56     style=cfaStyle,
    57     captionpos=b,
    58     #1
    59   }
    60 }{}
    61 
    62 \lstnewenvironment{cppcode}[1][]{
    63   \lstset{
    64     language = c++,
    65     style=defaultStyle,
    66     captionpos=b,
    67     #1
    68   }
    69 }{}
    70 
    71 \newcommand{\code}[1]{\lstinline[language=CFA,style=cfaStyle]{#1}}
     5\newcommand{\code}[1]{\lstinline[language=CFA]{#1}}
    726\newcommand{\uC}{$\mu$\CC}
    737
  • doc/theses/colby_parsons_MMAth/text/CFA_concurrency.tex

    rff71057 re02e13f  
    11\chapter{Concurrency in \CFA}\label{s:cfa_concurrency}
    22
    3 The groundwork for concurrency in \CFA was laid by Thierry Delisle in his Master's Thesis\cite{Delisle18}.
    4 In that work he introduced coroutines, user level threading, and monitors.
    5 Not listed in that work were the other concurrency features that were needed as building blocks, such as locks, futures, and condition variables which he also added to \CFA.
     3The groundwork for concurrency in \CFA was laid by Thierry Delisle in his Master's Thesis~\cite{Delisle18}.
     4In that work, he introduced generators, coroutines, monitors, and user-level threading.
     5Not listed in that work were basic concurrency features needed as building blocks, such as locks, futures, and condition variables, which he also added to \CFA.
    66
    77\section{Threading Model}\label{s:threading}
    8 \CFA has user level threading and supports a $M:N$ threading model where $M$ user threads are scheduled on $N$ cores, where both $M$ and $N$ can be explicitly set by the user.
    9 Cores are used by a program by creating instances of a \code{processor} struct.
    10 User threads types are defined using the \code{thread} keyword, in the place where a \code{struct} keyword is typically used.
    11 For each thread type a corresponding main must be defined, which is where the thread starts running once it is created.
    12 Listing~\ref{l:cfa_thd_init} shows an example of processor and thread creation.
    13 When processors are added, they are added alongside the existing processor given to each program.
    14 Thus if you want $N$ processors you need to allocate $N-1$.
    15 To join a thread the thread must be deallocated, either deleted if it is allocated on the heap, or go out of scope if stack allocated.
    16 The thread performing the deallocation will wait for the thread being deallocated to terminate before the deallocation can occur.
    17 A thread terminates by returning from the main routine where it starts.
     8\CFA provides user-level threading and supports an $M$:$N$ threading model where $M$ user threads are scheduled on $N$ kernel threads, where both $M$ and $N$ can be explicitly set by the user.
     9Kernel threads are created by instancing a @processor@ structure.
     10User-thread types are defined by creating a @thread@ aggregate-type, \ie replace @struct@ with @thread@.
     11For each thread type a corresponding @main@ routine must be defined, which is where the thread starts running once it is created.
     12Examples of \CFA  user thread and processor creation are shown in \VRef[Listing]{l:cfa_thd_init}.
    1813
    19 \begin{cfacode}[tabsize=3,caption={\CFA user thread and processor creation},label={l:cfa_thd_init}]
    20 
    21 thread my_thread {}     // user thread type
    22 void main( my_thread & this ) { // thread start routine
    23     printf("Hello threading world\n");
     14\begin{cfa}[caption={Example of \CFA user thread and processor creation},label={l:cfa_thd_init}]
     15@thread@ my_thread {...};                       $\C{// user thread type}$
     16void @main@( my_thread & this ) {       $\C{// thread start routine}$
     17        sout | "Hello threading world";
    2418}
    2519
    2620int main() {
    27     // add 2 processors, now 3 total
    28     processor p[2];   
    29     {
    30         my_thread t1;
    31         my_thread t2;
    32     } // waits for threads to end before going out of scope
     21        @processor@ p[2];                               $\C{// add 2 processors = 3 total with starting processor}$
     22        {
     23                my_thread t[2], * t3 = new();   $\C{// create 3 user threads, running in main routine}$
     24                ... // execute concurrently
     25                delete( t3 );                           $\C{// wait for thread to end and deallocate}$
     26        } // wait for threads to end and deallocate
    3327}
     28\end{cfa}
    3429
    35 \end{cfacode}
     30When processors are added, they are added alongside the existing processor given to each program.
     31Thus, for $N$ processors, allocate $N-1$ processors.
     32A thread is implicitly joined at deallocated, either implicitly at block exit for stack allocation or explicitly at @delete@ for heap allocation.
     33The thread performing the deallocation must wait for the thread to terminate before the deallocation can occur.
     34A thread terminates by returning from the main routine where it starts.
     35
     36% Local Variables: %
     37% tab-width: 4 %
     38% End: %
  • doc/theses/colby_parsons_MMAth/text/CFA_intro.tex

    rff71057 re02e13f  
    77\section{Overview}
    88The following serves as an introduction to \CFA.
    9 \CFA is a layer over C, is transpiled to C and is largely considered to be an extension of C.
    10 Beyond C, it adds productivity features, libraries, a type system, and many other language constructions.
    11 However, \CFA stays true to C as a language, with most code revolving around \code{struct}'s and routines, and respects the same rules as C.
    12 \CFA is not object oriented as it has no notion of \code{this} and no classes or methods, but supports some object oriented adjacent ideas including costructors, destructors, and limited inheritance.
    13 \CFA is rich with interesting features, but a subset that is pertinent to this work will be discussed.
     9\CFA is a layer over C, is transpiled\footnote{Source to source translator.} to C, and is largely considered to be an extension of C.
     10Beyond C, it adds productivity features, extended libraries, an advanced type system, and many control-flow/concurrency constructions.
     11However, \CFA stays true to the C programming style, with most code revolving around @struct@'s and routines, and respects the same rules as C.
     12\CFA is not object oriented as it has no notion of @this@ (receiver) and no structures with methods, but supports some object oriented ideas including constructors, destructors, and limited containment inheritance.
     13While \CFA is rich with interesting features, only the subset pertinent to this work is discussed.
    1414
    1515\section{References}
    16 References in \CFA are similar to references in \CC, however in \CFA references are rebindable, and support multi-level referencing.
     16References in \CFA are similar to references in \CC; however \CFA references are rebindable, and support multi-level referencing.
    1717References in \CFA are a layer of syntactic sugar over pointers to reduce the number of ref/deref operations needed with pointer usage.
    18 Some examples of references in \CFA are shown in Listing~\ref{l:cfa_ref}.
    19 Another related item to note is that the \CFA equivalent of \CC's \code{nullptr} is \code{0p}.
    20 
    21 \begin{cfacode}[caption={Example of \CFA references},label={l:cfa_ref}]
     18Another difference is the use of @0p@ instead of C's @NULL@ or \CC's @nullptr@.
     19Examples of references are shown in \VRef[Listing]{l:cfa_ref}.
     20
     21\begin{cfa}[caption={Example of \CFA references},label={l:cfa_ref}]
    2222int i = 2;
    23 int & ref_i = i;            // declare ref to i
    24 int * ptr_i = &i;           // ptr to i
     23int & ref_i = i;                        $\C{// declare ref to i}$
     24int * ptr_i = &i;                       $\C{// ptr to i}$
    2525
    2626// address of ref_i is the same as address of i
    2727assert( &ref_i == ptr_i );
    2828
    29 int && ref_ref_i = ref_i;   // can have a ref to a ref
    30 ref_i = 3;                  // set i to 3
     29int && ref_ref_i = ref_i;       $\C{// can have a ref to a ref}$
     30ref_i = 3;                                      $\C{// set i to 3}$
    3131int new_i = 4;
    3232
    3333// syntax to rebind ref_i (must cancel implicit deref)
    34 &ref_i = &new_i; // (&*)ref_i = &new_i; (sets underlying ptr)
    35 \end{cfacode}
    36 
    37 
    38 \section{Overloading}
    39 In \CFA routines can be overloaded on parameter type, number of parameters, and return type.
     34&ref_i = &new_i;                        $\C{// (\&*)ref\_i = \&new\_i; (sets underlying ptr)}$
     35\end{cfa}
     36
     37
     38\section{Overloading}\label{s:Overloading}
     39\CFA routines can be overloaded on parameter type, number of parameters, and \emph{return type}.
    4040Variables can also be overloaded on type, meaning that two variables can have the same name so long as they have different types.
    41 The variables will be disambiguated via type, sometimes requiring a cast.
    42 The code snippet in Listing~\ref{l:cfa_overload} contains examples of overloading.
    43 
    44 
    45 \begin{cfacode}[caption={Example of \CFA function overloading},label={l:cfa_overload}]
    46 int foo() { printf("A\n");  return 0;}
    47 int foo( int bar ) { printf("B\n"); return 1; }
    48 int foo( double bar ) { printf("C\n"); return 2; }
    49 double foo( double bar ) { printf("D\n"); return 3;}
    50 void foo( double bar ) { printf("%.0f\n", bar); }
    51 
    52 int main() {
    53     foo();                  // prints A
    54     foo( 0 );               // prints B
    55     int a = foo( 0.0 );     // prints C
    56     double a = foo( 0.0 );  // prints D
    57     foo( a );               // prints 3
    58 }
    59 \end{cfacode}
     41A routine or variable is disambiguated at each usage site via its type and surrounding expression context.
     42A cast is used to disambiguate any conflicting usage.
     43Examples of overloading are shown in \VRef[Listing]{l:cfa_overload}.
     44
     45\begin{cfa}[caption={Example of \CFA overloading},label={l:cfa_overload}]
     46int foo() { sout | "A";  return 0;}
     47int foo( int bar ) { sout | "B"; return 1; }
     48int foo( double bar ) { sout | "C"; return 2; }
     49double foo( double bar ) { sout | "D"; return 3; }
     50void foo( double bar ) { sout | bar; }
     51
     52int main() {
     53        foo();                                          $\C{// prints A}$
     54        foo( 0 );                                       $\C{// prints B}$
     55        int foo = foo( 0.0 );           $\C{// prints C}$
     56        double foo = foo( 0.0 );        $\C{// prints D}$
     57        foo( foo );                                     $\C{// prints 3., where left-hand side of expression is void}$
     58}
     59\end{cfa}
    6060
    6161
    6262\section{With Statement}
    63 The with statement is a tool for exposing members of aggregate types within a scope in \CFA.
    64 It allows users to use fields of aggregate types without using their fully qualified name.
    65 This feature is also implemented in Pascal.
    66 It can exist as a stand-alone statement or it can be used on routines to expose fields in the body of the routine.
    67 An example is shown in Listing~\ref{l:cfa_with}.
    68 
    69 
    70 \begin{cfacode}[tabsize=3,caption={Usage of \CFA with statement},label={l:cfa_with}]
    71 struct obj {
    72     int a, b, c;
    73 };
    74 struct pair {
    75     double x, y;
    76 };
    77 
    78 // Stand-alone with stmt:
     63The \CFA @with@ statement is for exposing fields of an aggregate type within a scope, allowing field names without qualification.
     64This feature is also implemented in Pascal~\cite{Pascal}.
     65It can exist as a stand-alone statement or wrap a routine body to expose aggregate fields.
     66Examples of the @with@ statement are shown in \VRef[Listing]{l:cfa_with}.
     67
     68\begin{cfa}[caption={Example of \CFA \lstinline{with} statement},label={l:cfa_with}]
     69struct pair {  double x, y;  };
     70struct triple {  int a, b, c;  };
    7971pair p;
    80 with( p ) {
    81     x = 6.28;
    82     y = 1.73;
    83 }
    84 
    85 // Can be used on routines:
    86 void foo( obj o, pair p ) with( o, p ) {
    87     a = 1;
    88     b = 2;
    89     c = 3;
    90     x = 3.14;
    91     y = 2.71;
    92 }
    93 
    94 // routine foo is equivalent to routine bar:
    95 void bar( obj o, pair p ) {
    96     o.a = 1;
    97     o.b = 2;
    98     o.c = 3;
    99     p.x = 3.14;
    100     p.y = 2.71;
    101 }
    102 \end{cfacode}
     72
     73@with( p )@ {                                   $\C{// stand-alone with}$
     74        p.x = 6.28;  p.y = 1.73;        $\C{// long form}$
     75           x = 6.28;     y = 1.73;      $\C{// short form}$
     76}
     77void foo( triple t, pair p ) @with( t, p )@ {  $\C{// routine with}$
     78        t.a = 1;  t.b = 2;  t.c = 3;  p.x = 3.14;  p.y = 2.71;  $\C{// long form}$
     79          a = 1;    b = 2;    c = 3;     x = 3.14;     y = 2.71;  $\C{// short form}$
     80}
     81\end{cfa}
    10382
    10483
    10584\section{Operators}
    10685Operators can be overloaded in \CFA with operator routines.
    107 Operators in \CFA are named using the operator symbol and '?' to respresent operands.
    108 An example is shown in Listing~\ref{l:cfa_operate}.
    109 
    110 
    111 \begin{cfacode}[tabsize=3,caption={Example of \CFA operators},label={l:cfa_operate}]
     86Operators in \CFA are named using an operator symbol and '@?@' to represent operands.
     87Examples of \CFA operators are shown in \VRef[Listing]{l:cfa_operate}.
     88
     89\begin{cfa}[caption={Example of \CFA operators},label={l:cfa_operate}]
    11290struct coord {
    113     double x;
    114     double y;
    115     double z;
    116 };
    117 coord ++?( coord & c ) with(c) {
    118     x++;
    119     y++;
    120     z++;
    121     return c;
    122 }
    123 coord ?<=?( coord op1, coord op2 ) with( op1 ) {
    124     return (x*x + y*y + z*z) <=
    125         (op2.x*op2.x + op2.y*op2.y + op2.z*op2.z);
    126 }
    127 \end{cfacode}
     91        double x, y, z;
     92};
     93coord ++@?@( coord & c ) with( c ) { $\C{// post increment}$
     94        x++;  y++;  z++;
     95        return c;
     96}
     97coord @?@<=@?@( coord op1, coord op2 ) with( op1 ) { $\C{// ambiguous with both parameters}$
     98        return (x * x + y * y + z * z) <= (op2.x * op2.x + op2.y * op2.y + op2.z * op2.z);
     99}
     100\end{cfa}
    128101
    129102
    130103\section{Constructors and Destructors}
    131 Constructors and destructors in \CFA are two special operator routines that are used for creation and destruction of objects.
    132 The default constructor and destructor for a type are called implicitly upon creation and deletion respectively if they are defined.
    133 An example is shown in Listing~\ref{l:cfa_ctor}.
    134 
    135 
    136 \begin{cfacode}[tabsize=3,caption={Example of \CFA constructors and destructors},label={l:cfa_ctor}]
     104Constructors and destructors in \CFA are special operator routines used for creation and destruction of objects.
     105The default constructor and destructor for a type are called implicitly upon creation and deletion, respectively.
     106Examples of \CFA constructors and destructors are shown in \VRef[Listing]{l:cfa_ctor}.
     107
     108\begin{cfa}[caption={Example of \CFA constructors and destructors},label={l:cfa_ctor}]
    137109struct discrete_point {
    138     int x;
    139     int y;
    140 };
    141 void ?{}( discrete_point & this ) with(this) { // ctor
    142     x = 0;
    143     y = 0;
    144 }
    145 void ?{}( discrete_point & this, int x, int y ) { // ctor
    146     this.x = x;
    147     this.y = y;
    148 }
    149 void ^?{}( discrete_point & this ) with(this) { // dtor
    150     x = 0;
    151     y = 0;
    152 }
    153 
    154 int main() {
    155     discrete_point d; // implicit call to ?{}
    156     discrete_point p{}; // same call as line above
    157     discrete_point dp{ 2, -4 }; // specialized ctor
    158 } // ^d{}, ^p{}, ^dp{} all called as they go out of scope
    159 \end{cfacode}
     110        int x, y;
     111};
     112void ?{}( discrete_point & this ) with(this) { $\C{// default constructor}$
     113        [x, y] = 0;
     114}
     115void ?{}( discrete_point & this, int x, int y ) { $\C{// explicit constructor}$
     116        this.[x, y] = [x, y];
     117}
     118void ^?{}( discrete_point & this ) with(this) { $\C{// destructor}$
     119        ?{}( this );  $\C{// reset by calling default constructor}$
     120}
     121int main() {
     122        discrete_point x, y{};  $\C{// implicit call to default ctor, ?\{\}}$
     123        discrete_point s = { 2, -4 }, t{ 4, 2 };  $\C{// explicit call to specialized ctor}$
     124} // ^t{}, ^s{}, ^y{}, ^x{} implicit calls in reverse allocation order
     125\end{cfa}
    160126
    161127
    162128\section{Polymorphism}\label{s:poly}
    163 C does not natively support polymorphism, and requires users to implement polymorphism themselves if they want to use it.
    164 \CFA extends C with two styles of polymorphism that it supports, parametric polymorphism and nominal inheritance.
     129C supports limited polymorphism, often requiring users to implement polymorphism using a @void *@ (type erasure) approach.
     130\CFA extends C with generalized overloading polymorphism (see \VRef{s:Overloading}), as well as, parametric polymorphism and nominal inheritance.
    165131
    166132\subsection{Parametric Polymorphism}
    167 \CFA provides parametric polymorphism in the form of \code{forall}, and \code{trait}s.
    168 A \code{forall} takes in a set of types and a list of constraints.
    169 The declarations that follow the \code{forall} are parameterized over the types listed that satisfy the constraints.
    170 Sometimes the list of constraints can be long, which is where a \code{trait} can be used.
    171 A \code{trait} is a collection of constraints that is given a name and can be reused in foralls.
    172 An example of the usage of parametric polymorphism in \CFA is shown in Listing~\ref{l:cfa_poly}.
    173 
    174 \begin{cfacode}[tabsize=3,caption={Example of \CFA polymorphism},label={l:cfa_poly}]
     133\CFA provides parametric polymorphism in the form of @forall@, and @trait@s.
     134A @forall@ takes in a set of types and a list of constraints.
     135The declarations that follow the @forall@ are parameterized over the types listed that satisfy the constraints.
     136A list of @forall@ constraints can be refactored into a named @trait@ and reused in @forall@s.
     137Examples of \CFA parametric polymorphism are shown in \VRef[Listing]{l:cfa_poly}.
     138
     139\begin{cfa}[caption={Example of \CFA parametric polymorphism},label={l:cfa_poly}]
    175140// sized() is a trait that means the type has a size
    176 forall( V & | sized(V) )        // type params for trait
     141forall( V & | sized(V) )                $\C{// type params for trait}$
    177142trait vector_space {
    178     V add( V, V );              // vector addition
    179     V scalar_mult( int, V );    // scalar multiplication
    180 
    181     // dtor and copy ctor needed in constraints to pass by copy
    182     void ?{}( V &, V & );       // copy ctor for return
    183     void ^?{}( V & );           // dtor
    184 };
    185 
    186 forall( V & | vector_space( V )) {
    187     V get_inverse( V v1 ) {
    188         return scalar_mult( -1, v1 );  // can use ?*? routine defined in trait
    189     }
    190     V add_and_invert( V v1, V v2 ) {
    191         return get_inverse( add( v1, v2 ) );  // can use ?*? routine defined in trait
    192     }
     143        // dtor and copy ctor needed in constraints to pass by copy
     144        void ?{}( V &, V & );           $\C{// copy ctor for return}$
     145        void ^?{}( V & );                       $\C{// dtor}$
     146        V ?+?( V, V );                          $\C{// vector addition}$
     147        V ?*?( int, V );                        $\C{// scalar multiplication}$
     148};
     149
     150forall( V & | vector_space( V ) ) {
     151        V get_inverse( V v1 ) {
     152                return -1 * v1;                 $\C{// can use ?*? routine defined in trait}$
     153        }
     154        V add_and_invert( V v1, V v2 ) {
     155                return get_inverse( v1 + v2 );  $\C{// can use ?+? routine defined in trait}$
     156        }
    193157}
    194158struct Vec1 { int x; };
     
    196160void ?{}( Vec1 & this, int x ) { this.x = x; }
    197161void ^?{}( Vec1 & this ) {}
    198 Vec1 add( Vec1 v1, Vec1 v2 ) { v1.x += v2.x; return v1; }
    199 Vec1 scalar_mult( int c, Vec1 v1 ) { v1.x = v1.x * c; return v1; }
     162Vec1 ?+?( Vec1 v1, Vec1 v2 ) { v1.x += v2.x; return v1; }
     163Vec1 ?*?( int c, Vec1 v1 ) { v1.x = v1.x * c; return v1; }
    200164
    201165struct Vec2 { int x; int y; };
     
    203167void ?{}( Vec2 & this, int x ) { this.x = x; this.y = x; }
    204168void ^?{}( Vec2 & this ) {}
    205 Vec2 add( Vec2 v1, Vec2 v2 ) { v1.x += v2.x; v1.y += v2.y; return v1; }
    206 Vec2 scalar_mult( int c, Vec2 v1 ) { v1.x = v1.x * c; v1.y = v1.y * c; return v1; }
    207 
    208 int main() {
    209     Vec1 v1{ 1 }; // create Vec1 and call ctor
    210     Vec2 v2{ 2 }; // create Vec2 and call ctor
    211 
    212     // can use forall defined routines since types satisfy trait
    213     add_and_invert( get_inverse( v1 ), v1 );
    214     add_and_invert( get_inverse( v2 ), v2 );
    215 }
    216 
    217 \end{cfacode}
     169Vec2 ?+?( Vec2 v1, Vec2 v2 ) { v1.x += v2.x; v1.y += v2.y; return v1; }
     170Vec2 ?*?( int c, Vec2 v1 ) { v1.x = v1.x * c; v1.y = v1.y * c; return v1; }
     171
     172int main() {
     173        Vec1 v1{ 1 };                           $\C{// create Vec1 and call ctor}$
     174        Vec2 v2{ 2 };                           $\C{// create Vec2 and call ctor}$
     175        // can use forall defined routines since types satisfy trait
     176        add_and_invert( get_inverse( v1 ), v1 );
     177        add_and_invert( get_inverse( v2 ), v2 );
     178}
     179\end{cfa}
    218180
    219181\subsection{Inheritance}
    220 Inheritance in \CFA copies its style from Plan-9 C nominal inheritance.
    221 In \CFA structs can \code{inline} another struct type to gain its fields and to be able to be passed to routines that require a parameter of the inlined type.
    222 An example of \CFA inheritance is shown in Listing~\ref{l:cfa_inherit}.
    223 
    224 \begin{cfacode}[tabsize=3,caption={Example of \CFA inheritance},label={l:cfa_inherit}]
     182Inheritance in \CFA is taken from Plan-9 C's containment inheritance.
     183In \CFA, @struct@s can @inline@ another struct type to gain its fields and masquerade as that type.
     184Examples of \CFA containment inheritance are shown in \VRef[Listing]{l:cfa_inherit}.
     185
     186\begin{cfa}[caption={Example of \CFA containment inheritance},label={l:cfa_inherit}]
    225187struct one_d { double x; };
    226188struct two_d {
    227     inline one_d;
    228     double y;
     189        @inline@ one_d;
     190        double y;
    229191};
    230192struct three_d {
    231     inline two_d;
    232     double z;
     193        @inline@ two_d;
     194        double z;
    233195};
    234196double get_x( one_d & d ){ return d.x; }
     
    236198struct dog {};
    237199struct dog_food {
    238     int count;
     200        int count;
    239201};
    240202struct pet {
    241     inline dog;
    242     inline dog_food;
    243 };
    244 void pet_dog( dog & d ){printf("woof\n");}
    245 void print_food( dog_food & f ){printf("%d\n", f.count);}
    246 
    247 int main() {
    248     one_d x;
    249     two_d y;
    250     three_d z;
    251     x.x = 1;
    252     y.x = 2;
    253     z.x = 3;
    254     get_x( x ); // returns 1;
    255     get_x( y ); // returns 2;
    256     get_x( z ); // returns 3;
    257     pet p;
    258     p.count = 5;
    259     pet_dog( p );    // prints woof
    260     print_food( p ); // prints 5
    261 }
    262 \end{cfacode}
    263 
    264 
     203        @inline@ dog;
     204        @inline@ dog_food;
     205};
     206void pet_dog( dog & d ) { sout | "woof"; }
     207void print_food( dog_food & f ) { sout | f.count; }
     208
     209int main() {
     210        one_d x;
     211        two_d y;
     212        three_d z;
     213        x.x = 1;
     214        y.x = 2;
     215        z.x = 3;
     216        get_x( x );                                     $\C{// returns 1;}$
     217        get_x( y );                                     $\C{// returns 2;}$
     218        get_x( z );                                     $\C{// returns 3;}$
     219        pet p;
     220        p.count = 5;
     221        pet_dog( p );                           $\C{// prints woof}$
     222        print_food( p );                        $\C{// prints 5}$
     223}
     224\end{cfa}
     225
     226% Local Variables: %
     227% tab-width: 4 %
     228% End: %
  • doc/theses/colby_parsons_MMAth/text/actors.tex

    rff71057 re02e13f  
    8888Similarly to create a message type a user must define a struct which \code{inline}'s the base \code{message} struct.
    8989
    90 \begin{cfacode}
     90\begin{cfa}
    9191struct derived_actor {
    9292    inline actor;       // Plan-9 C inheritance
     
    118118    return 0;
    119119}
    120 \end{cfacode}
     120\end{cfa}
    121121
    122122The above code is a simple actor program in \CFA.
     
    125125Key things to highlight include the \code{receive} signature, and calls to \code{start_actor_system}, and \code{stop_actor_system}.
    126126To define a behaviour for some derived actor and derived message type, one must declare a routine with the signature:
    127 \begin{cfacode}
     127\begin{cfa}
    128128Allocation receive( derived_actor & receiver, derived_msg & msg )
    129 \end{cfacode}
     129\end{cfa}
    130130Where \code{derived_actor} and \code{derived_msg} can be any derived actor and derived message types respectively.
    131131The return value of \code{receive} must be a value from the \code{Allocation} enum:
    132 \begin{cfacode}
     132\begin{cfa}
    133133enum Allocation { Nodelete, Delete, Destroy, Finished };
    134 \end{cfacode}
     134\end{cfa}
    135135The \code{Allocation} enum is a set of actions that dictate what the executor should do with a message or actor after a given behaviour has been completed.
    136136In the case of an actor, the \code{receive} routine returns the \code{Allocation} status to the executor which sets the status on the actor and takes the appropriate action.
    137137For messages, they either default to \code{Nodelete}, or they can be passed an \code{Allocation} via the \code{message} constructor.
    138138Message state can be updated via a call to:
    139 \begin{cfacode}
     139\begin{cfa}
    140140void set_allocation( message & this, Allocation state )
    141 \end{cfacode}
     141\end{cfa}
    142142
    143143The following describes the use of each of the \code{Allocation} values:
     
    186186All message sends are done using the left shift operater, \ie <<, similar to the syntax of \CC's output.
    187187The signature of the left shift operator is:
    188 \begin{cfacode}
     188\begin{cfa}
    189189Allocation ?<<?( derived_actor & receiver, derived_msg & msg )
    190 \end{cfacode}
     190\end{cfa}
    191191
    192192An astute eye will notice that this is the same signature as the \code{receive} routine which is no coincidence.
     
    368368To first verify sequential correctness, consider the equivalent sequential swap below:
    369369
    370 \begin{cfacode}
     370\begin{cfa}
    371371void swap( uint victim_idx, uint my_idx  ) {
    372372    // Step 0:
     
    380380    request_queues[my_idx] = vic_queue;
    381381}
    382 \end{cfacode}
     382\end{cfa}
    383383
    384384Step 1 is missing in the sequential example since in only matter in the concurrent context presented later.
     
    386386Temporary copies of each pointer being swapped are stored, and then the original values of each pointer are set using the copy of the other pointer.
    387387
    388 \begin{cfacode}
     388\begin{cfa}
    389389// This routine is atomic
    390390bool CAS( work_queue ** ptr, work_queue ** old, work_queue * new ) {
     
    427427    return true;
    428428}
    429 \end{cfacode}\label{c:swap}
     429\end{cfa}\label{c:swap}
    430430
    431431Now consider the concurrent implementation of the swap.
  • doc/theses/colby_parsons_MMAth/text/channels.tex

    rff71057 re02e13f  
    118118Also note that in the Go version~\ref{l:go_chan_bar}, the size of the barrier channels has to be larger than in the \CFA version to ensure that the main thread does not block when attempting to clear the barrier.
    119119
    120 \begin{cfacode}[tabsize=3,caption={\CFA channel barrier termination},label={l:cfa_chan_bar}]
     120\begin{cfa}[tabsize=3,caption={\CFA channel barrier termination},label={l:cfa_chan_bar}]
    121121struct barrier {
    122122    channel( int ) barWait;
     
    171171    return 0;
    172172}
    173 \end{cfacode}
    174 
    175 \begin{cfacode}[tabsize=3,caption={Go channel barrier termination},label={l:go_chan_bar}]
     173\end{cfa}
     174
     175\begin{cfa}[tabsize=3,caption={Go channel barrier termination},label={l:go_chan_bar}]
    176176
    177177struct barrier {
     
    237237    return 0;
    238238}
    239 \end{cfacode}
     239\end{cfa}
    240240
    241241In Listing~\ref{l:cfa_resume} an example of channel closing with resumption is used.
     
    244244If the same program was implemented in Go it would require explicit synchronization with both producers and consumers by some mechanism outside the channel to ensure that all elements were removed before task termination.
    245245
    246 \begin{cfacode}[tabsize=3,caption={\CFA channel resumption usage},label={l:cfa_resume}]
     246\begin{cfa}[tabsize=3,caption={\CFA channel resumption usage},label={l:cfa_resume}]
    247247channel( int ) chan{ 128 };
    248248
     
    280280    return 0;
    281281}
    282 \end{cfacode}
     282\end{cfa}
    283283
    284284\section{Performance}
  • doc/theses/colby_parsons_MMAth/text/mutex_stmt.tex

    rff71057 re02e13f  
    1212Additionally, it provides the safety guarantee of deadlock-freedom, both by acquiring the locks in a deadlock-free manner, and by ensuring that the locks release on error, or normal program execution via \gls{raii}.
    1313
    14 \begin{cfacode}[tabsize=3,caption={\CFA mutex statement usage},label={l:cfa_mutex_ex}]
     14\begin{cfa}[tabsize=3,caption={\CFA mutex statement usage},label={l:cfa_mutex_ex}]
    1515owner_lock lock1, lock2, lock3;
    1616int count = 0;
     
    2020}
    2121mutex( lock2, lock3 ) count++; // or inline statement
    22 \end{cfacode}
     22\end{cfa}
    2323
    2424\section{Other Languages}
     
    3232An example of \CC scoped\_lock usage is shown in Listing~\ref{l:cc_scoped_lock}.
    3333
    34 \begin{cppcode}[tabsize=3,caption={\CC scoped\_lock usage},label={l:cc_scoped_lock}]
     34\begin{cfa}[tabsize=3,caption={\CC scoped\_lock usage},label={l:cc_scoped_lock}]
    3535std::mutex lock1, lock2, lock3;
    3636{
     
    3838    // locks are released via raii at end of scope
    3939}
    40 \end{cppcode}
     40\end{cfa}
    4141
    4242\section{\CFA implementation}
     
    5858This use case is shown in Listing~\ref{l:sout}.
    5959
    60 \begin{cfacode}[tabsize=3,caption={\CFA sout with mutex statement},label={l:sout}]
     60\begin{cfa}[tabsize=3,caption={\CFA sout with mutex statement},label={l:sout}]
    6161mutex( sout )
    6262    sout | "This output is protected by mutual exclusion!";
    63 \end{cfacode}
     63\end{cfa}
    6464
    6565\section{Deadlock Avoidance}
     
    7070The algorithm presented is taken directly from the source code of the \code{<mutex>} header, with some renaming and comments for clarity.
    7171
    72 \begin{cppcode}[caption={\CC scoped\_lock deadlock avoidance algorithm},label={l:cc_deadlock_avoid}]
     72\begin{cfa}[caption={\CC scoped\_lock deadlock avoidance algorithm},label={l:cc_deadlock_avoid}]
    7373int first = 0;  // first lock to attempt to lock
    7474do {
     
    8686// if first lock is still held then all have been acquired
    8787} while (!locks[first].owns_lock());  // is first lock held?
    88 \end{cppcode}
     88\end{cfa}
    8989
    9090The algorithm in \ref{l:cc_deadlock_avoid} successfully avoids deadlock, however there is a potential livelock scenario.
  • doc/theses/colby_parsons_MMAth/thesis.tex

    rff71057 re02e13f  
    9898\hypersetup{
    9999    plainpages=false,       % needed if Roman numbers in frontpages
    100     unicode=false,          % non-Latin characters in Acrobats bookmarks
    101     pdftoolbar=true,        % show Acrobats toolbar?
    102     pdfmenubar=true,        % show Acrobats menu?
     100    unicode=false,          % non-Latin characters in Acrobat's bookmarks
     101    pdftoolbar=true,        % show Acrobat's toolbar?
     102    pdfmenubar=true,        % show Acrobat's menu?
    103103    pdffitwindow=false,     % window fit to page when opened
    104104    pdfstartview={FitH},    % fits the width of the page to the window
     
    110110    colorlinks=true,        % false: boxed links; true: colored links
    111111    linkcolor=blue,         % color of internal links
    112     citecolor=green,        % color of links to bibliography
     112    citecolor=blue,        % color of links to bibliography
    113113    filecolor=magenta,      % color of file links
    114114    urlcolor=cyan           % color of external links
  • src/AST/SymbolTable.cpp

    rff71057 re02e13f  
    7070        if ( baseExpr ) {
    7171                if (baseExpr->env) {
    72                         Expr * base = shallowCopy(baseExpr);
     72                        Expr * base = deepCopy(baseExpr);
    7373                        const TypeSubstitution * subs = baseExpr->env;
    7474                        base->env = nullptr;
  • src/Parser/DeclarationNode.cc

    rff71057 re02e13f  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Mar 14 11:56:00 2023
    13 // Update Count     : 1406
     12// Last Modified On : Tue Apr  4 10:28:00 2023
     13// Update Count     : 1392
    1414//
    1515
     
    2121#include <string>                  // for string, operator+, allocator, char...
    2222
     23#include "AST/Attribute.hpp"       // for Attribute
     24#include "AST/Copy.hpp"            // for shallowCopy
     25#include "AST/Decl.hpp"            // for Decl
     26#include "AST/Expr.hpp"            // for Expr
     27#include "AST/Print.hpp"           // for print
     28#include "AST/Stmt.hpp"            // for AsmStmt, DirectiveStmt
     29#include "AST/StorageClasses.hpp"  // for Storage::Class
     30#include "AST/Type.hpp"            // for Type
     31#include "Common/CodeLocation.h"   // for CodeLocation
     32#include "Common/Iterate.hpp"      // for reverseIterate
    2333#include "Common/SemanticError.h"  // for SemanticError
    2434#include "Common/UniqueName.h"     // for UniqueName
    25 #include "Common/utility.h"        // for maybeClone, maybeBuild, CodeLocation
     35#include "Common/utility.h"        // for maybeClone
    2636#include "Parser/ParseNode.h"      // for DeclarationNode, ExpressionNode
    27 #include "SynTree/LinkageSpec.h"   // for Spec, linkageName, Cforall
    28 #include "SynTree/Attribute.h"     // for Attribute
    29 #include "SynTree/Declaration.h"   // for TypeDecl, ObjectDecl, InlineMemberDecl, Declaration
    30 #include "SynTree/Expression.h"    // for Expression, ConstantExpr
    31 #include "SynTree/Statement.h"     // for AsmStmt
    32 #include "SynTree/Type.h"          // for Type, Type::StorageClasses, Type::...
    3337#include "TypeData.h"              // for TypeData, TypeData::Aggregate_t
    3438#include "TypedefTable.h"          // for TypedefTable
     
    6165UniqueName DeclarationNode::anonymous( "__anonymous" );
    6266
    63 extern LinkageSpec::Spec linkage;                                               // defined in parser.yy
     67extern ast::Linkage::Spec linkage;                                              // defined in parser.yy
    6468
    6569DeclarationNode::DeclarationNode() :
     
    6771
    6872//      variable.name = nullptr;
    69         variable.tyClass = TypeDecl::NUMBER_OF_KINDS;
     73        variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS;
    7074        variable.assertions = nullptr;
    7175        variable.initializer = nullptr;
     
    105109        newnode->hasEllipsis = hasEllipsis;
    106110        newnode->linkage = linkage;
    107         newnode->asmName = maybeClone( asmName );
    108         cloneAll( attributes, newnode->attributes );
     111        newnode->asmName = maybeCopy( asmName );
     112        newnode->attributes = attributes;
    109113        newnode->initializer = maybeClone( initializer );
    110114        newnode->extension = extension;
     
    118122
    119123        newnode->assert.condition = maybeClone( assert.condition );
    120         newnode->assert.message = maybeClone( assert.message );
     124        newnode->assert.message = maybeCopy( assert.message );
    121125        return newnode;
    122126} // DeclarationNode::clone
     
    128132        } // if
    129133
    130         if ( linkage != LinkageSpec::Cforall ) {
    131                 os << LinkageSpec::name( linkage ) << " ";
    132         } // if
    133 
    134         storageClasses.print( os );
    135         funcSpecs.print( os );
     134        if ( linkage != ast::Linkage::Cforall ) {
     135                os << ast::Linkage::name( linkage ) << " ";
     136        } // if
     137
     138        ast::print( os, storageClasses );
     139        ast::print( os, funcSpecs );
    136140
    137141        if ( type ) {
     
    154158        if ( ! attributes.empty() ) {
    155159                os << string( indent + 2, ' ' ) << "with attributes " << endl;
    156                 for ( Attribute * attr: reverseIterate( attributes ) ) {
     160                for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( attributes ) ) {
    157161                        os << string( indent + 4, ' ' ) << attr->name.c_str() << endl;
    158162                } // for
     
    169173}
    170174
    171 DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) {
     175DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) {
    172176        DeclarationNode * newnode = new DeclarationNode;
    173177        newnode->storageClasses = sc;
     
    175179} // DeclarationNode::newStorageClass
    176180
    177 DeclarationNode * DeclarationNode::newFuncSpecifier( Type::FuncSpecifiers fs ) {
     181DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) {
    178182        DeclarationNode * newnode = new DeclarationNode;
    179183        newnode->funcSpecs = fs;
     
    181185} // DeclarationNode::newFuncSpecifier
    182186
    183 DeclarationNode * DeclarationNode::newTypeQualifier( Type::Qualifiers tq ) {
     187DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) {
    184188        DeclarationNode * newnode = new DeclarationNode;
    185189        newnode->type = new TypeData();
     
    241245}
    242246
    243 DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
     247DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
    244248        DeclarationNode * newnode = new DeclarationNode;
    245249        newnode->type = new TypeData( TypeData::Aggregate );
     
    271275} // DeclarationNode::newEnum
    272276
    273 
    274 
    275277DeclarationNode * DeclarationNode::newName( const string * name ) {
    276278        DeclarationNode * newnode = new DeclarationNode;
     
    324326} // DeclarationNode::newFromTypeGen
    325327
    326 DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) {
     328DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) {
    327329        DeclarationNode * newnode = newName( name );
    328330        newnode->type = nullptr;
     
    336338        newnode->type = new TypeData( TypeData::Aggregate );
    337339        newnode->type->aggregate.name = name;
    338         newnode->type->aggregate.kind = AggregateDecl::Trait;
     340        newnode->type->aggregate.kind = ast::AggregateDecl::Trait;
    339341        newnode->type->aggregate.params = params;
    340342        newnode->type->aggregate.fields = asserts;
     
    346348        newnode->type = new TypeData( TypeData::AggregateInst );
    347349        newnode->type->aggInst.aggregate = new TypeData( TypeData::Aggregate );
    348         newnode->type->aggInst.aggregate->aggregate.kind = AggregateDecl::Trait;
     350        newnode->type->aggInst.aggregate->aggregate.kind = ast::AggregateDecl::Trait;
    349351        newnode->type->aggInst.aggregate->aggregate.name = name;
    350352        newnode->type->aggInst.params = params;
     
    381383        newnode->type->array.dimension = size;
    382384        newnode->type->array.isStatic = isStatic;
    383         if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ConstantExpr * >() ) {
     385        if ( newnode->type->array.dimension == nullptr || newnode->type->array.dimension->isExpressionType<ast::ConstantExpr *>() ) {
    384386                newnode->type->array.isVarLen = false;
    385387        } else {
     
    451453        DeclarationNode * newnode = new DeclarationNode;
    452454        newnode->type = nullptr;
    453         std::list< Expression * > exprs;
     455        std::vector<ast::ptr<ast::Expr>> exprs;
    454456        buildList( expr, exprs );
    455         newnode->attributes.push_back( new Attribute( *name, exprs ) );
     457        newnode->attributes.push_back(
     458                new ast::Attribute( *name, std::move( exprs ) ) );
    456459        delete name;
    457460        return newnode;
     
    470473}
    471474
    472 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression * message ) {
     475DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr * message ) {
    473476        DeclarationNode * newnode = new DeclarationNode;
    474477        newnode->assert.condition = condition;
     
    477480}
    478481
    479 
    480 void appendError( string & dst, const string & src ) {
     482static void appendError( string & dst, const string & src ) {
    481483        if ( src.empty() ) return;
    482484        if ( dst.empty() ) { dst = src; return; }
     
    485487
    486488void DeclarationNode::checkQualifiers( const TypeData * src, const TypeData * dst ) {
    487         const Type::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
    488 
    489         if ( (qsrc & qdst).any() ) {                                            // duplicates ?
    490                 for ( unsigned int i = 0; i < Type::NumTypeQualifier; i += 1 ) { // find duplicates
    491                         if ( qsrc[i] && qdst[i] ) {
    492                                 appendError( error, string( "duplicate " ) + Type::QualifiersNames[i] );
    493                         } // if
    494                 } // for
     489        const ast::CV::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
     490        const ast::CV::Qualifiers duplicates = qsrc & qdst;
     491
     492        if ( duplicates.any() ) {
     493                std::stringstream str;
     494                str << "duplicate ";
     495                ast::print( str, duplicates );
     496                str << "qualifier(s)";
     497                appendError( error, str.str() );
    495498        } // for
    496499} // DeclarationNode::checkQualifiers
    497500
    498501void DeclarationNode::checkSpecifiers( DeclarationNode * src ) {
    499         if ( (funcSpecs & src->funcSpecs).any() ) {                     // duplicates ?
    500                 for ( unsigned int i = 0; i < Type::NumFuncSpecifier; i += 1 ) { // find duplicates
    501                         if ( funcSpecs[i] && src->funcSpecs[i] ) {
    502                                 appendError( error, string( "duplicate " ) + Type::FuncSpecifiersNames[i] );
    503                         } // if
    504                 } // for
    505         } // if
    506 
    507         if ( storageClasses.any() && src->storageClasses.any() ) { // any reason to check ?
    508                 if ( (storageClasses & src->storageClasses ).any() ) { // duplicates ?
    509                         for ( unsigned int i = 0; i < Type::NumStorageClass; i += 1 ) { // find duplicates
    510                                 if ( storageClasses[i] && src->storageClasses[i] ) {
    511                                         appendError( error, string( "duplicate " ) + Type::StorageClassesNames[i] );
    512                                 } // if
    513                         } // for
    514                         // src is the new item being added and has a single bit
    515                 } else if ( ! src->storageClasses.is_threadlocal_any() ) { // conflict ?
    516                         appendError( error, string( "conflicting " )
    517                                 + Type::StorageClassesNames[storageClasses.ffs()]
    518                                 + " & " + Type::StorageClassesNames[src->storageClasses.ffs()] );
    519                         src->storageClasses.reset();                            // FIX to preserve invariant of one basic storage specifier
    520                 } // if
     502        ast::Function::Specs fsDups = funcSpecs & src->funcSpecs;
     503        if ( fsDups.any() ) {
     504                std::stringstream str;
     505                str << "duplicate ";
     506                ast::print( str, fsDups );
     507                str << "function specifier(s)";
     508                appendError( error, str.str() );
     509        } // if
     510
     511        // Skip if everything is unset.
     512        if ( storageClasses.any() && src->storageClasses.any() ) {
     513                ast::Storage::Classes dups = storageClasses & src->storageClasses;
     514                // Check for duplicates.
     515                if ( dups.any() ) {
     516                        std::stringstream str;
     517                        str << "duplicate ";
     518                        ast::print( str, dups );
     519                        str << "storage class(es)";
     520                        appendError( error, str.str() );
     521                // Check for conflicts.
     522                } else if ( !src->storageClasses.is_threadlocal_any() ) {
     523                        std::stringstream str;
     524                        str << "conflicting ";
     525                        ast::print( str, ast::Storage::Classes( 1 << storageClasses.ffs() ) );
     526                        str << "& ";
     527                        ast::print( str, ast::Storage::Classes( 1 << src->storageClasses.ffs() ) );
     528                        str << "storage classes";
     529                        appendError( error, str.str() );
     530                        // FIX to preserve invariant of one basic storage specifier
     531                        src->storageClasses.reset();
     532                }
    521533        } // if
    522534
     
    528540        storageClasses |= q->storageClasses;
    529541
    530         for ( Attribute * attr: reverseIterate( q->attributes ) ) {
    531                 attributes.push_front( attr->clone() );
    532         } // for
     542        std::vector<ast::ptr<ast::Attribute>> tmp;
     543        tmp.reserve( q->attributes.size() );
     544        for ( auto const & attr : q->attributes ) {
     545                tmp.emplace_back( ast::shallowCopy( attr.get() ) );
     546        }
     547        spliceBegin( attributes, tmp );
     548
    533549        return this;
    534550} // DeclarationNode::copySpecifiers
     
    716732
    717733DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) {
    718         if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
     734        if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
    719735                if ( variable.assertions ) {
    720736                        variable.assertions->appendList( assertions );
     
    798814DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) {
    799815        if ( a ) {
    800                 for ( Attribute *attr: reverseIterate( a->attributes ) ) {
    801                         attributes.push_front( attr );
    802                 } // for
     816                spliceBegin( attributes, a->attributes );
    803817                a->attributes.clear();
    804818        } // if
     
    921935
    922936DeclarationNode * DeclarationNode::addTypeInitializer( DeclarationNode * init ) {
    923         assertf( variable.tyClass != TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
     937        assertf( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS, "Called addTypeInitializer on something that isn't a type variable." );
    924938        variable.initializer = init;
    925939        return this;
     
    985999}
    9861000
    987 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) {
     1001void buildList( const DeclarationNode * firstNode,
     1002                std::vector<ast::ptr<ast::Decl>> & outputList ) {
    9881003        SemanticErrorException errors;
    989         std::back_insert_iterator< std::list< Declaration * > > out( outputList );
     1004        std::back_insert_iterator<std::vector<ast::ptr<ast::Decl>>> out( outputList );
    9901005
    9911006        for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
    9921007                try {
    9931008                        bool extracted = false, anon = false;
    994                         AggregateDecl * unionDecl = nullptr;
     1009                        ast::AggregateDecl * unionDecl = nullptr;
    9951010
    9961011                        if ( DeclarationNode * extr = cur->extractAggregate() ) {
     
    10291044                                } // if
    10301045
    1031                                 Declaration * decl = extr->build();
     1046                                ast::Decl * decl = extr->build();
    10321047                                if ( decl ) {
    10331048                                        // Remember the declaration if it is a union aggregate ?
    1034                                         unionDecl = dynamic_cast<UnionDecl *>( decl );
     1049                                        unionDecl = dynamic_cast<ast::UnionDecl *>( decl );
    10351050
    10361051                                        decl->location = cur->location;
     
    10511066                        } // if
    10521067
    1053                         Declaration * decl = cur->build();
     1068                        ast::Decl * decl = cur->build();
    10541069                        if ( decl ) {
    1055                                 if ( TypedefDecl * typedefDecl = dynamic_cast<TypedefDecl *>( decl ) ) {
     1070                                if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) {
    10561071                                        if ( unionDecl ) {                                      // is the typedef alias a union aggregate ?
    10571072                                                // This code handles a special issue with the attribute transparent_union.
     
    10651080
    10661081                                                // If typedef is an alias for a union, then its alias type was hoisted above and remembered.
    1067                                                 if ( UnionInstType * unionInstType = dynamic_cast<UnionInstType *>( typedefDecl->base ) ) {
     1082                                                if ( auto unionInstType = typedefDecl->base.as<ast::UnionInstType>() ) {
     1083                                                        auto instType = ast::mutate( unionInstType );
    10681084                                                        // Remove all transparent_union attributes from typedef and move to alias union.
    1069                                                         list<Attribute *>::iterator attr;
    1070                                                         for ( attr = unionInstType->attributes.begin(); attr != unionInstType->attributes.end(); ) { // forward order
     1085                                                        for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) { // forward order
     1086                                                                assert( *attr );
    10711087                                                                if ( (*attr)->name == "transparent_union" || (*attr)->name == "__transparent_union__" ) {
    1072                                                                         list<Attribute *>::iterator cur = attr; // remember current node
    1073                                                                         attr++;                         // advance iterator
    1074                                                                         unionDecl->attributes.emplace_back( *cur ); // move current
    1075                                                                         unionInstType->attributes.erase( cur ); // remove current
     1088                                                                        unionDecl->attributes.emplace_back( attr->release() );
     1089                                                                        attr = instType->attributes.erase( attr );
    10761090                                                                } else {
    1077                                                                         attr++;                         // advance iterator
     1091                                                                        attr++;
    10781092                                                                } // if
    10791093                                                        } // for
     1094                                                        typedefDecl->base = instType;
    10801095                                                } // if
    10811096                                        } // if
     
    10901105                                if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) {
    10911106                                        if ( decl->name == "" ) {
    1092                                                 if ( DeclarationWithType * dwt = dynamic_cast<DeclarationWithType *>( decl ) ) {
    1093                                                         if ( ReferenceToType * aggr = dynamic_cast<ReferenceToType *>( dwt->get_type() ) ) {
     1107                                                if ( auto dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
     1108                                                        if ( auto aggr = dynamic_cast<ast::BaseInstType const *>( dwt->get_type() ) ) {
    10941109                                                                if ( aggr->name.find("anonymous") == std::string::npos ) {
    10951110                                                                        if ( ! cur->get_inLine() ) {
     
    11171132
    11181133// currently only builds assertions, function parameters, and return values
    1119 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList ) {
     1134void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) {
    11201135        SemanticErrorException errors;
    1121         std::back_insert_iterator< std::list< DeclarationWithType * > > out( outputList );
     1136        std::back_insert_iterator<std::vector<ast::ptr<ast::DeclWithType>>> out( outputList );
    11221137
    11231138        for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) {
    11241139                try {
    1125                         Declaration * decl = cur->build();
     1140                        ast::Decl * decl = cur->build();
    11261141                        assert( decl );
    1127                         if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
     1142                        if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) {
    11281143                                dwt->location = cur->location;
    11291144                                *out++ = dwt;
    1130                         } else if ( StructDecl * agg = dynamic_cast< StructDecl * >( decl ) ) {
     1145                        } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) {
    11311146                                // e.g., int foo(struct S) {}
    1132                                 StructInstType * inst = new StructInstType( Type::Qualifiers(), agg->name );
    1133                                 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    1134                                 obj->location = cur->location;
     1147                                auto inst = new ast::StructInstType( agg->name );
     1148                                auto obj = new ast::ObjectDecl( cur->location, "", inst );
     1149                                obj->linkage = linkage;
    11351150                                *out++ = obj;
    11361151                                delete agg;
    1137                         } else if ( UnionDecl * agg = dynamic_cast< UnionDecl * >( decl ) ) {
     1152                        } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) {
    11381153                                // e.g., int foo(union U) {}
    1139                                 UnionInstType * inst = new UnionInstType( Type::Qualifiers(), agg->name );
    1140                                 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    1141                                 obj->location = cur->location;
     1154                                auto inst = new ast::UnionInstType( agg->name );
     1155                                auto obj = new ast::ObjectDecl( cur->location,
     1156                                        "", inst, nullptr, ast::Storage::Classes(),
     1157                                        linkage );
    11421158                                *out++ = obj;
    1143                         } else if ( EnumDecl * agg = dynamic_cast< EnumDecl * >( decl ) ) {
     1159                        } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) {
    11441160                                // e.g., int foo(enum E) {}
    1145                                 EnumInstType * inst = new EnumInstType( Type::Qualifiers(), agg->name );
    1146                                 auto obj = new ObjectDecl( "", Type::StorageClasses(), linkage, nullptr, inst, nullptr );
    1147                                 obj->location = cur->location;
     1161                                auto inst = new ast::EnumInstType( agg->name );
     1162                                auto obj = new ast::ObjectDecl( cur->location,
     1163                                        "",
     1164                                        inst,
     1165                                        nullptr,
     1166                                        ast::Storage::Classes(),
     1167                                        linkage
     1168                                );
    11481169                                *out++ = obj;
    11491170                        } // if
     
    11581179} // buildList
    11591180
    1160 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) {
     1181void buildTypeList( const DeclarationNode * firstNode,
     1182                std::vector<ast::ptr<ast::Type>> & outputList ) {
    11611183        SemanticErrorException errors;
    1162         std::back_insert_iterator< std::list< Type * > > out( outputList );
     1184        std::back_insert_iterator<std::vector<ast::ptr<ast::Type>>> out( outputList );
    11631185        const DeclarationNode * cur = firstNode;
    11641186
     
    11771199} // buildTypeList
    11781200
    1179 Declaration * DeclarationNode::build() const {
     1201ast::Decl * DeclarationNode::build() const {
    11801202        if ( ! error.empty() ) SemanticError( this, error + " in declaration of " );
    11811203
    11821204        if ( asmStmt ) {
    1183                 return new AsmDecl( strict_dynamic_cast<AsmStmt *>( asmStmt->build() ) );
     1205                auto stmt = strict_dynamic_cast<ast::AsmStmt *>( asmStmt->build() );
     1206                return new ast::AsmDecl( stmt->location, stmt );
    11841207        } // if
    11851208        if ( directiveStmt ) {
    1186                 return new DirectiveDecl( strict_dynamic_cast<DirectiveStmt *>( directiveStmt->build() ) );
    1187         } // if
    1188 
    1189         if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {
     1209                auto stmt = strict_dynamic_cast<ast::DirectiveStmt *>( directiveStmt->build() );
     1210                return new ast::DirectiveDecl( stmt->location, stmt );
     1211        } // if
     1212
     1213        if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) {
    11901214                // otype is internally converted to dtype + otype parameters
    1191                 static const TypeDecl::Kind kindMap[] = { TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Dtype, TypeDecl::Ftype, TypeDecl::Ttype, TypeDecl::Dimension };
    1192                 static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
     1215                static const ast::TypeDecl::Kind kindMap[] = { ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Dtype, ast::TypeDecl::Ftype, ast::TypeDecl::Ttype, ast::TypeDecl::Dimension };
     1216                static_assert( sizeof(kindMap) / sizeof(kindMap[0]) == ast::TypeDecl::NUMBER_OF_KINDS, "DeclarationNode::build: kindMap is out of sync." );
    11931217                assertf( variable.tyClass < sizeof(kindMap)/sizeof(kindMap[0]), "Variable's tyClass is out of bounds." );
    1194                 TypeDecl * ret = new TypeDecl( *name, Type::StorageClasses(), nullptr, kindMap[ variable.tyClass ], variable.tyClass == TypeDecl::Otype || variable.tyClass == TypeDecl::DStype, variable.initializer ? variable.initializer->buildType() : nullptr );
    1195                 buildList( variable.assertions, ret->get_assertions() );
     1218                ast::TypeDecl * ret = new ast::TypeDecl( location,
     1219                        *name,
     1220                        ast::Storage::Classes(),
     1221                        (ast::Type *)nullptr,
     1222                        kindMap[ variable.tyClass ],
     1223                        variable.tyClass == ast::TypeDecl::Otype || variable.tyClass == ast::TypeDecl::DStype,
     1224                        variable.initializer ? variable.initializer->buildType() : nullptr
     1225                );
     1226                buildList( variable.assertions, ret->assertions );
    11961227                return ret;
    11971228        } // if
     
    12151246                } // if
    12161247                bool isDelete = initializer && initializer->get_isDelete();
    1217                 Declaration * decl = buildDecl( type, name ? *name : string( "" ), storageClasses, maybeBuild( bitfieldWidth ), funcSpecs, linkage, asmName, isDelete ? nullptr : maybeBuild(initializer), attributes )->set_extension( extension );
     1248                ast::Decl * decl = buildDecl(
     1249                        type,
     1250                        name ? *name : string( "" ),
     1251                        storageClasses,
     1252                        maybeBuild( bitfieldWidth ),
     1253                        funcSpecs,
     1254                        linkage,
     1255                        asmName,
     1256                        isDelete ? nullptr : maybeBuild( initializer ),
     1257                        copy( attributes )
     1258                )->set_extension( extension );
    12181259                if ( isDelete ) {
    1219                         DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl );
     1260                        auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl );
    12201261                        dwt->isDeleted = true;
    12211262                }
     
    12241265
    12251266        if ( assert.condition ) {
    1226                 return new StaticAssertDecl( maybeBuild( assert.condition ), strict_dynamic_cast< ConstantExpr * >( maybeClone( assert.message ) ) );
     1267                auto cond = maybeBuild( assert.condition );
     1268                auto msg = strict_dynamic_cast<ast::ConstantExpr *>( maybeCopy( assert.message ) );
     1269                return new ast::StaticAssertDecl( location, cond, msg );
    12271270        }
    12281271
     
    12351278        } // if
    12361279        if ( enumInLine ) {
    1237                 return new InlineMemberDecl( *name, storageClasses, linkage, nullptr );
     1280                return new ast::InlineMemberDecl( location,
     1281                        *name, (ast::Type*)nullptr, storageClasses, linkage );
    12381282        } // if
    12391283        assertf( name, "ObjectDecl must a have name\n" );
    1240         return (new ObjectDecl( *name, storageClasses, linkage, maybeBuild( bitfieldWidth ), nullptr, maybeBuild( initializer ) ))->set_asmName( asmName )->set_extension( extension );
    1241 }
    1242 
    1243 Type * DeclarationNode::buildType() const {
     1284        auto ret = new ast::ObjectDecl( location,
     1285                *name,
     1286                (ast::Type*)nullptr,
     1287                maybeBuild( initializer ),
     1288                storageClasses,
     1289                linkage,
     1290                maybeBuild( bitfieldWidth )
     1291        );
     1292        ret->asmName = asmName;
     1293        ret->extension = extension;
     1294        return ret;
     1295}
     1296
     1297ast::Type * DeclarationNode::buildType() const {
    12441298        assert( type );
    12451299
     
    12471301        case TypeData::Enum:
    12481302        case TypeData::Aggregate: {
    1249                 ReferenceToType * ret = buildComAggInst( type, attributes, linkage );
    1250                 buildList( type->aggregate.actuals, ret->get_parameters() );
     1303                ast::BaseInstType * ret =
     1304                        buildComAggInst( type, copy( attributes ), linkage );
     1305                buildList( type->aggregate.actuals, ret->params );
    12511306                return ret;
    12521307        }
    12531308        case TypeData::Symbolic: {
    1254                 TypeInstType * ret = new TypeInstType( buildQualifiers( type ), *type->symbolic.name, false, attributes );
    1255                 buildList( type->symbolic.actuals, ret->get_parameters() );
     1309                ast::TypeInstType * ret = new ast::TypeInstType(
     1310                        *type->symbolic.name,
     1311                        // This is just a default, the true value is not known yet.
     1312                        ast::TypeDecl::Dtype,
     1313                        buildQualifiers( type ),
     1314                        copy( attributes ) );
     1315                buildList( type->symbolic.actuals, ret->params );
    12561316                return ret;
    12571317        }
    12581318        default:
    1259                 Type * simpletypes = typebuild( type );
    1260                 simpletypes->get_attributes() = attributes;             // copy because member is const
     1319                ast::Type * simpletypes = typebuild( type );
     1320                // copy because member is const
     1321                simpletypes->attributes = attributes;
    12611322                return simpletypes;
    12621323        } // switch
  • src/Parser/ExpressionNode.cc

    rff71057 re02e13f  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Mar 14 12:00:00 2023
    13 // Update Count     : 1082
     12// Last Modified On : Tue Apr  4 11:07:00 2023
     13// Update Count     : 1083
    1414//
    1515
     
    2121#include <string>                  // for string, operator+, operator==
    2222
     23#include "AST/Expr.hpp"            // for NameExpr
     24#include "AST/Type.hpp"            // for BaseType, SueInstType
    2325#include "Common/SemanticError.h"  // for SemanticError
    2426#include "Common/utility.h"        // for maybeMoveBuild, maybeBuild, CodeLo...
    2527#include "ParseNode.h"             // for ExpressionNode, maybeMoveBuildType
    26 #include "SynTree/Constant.h"      // for Constant
    27 #include "SynTree/Declaration.h"   // for EnumDecl, StructDecl, UnionDecl
    28 #include "SynTree/Expression.h"    // for Expression, ConstantExpr, NameExpr
    29 #include "SynTree/Statement.h"     // for CompoundStmt, Statement
    30 #include "SynTree/Type.h"          // for BasicType, Type, Type::Qualifiers
    3128#include "parserutility.h"         // for notZeroExpr
    32 
    33 class Initializer;
    3429
    3530using namespace std;
     
    4843// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
    4944// type.
    50 
    51 extern const Type::Qualifiers noQualifiers;                             // no qualifiers on constants
    5245
    5346// static inline bool checkH( char c ) { return c == 'h' || c == 'H'; }
     
    127120} // scanbin
    128121
    129 Expression * build_constantInteger( string & str ) {
    130         static const BasicType::Kind kind[2][6] = {
     122ast::Expr * build_constantInteger(
     123                const CodeLocation & location, string & str ) {
     124        static const ast::BasicType::Kind kind[2][6] = {
    131125                // short (h) must be before char (hh) because shorter type has the longer suffix
    132                 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ BasicType::LongLongSignedInt, },
    133                 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */ BasicType::LongLongUnsignedInt, },
     126                { ast::BasicType::ShortSignedInt, ast::BasicType::SignedChar, ast::BasicType::SignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, /* BasicType::SignedInt128 */ ast::BasicType::LongLongSignedInt, },
     127                { ast::BasicType::ShortUnsignedInt, ast::BasicType::UnsignedChar, ast::BasicType::UnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, /* BasicType::UnsignedInt128 */ ast::BasicType::LongLongUnsignedInt, },
    134128        };
    135129
     
    141135        string str2( "0x0" );
    142136        unsigned long long int v, v2 = 0;                                       // converted integral value
    143         Expression * ret, * ret2;
     137        ast::Expr * ret, * ret2;
    144138
    145139        int type = -1;                                                                          // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
     
    149143        // special constants
    150144        if ( str == "0" ) {
    151                 ret = new ConstantExpr( Constant( (Type *)new ZeroType( noQualifiers ), str, (unsigned long long int)0 ) );
     145                ret = new ast::ConstantExpr( location, new ast::ZeroType(), str, 0 );
    152146                goto CLEANUP;
    153147        } // if
    154148        if ( str == "1" ) {
    155                 ret = new ConstantExpr( Constant( (Type *)new OneType( noQualifiers ), str, (unsigned long long int)1 ) );
     149                ret = new ast::ConstantExpr( location, new ast::OneType(), str, 1 );
    156150                goto CLEANUP;
    157151        } // if
     
    304298
    305299        // Constant type is correct for overload resolving.
    306         ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][type] ), str, v ) );
     300        ret = new ast::ConstantExpr( location,
     301                new ast::BasicType( kind[Unsigned][type] ), str, v );
    307302        if ( Unsigned && type < 2 ) {                                           // hh or h, less than int ?
    308303                // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values.
    309                 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
     304                ret = new ast::CastExpr( location,
     305                        ret,
     306                        new ast::BasicType( kind[Unsigned][type] ),
     307                        ast::ExplicitCast );
    310308        } else if ( ltype != -1 ) {                                                     // explicit length ?
    311309                if ( ltype == 6 ) {                                                             // int128, (int128)constant
    312 //                      ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][type] ), false );
    313                         ret2 = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::LongLongSignedInt ), str2, v2 ) );
    314                         ret = build_compoundLiteral(
    315                                 DeclarationNode::newBasicType( DeclarationNode::Int128 )->addType( DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ),
    316                                 new InitializerNode( (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true ) );
     310                        ret2 = new ast::ConstantExpr( location,
     311                                new ast::BasicType( ast::BasicType::LongLongSignedInt ),
     312                                str2,
     313                                v2 );
     314                        ret = build_compoundLiteral( location,
     315                                DeclarationNode::newBasicType(
     316                                        DeclarationNode::Int128
     317                                )->addType(
     318                                        DeclarationNode::newSignedNess( DeclarationNode::Unsigned ) ),
     319                                new InitializerNode(
     320                                        (InitializerNode *)(new InitializerNode( new ExpressionNode( v2 == 0 ? ret2 : ret ) ))->set_last( new InitializerNode( new ExpressionNode( v2 == 0 ? ret : ret2 ) ) ), true )
     321                        );
    317322                } else {                                                                                // explicit length, (length_type)constant
    318                         ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][ltype], false ), false );
     323                        ret = new ast::CastExpr( location,
     324                                ret,
     325                                new ast::TypeInstType( lnthsInt[Unsigned][ltype], ast::TypeDecl::Dtype ),
     326                                ast::ExplicitCast );
    319327                        if ( ltype == 5 ) {                                                     // pointer, intptr( (uintptr_t)constant )
    320                                 ret = build_func( new ExpressionNode( build_varref( new string( "intptr" ) ) ), new ExpressionNode( ret ) );
     328                                ret = build_func( location,
     329                                        new ExpressionNode(
     330                                                build_varref( location, new string( "intptr" ) ) ),
     331                                        new ExpressionNode( ret ) );
    321332                        } // if
    322333                } // if
     
    362373
    363374
    364 Expression * build_constantFloat( string & str ) {
    365         static const BasicType::Kind kind[2][12] = {
    366                 { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x },
    367                 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, BasicType::NUMBER_OF_BASIC_TYPES, BasicType::NUMBER_OF_BASIC_TYPES, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex, BasicType::uFloat128xComplex },
     375ast::Expr * build_constantFloat(
     376                const CodeLocation & location, string & str ) {
     377        static const ast::BasicType::Kind kind[2][12] = {
     378                { ast::BasicType::Float, ast::BasicType::Double, ast::BasicType::LongDouble, ast::BasicType::uuFloat80, ast::BasicType::uuFloat128, ast::BasicType::uFloat16, ast::BasicType::uFloat32, ast::BasicType::uFloat32x, ast::BasicType::uFloat64, ast::BasicType::uFloat64x, ast::BasicType::uFloat128, ast::BasicType::uFloat128x },
     379                { ast::BasicType::FloatComplex, ast::BasicType::DoubleComplex, ast::BasicType::LongDoubleComplex, ast::BasicType::NUMBER_OF_BASIC_TYPES, ast::BasicType::NUMBER_OF_BASIC_TYPES, ast::BasicType::uFloat16Complex, ast::BasicType::uFloat32Complex, ast::BasicType::uFloat32xComplex, ast::BasicType::uFloat64Complex, ast::BasicType::uFloat64xComplex, ast::BasicType::uFloat128Complex, ast::BasicType::uFloat128xComplex },
    368380        };
    369381
     
    402414
    403415        assert( 0 <= type && type < 12 );
    404         Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][type] ), str, v ) );
    405         if ( explnth ) {                                                                        // explicit length ?
    406                 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][type] ), false );
     416        ast::Expr * ret = new ast::ConstantExpr( location,
     417                new ast::BasicType( kind[complx][type] ),
     418                str,
     419                v );
     420        // explicit length ?
     421        if ( explnth ) {
     422                ret = new ast::CastExpr( location,
     423                        ret,
     424                        new ast::BasicType( kind[complx][type] ),
     425                        ast::ExplicitCast );
    407426        } // if
    408427
     
    419438} // sepString
    420439
    421 Expression * build_constantChar( string & str ) {
     440ast::Expr * build_constantChar( const CodeLocation & location, string & str ) {
    422441        string units;                                                                           // units
    423442        sepString( str, units, '\'' );                                          // separate constant from units
    424443
    425         Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) );
     444        ast::Expr * ret = new ast::ConstantExpr( location,
     445                new ast::BasicType( ast::BasicType::Char ),
     446                str,
     447                (unsigned long long int)(unsigned char)str[1] );
    426448        if ( units.length() != 0 ) {
    427                 ret = new UntypedExpr( new NameExpr( units ), { ret } );
     449                ret = new ast::UntypedExpr( location,
     450                        new ast::NameExpr( location, units ),
     451                        { ret } );
    428452        } // if
    429453
     
    432456} // build_constantChar
    433457
    434 Expression * build_constantStr( string & str ) {
     458ast::Expr * build_constantStr(
     459                const CodeLocation & location,
     460                string & str ) {
    435461        assert( str.length() > 0 );
    436462        string units;                                                                           // units
    437463        sepString( str, units, '"' );                                           // separate constant from units
    438464
    439         Type * strtype;
     465        ast::Type * strtype;
    440466        switch ( str[0] ) {                                                                     // str has >= 2 characters, i.e, null string "" => safe to look at subscripts 0/1
    441467        case 'u':
    442468                if ( str[1] == '8' ) goto Default;                              // utf-8 characters => array of char
    443469                // lookup type of associated typedef
    444                 strtype = new TypeInstType( Type::Qualifiers( ), "char16_t", false );
     470                strtype = new ast::TypeInstType( "char16_t", ast::TypeDecl::Dtype );
    445471                break;
    446472        case 'U':
    447                 strtype = new TypeInstType( Type::Qualifiers( ), "char32_t", false );
     473                strtype = new ast::TypeInstType( "char32_t", ast::TypeDecl::Dtype );
    448474                break;
    449475        case 'L':
    450                 strtype = new TypeInstType( Type::Qualifiers( ), "wchar_t", false );
     476                strtype = new ast::TypeInstType( "wchar_t", ast::TypeDecl::Dtype );
    451477                break;
    452478        Default:                                                                                        // char default string type
    453479        default:
    454                 strtype = new BasicType( Type::Qualifiers( ), BasicType::Char );
     480                strtype = new ast::BasicType( ast::BasicType::Char );
    455481        } // switch
    456         ArrayType * at = new ArrayType( noQualifiers, strtype,
    457                                                                         new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
    458                                                                         false, false );
    459         Expression * ret = new ConstantExpr( Constant( at, str, std::nullopt ) );
     482        ast::ArrayType * at = new ast::ArrayType(
     483                strtype,
     484                // Length is adjusted: +1 for '\0' and -2 for '"'
     485                ast::ConstantExpr::from_ulong( location, str.size() + 1 - 2 ),
     486                ast::FixedLen,
     487                ast::DynamicDim );
     488        ast::Expr * ret = new ast::ConstantExpr( location, at, str, std::nullopt );
    460489        if ( units.length() != 0 ) {
    461                 ret = new UntypedExpr( new NameExpr( units ), { ret } );
     490                ret = new ast::UntypedExpr( location,
     491                        new ast::NameExpr( location, units ),
     492                        { ret } );
    462493        } // if
    463494
     
    466497} // build_constantStr
    467498
    468 Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) {
     499ast::Expr * build_field_name_FLOATING_FRACTIONconstant(
     500                const CodeLocation & location, const string & str ) {
    469501        if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) SemanticError( yylloc, "invalid tuple index " + str );
    470         Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
     502        ast::Expr * ret = build_constantInteger( location,
     503                *new string( str.substr(1) ) );
    471504        delete &str;
    472505        return ret;
    473506} // build_field_name_FLOATING_FRACTIONconstant
    474507
    475 Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
     508ast::Expr * build_field_name_FLOATING_DECIMALconstant(
     509                const CodeLocation & location, const string & str ) {
    476510        if ( str[str.size() - 1] != '.' ) SemanticError( yylloc, "invalid tuple index " + str );
    477         Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
     511        ast::Expr * ret = build_constantInteger(
     512                location, *new string( str.substr( 0, str.size()-1 ) ) );
    478513        delete &str;
    479514        return ret;
    480515} // build_field_name_FLOATING_DECIMALconstant
    481516
    482 Expression * build_field_name_FLOATINGconstant( const string & str ) {
     517ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation & location,
     518                const string & str ) {
    483519        // str is of the form A.B -> separate at the . and return member expression
    484520        int a, b;
     
    486522        stringstream ss( str );
    487523        ss >> a >> dot >> b;
    488         UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) );
     524        auto ret = new ast::UntypedMemberExpr( location,
     525                ast::ConstantExpr::from_int( location, b ),
     526                ast::ConstantExpr::from_int( location, a )
     527        );
    489528        delete &str;
    490529        return ret;
    491530} // build_field_name_FLOATINGconstant
    492531
    493 Expression * make_field_name_fraction_constants( Expression * fieldName, Expression * fracts ) {
    494         if ( fracts ) {
    495                 if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( fracts ) ) {
    496                         memberExpr->set_member( make_field_name_fraction_constants( fieldName, memberExpr->get_aggregate() ) );
    497                         return memberExpr;
    498                 } else {
    499                         return new UntypedMemberExpr( fracts, fieldName );
    500                 } // if
    501         } // if
    502         return fieldName;
     532ast::Expr * make_field_name_fraction_constants( const CodeLocation & location,
     533                ast::Expr * fieldName,
     534                ast::Expr * fracts ) {
     535        if ( nullptr == fracts ) {
     536                return fieldName;
     537        } else if ( auto memberExpr = dynamic_cast<ast::UntypedMemberExpr *>( fracts ) ) {
     538                memberExpr->member = make_field_name_fraction_constants( location,
     539                        fieldName,
     540                        ast::mutate( memberExpr->aggregate.get() ) );
     541                return memberExpr;
     542        } else {
     543                return new ast::UntypedMemberExpr( location, fracts, fieldName );
     544        } // if
    503545} // make_field_name_fraction_constants
    504546
    505 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ) {
    506         return make_field_name_fraction_constants( fieldName, maybeMoveBuild( fracts ) );
     547ast::Expr * build_field_name_fraction_constants( const CodeLocation & location,
     548                ast::Expr * fieldName,
     549                ExpressionNode * fracts ) {
     550        return make_field_name_fraction_constants( location, fieldName, maybeMoveBuild( fracts ) );
    507551} // build_field_name_fraction_constants
    508552
    509 NameExpr * build_varref( const string * name ) {
    510         NameExpr * expr = new NameExpr( *name );
     553ast::NameExpr * build_varref( const CodeLocation & location,
     554                const string * name ) {
     555        ast::NameExpr * expr = new ast::NameExpr( location, *name );
    511556        delete name;
    512557        return expr;
    513558} // build_varref
    514559
    515 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name ) {
    516         Declaration * newDecl = maybeBuild(decl_node);
    517         if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) {
    518                 const Type * t = newDeclWithType->get_type();
    519                 if ( t ) {
    520                         if ( const TypeInstType * typeInst = dynamic_cast<const TypeInstType *>( t ) ) {
    521                                 newDecl= new EnumDecl( typeInst->name );
     560ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation & location,
     561                const DeclarationNode * decl_node,
     562                const ast::NameExpr * name ) {
     563        ast::Decl * newDecl = maybeBuild( decl_node );
     564        if ( ast::DeclWithType * newDeclWithType = dynamic_cast<ast::DeclWithType *>( newDecl ) ) {
     565                if ( const ast::Type * t = newDeclWithType->get_type() ) {
     566                        if ( auto typeInst = dynamic_cast<const ast::TypeInstType *>( t ) ) {
     567                                newDecl = new ast::EnumDecl( location, typeInst->name );
    522568                        }
    523569                }
    524570        }
    525         return new QualifiedNameExpr( newDecl, name->name );
     571        return new ast::QualifiedNameExpr( location, newDecl, name->name );
    526572}
    527573
    528 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl_node, const NameExpr * name ) {
    529         EnumDecl * newDecl = const_cast< EnumDecl * >( decl_node );
    530         return new QualifiedNameExpr( newDecl, name->name );
     574ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation & location,
     575                const ast::EnumDecl * decl,
     576                const ast::NameExpr * name ) {
     577        return new ast::QualifiedNameExpr( location, decl, name->name );
    531578}
    532579
    533 DimensionExpr * build_dimensionref( const string * name ) {
    534         DimensionExpr * expr = new DimensionExpr( *name );
     580ast::DimensionExpr * build_dimensionref( const CodeLocation & location,
     581                const string * name ) {
     582        ast::DimensionExpr * expr = new ast::DimensionExpr( location, *name );
    535583        delete name;
    536584        return expr;
     
    548596}; // OperName
    549597
    550 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) {
    551         Type * targetType = maybeMoveBuildType( decl_node );
    552         if ( dynamic_cast< VoidType * >( targetType ) ) {
     598ast::Expr * build_cast( const CodeLocation & location,
     599                DeclarationNode * decl_node,
     600                ExpressionNode * expr_node ) {
     601        ast::Type * targetType = maybeMoveBuildType( decl_node );
     602        if ( dynamic_cast<ast::VoidType *>( targetType ) ) {
    553603                delete targetType;
    554                 return new CastExpr( maybeMoveBuild( expr_node ), false );
     604                return new ast::CastExpr( location,
     605                        maybeMoveBuild( expr_node ),
     606                        ast::ExplicitCast );
    555607        } else {
    556                 return new CastExpr( maybeMoveBuild( expr_node ), targetType, false );
     608                return new ast::CastExpr( location,
     609                        maybeMoveBuild( expr_node ),
     610                        targetType,
     611                        ast::ExplicitCast );
    557612        } // if
    558613} // build_cast
    559614
    560 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node ) {
    561         return new KeywordCastExpr( maybeMoveBuild( expr_node ), target );
     615ast::Expr * build_keyword_cast( const CodeLocation & location,
     616                ast::AggregateDecl::Aggregate target,
     617                ExpressionNode * expr_node ) {
     618        return new ast::KeywordCastExpr( location,
     619                maybeMoveBuild( expr_node ),
     620                target
     621        );
    562622}
    563623
    564 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) {
    565         return new VirtualCastExpr( maybeMoveBuild( expr_node ), maybeMoveBuildType( decl_node ) );
     624ast::Expr * build_virtual_cast( const CodeLocation & location,
     625                DeclarationNode * decl_node,
     626                ExpressionNode * expr_node ) {
     627        return new ast::VirtualCastExpr( location,
     628                maybeMoveBuild( expr_node ),
     629                maybeMoveBuildType( decl_node )
     630        );
    566631} // build_virtual_cast
    567632
    568 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member ) {
    569         return new UntypedMemberExpr( member, maybeMoveBuild( expr_node ) );
     633ast::Expr * build_fieldSel( const CodeLocation & location,
     634                ExpressionNode * expr_node,
     635                ast::Expr * member ) {
     636        return new ast::UntypedMemberExpr( location,
     637                member,
     638                maybeMoveBuild( expr_node )
     639        );
    570640} // build_fieldSel
    571641
    572 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member ) {
    573         UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
     642ast::Expr * build_pfieldSel( const CodeLocation & location,
     643                ExpressionNode * expr_node,
     644                ast::Expr * member ) {
     645        auto deref = new ast::UntypedExpr( location,
     646                new ast::NameExpr( location, "*?" )
     647        );
    574648        deref->location = expr_node->location;
    575         deref->get_args().push_back( maybeMoveBuild( expr_node ) );
    576         UntypedMemberExpr * ret = new UntypedMemberExpr( member, deref );
     649        deref->args.push_back( maybeMoveBuild( expr_node ) );
     650        auto ret = new ast::UntypedMemberExpr( location, member, deref );
    577651        return ret;
    578652} // build_pfieldSel
    579653
    580 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member ) {
    581         Expression * ret = new UntypedOffsetofExpr( maybeMoveBuildType( decl_node ), member->get_name() );
     654ast::Expr * build_offsetOf( const CodeLocation & location,
     655                DeclarationNode * decl_node,
     656                ast::NameExpr * member ) {
     657        ast::Expr * ret = new ast::UntypedOffsetofExpr( location,
     658                maybeMoveBuildType( decl_node ),
     659                member->name
     660        );
     661        ret->result = new ast::BasicType( ast::BasicType::LongUnsignedInt );
    582662        delete member;
    583663        return ret;
    584664} // build_offsetOf
    585665
    586 Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind ) {
    587         return new LogicalExpr( notZeroExpr( maybeMoveBuild( expr_node1 ) ), notZeroExpr( maybeMoveBuild( expr_node2 ) ), kind );
     666ast::Expr * build_and_or( const CodeLocation & location,
     667                ExpressionNode * expr_node1,
     668                ExpressionNode * expr_node2,
     669                ast::LogicalFlag flag ) {
     670        return new ast::LogicalExpr( location,
     671                notZeroExpr( maybeMoveBuild( expr_node1 ) ),
     672                notZeroExpr( maybeMoveBuild( expr_node2 ) ),
     673                flag
     674        );
    588675} // build_and_or
    589676
    590 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ) {
    591         list< Expression * > args;
     677ast::Expr * build_unary_val( const CodeLocation & location,
     678                OperKinds op,
     679                ExpressionNode * expr_node ) {
     680        std::vector<ast::ptr<ast::Expr>> args;
    592681        args.push_back( maybeMoveBuild( expr_node ) );
    593         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     682        return new ast::UntypedExpr( location,
     683                new ast::NameExpr( location, OperName[ (int)op ] ),
     684                std::move( args )
     685        );
    594686} // build_unary_val
    595687
    596 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
    597         list< Expression * > args;
     688ast::Expr * build_binary_val( const CodeLocation & location,
     689                OperKinds op,
     690                ExpressionNode * expr_node1,
     691                ExpressionNode * expr_node2 ) {
     692        std::vector<ast::ptr<ast::Expr>> args;
    598693        args.push_back( maybeMoveBuild( expr_node1 ) );
    599694        args.push_back( maybeMoveBuild( expr_node2 ) );
    600         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     695        return new ast::UntypedExpr( location,
     696                new ast::NameExpr( location, OperName[ (int)op ] ),
     697                std::move( args )
     698        );
    601699} // build_binary_val
    602700
    603 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
    604         list< Expression * > args;
    605         args.push_back( maybeMoveBuild( expr_node1 ) );
    606         args.push_back( maybeMoveBuild( expr_node2 ) );
    607         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     701ast::Expr * build_binary_ptr( const CodeLocation & location,
     702                OperKinds op,
     703                ExpressionNode * expr_node1,
     704                ExpressionNode * expr_node2 ) {
     705        return build_binary_val( location, op, expr_node1, expr_node2 );
    608706} // build_binary_ptr
    609707
    610 Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 ) {
    611         return new ConditionalExpr( notZeroExpr( maybeMoveBuild( expr_node1 ) ), maybeMoveBuild( expr_node2 ), maybeMoveBuild( expr_node3 ) );
     708ast::Expr * build_cond( const CodeLocation & location,
     709                ExpressionNode * expr_node1,
     710                ExpressionNode * expr_node2,
     711                ExpressionNode * expr_node3 ) {
     712        return new ast::ConditionalExpr( location,
     713                notZeroExpr( maybeMoveBuild( expr_node1 ) ),
     714                maybeMoveBuild( expr_node2 ),
     715                maybeMoveBuild( expr_node3 )
     716        );
    612717} // build_cond
    613718
    614 Expression * build_tuple( ExpressionNode * expr_node ) {
    615         list< Expression * > exprs;
     719ast::Expr * build_tuple( const CodeLocation & location,
     720                ExpressionNode * expr_node ) {
     721        std::vector<ast::ptr<ast::Expr>> exprs;
    616722        buildMoveList( expr_node, exprs );
    617         return new UntypedTupleExpr( exprs );;
     723        return new ast::UntypedTupleExpr( location, std::move( exprs ) );
    618724} // build_tuple
    619725
    620 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ) {
    621         list< Expression * > args;
     726ast::Expr * build_func( const CodeLocation & location,
     727                ExpressionNode * function,
     728                ExpressionNode * expr_node ) {
     729        std::vector<ast::ptr<ast::Expr>> args;
    622730        buildMoveList( expr_node, args );
    623         return new UntypedExpr( maybeMoveBuild( function ), args );
     731        return new ast::UntypedExpr( location,
     732                maybeMoveBuild( function ),
     733                std::move( args )
     734        );
    624735} // build_func
    625736
    626 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids ) {
    627         Declaration * newDecl = maybeBuild( decl_node ); // compound literal type
    628         if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
    629                 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeMoveBuild( kids ) );
     737ast::Expr * build_compoundLiteral( const CodeLocation & location,
     738                DeclarationNode * decl_node,
     739                InitializerNode * kids ) {
     740        // compound literal type
     741        ast::Decl * newDecl = maybeBuild( decl_node );
     742        // non-sue compound-literal type
     743        if ( ast::DeclWithType * newDeclWithType = dynamic_cast<ast::DeclWithType *>( newDecl ) ) {
     744                return new ast::CompoundLiteralExpr( location,
     745                        newDeclWithType->get_type(),
     746                        maybeMoveBuild( kids ) );
    630747        // these types do not have associated type information
    631         } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl )  ) {
    632                 if ( newDeclStructDecl->has_body() ) {
    633                         return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl ), maybeMoveBuild( kids ) );
     748        } else if ( auto newDeclStructDecl = dynamic_cast<ast::StructDecl *>( newDecl ) ) {
     749                if ( newDeclStructDecl->body ) {
     750                        return new ast::CompoundLiteralExpr( location,
     751                                new ast::StructInstType( newDeclStructDecl ),
     752                                maybeMoveBuild( kids ) );
    634753                } else {
    635                         return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeMoveBuild( kids ) );
    636                 } // if
    637         } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl )  ) {
    638                 if ( newDeclUnionDecl->has_body() ) {
    639                         return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl ), maybeMoveBuild( kids ) );
     754                        return new ast::CompoundLiteralExpr( location,
     755                                new ast::StructInstType( newDeclStructDecl->name ),
     756                                maybeMoveBuild( kids ) );
     757                } // if
     758        } else if ( auto newDeclUnionDecl = dynamic_cast<ast::UnionDecl *>( newDecl )  ) {
     759                if ( newDeclUnionDecl->body ) {
     760                        return new ast::CompoundLiteralExpr( location,
     761                                new ast::UnionInstType( newDeclUnionDecl ),
     762                                maybeMoveBuild( kids ) );
    640763                } else {
    641                         return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeMoveBuild( kids ) );
    642                 } // if
    643         } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl )  ) {
    644                 if ( newDeclEnumDecl->has_body() ) {
    645                         return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl ), maybeMoveBuild( kids ) );
     764                        return new ast::CompoundLiteralExpr( location,
     765                                new ast::UnionInstType( newDeclUnionDecl->name ),
     766                                maybeMoveBuild( kids ) );
     767                } // if
     768        } else if ( auto newDeclEnumDecl = dynamic_cast<ast::EnumDecl *>( newDecl )  ) {
     769                if ( newDeclEnumDecl->body ) {
     770                        return new ast::CompoundLiteralExpr( location,
     771                                new ast::EnumInstType( newDeclEnumDecl ),
     772                                maybeMoveBuild( kids ) );
    646773                } else {
    647                         return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeMoveBuild( kids ) );
     774                        return new ast::CompoundLiteralExpr( location,
     775                                new ast::EnumInstType( newDeclEnumDecl->name ),
     776                                maybeMoveBuild( kids ) );
    648777                } // if
    649778        } else {
  • src/Parser/InitializerNode.cc

    rff71057 re02e13f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:20:24 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Jul 28 23:27:20 2017
    13 // Update Count     : 26
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr  4 11:18:00 2023
     13// Update Count     : 27
    1414//
    1515
     
    2020using namespace std;
    2121
     22#include "AST/Expr.hpp"            // for Expr
     23#include "AST/Init.hpp"            // for Designator, Init, ListInit, Sing...
    2224#include "Common/SemanticError.h"  // for SemanticError
    2325#include "Common/utility.h"        // for maybeBuild
    2426#include "ParseNode.h"             // for InitializerNode, ExpressionNode
    25 #include "SynTree/Expression.h"    // for Expression
    26 #include "SynTree/Initializer.h"   // for Initializer, ListInit, SingleInit
     27
     28static ast::ConstructFlag toConstructFlag( bool maybeConstructed ) {
     29        return maybeConstructed ? ast::MaybeConstruct : ast::NoConstruct;
     30}
    2731
    2832InitializerNode::InitializerNode( ExpressionNode * _expr, bool aggrp, ExpressionNode * des )
     
    3337        if ( kids )
    3438                set_last( nullptr );
    35 } // InitializerNode::InitializerNode
     39} // InitializerNode::InitializerNode
    3640
    3741InitializerNode::InitializerNode( InitializerNode * init, bool aggrp, ExpressionNode * des )
     
    8589} // InitializerNode::printOneLine
    8690
    87 Initializer * InitializerNode::build() const {
     91ast::Init * InitializerNode::build() const {
    8892        assertf( ! isDelete, "Should not build delete stmt InitializerNode" );
    8993        if ( aggregate ) {
    9094                // steal designators from children
    91                 std::list< Designation * > designlist;
     95                std::vector<ast::ptr<ast::Designation>> designlist;
    9296                InitializerNode * child = next_init();
    93                 for ( ; child != nullptr; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) {
    94                         std::list< Expression * > desList;
    95                         buildList< Expression, ExpressionNode >( child->designator, desList );
    96                         designlist.push_back( new Designation( desList ) );
     97                for ( ; child != nullptr ; child = dynamic_cast< InitializerNode * >( child->get_next() ) ) {
     98                        std::deque<ast::ptr<ast::Expr>> desList;
     99                        buildList( child->designator, desList );
     100                        designlist.push_back(
     101                                new ast::Designation( location, std::move( desList ) ) );
    97102                } // for
    98                 std::list< Initializer * > initlist;
    99                 buildList< Initializer, InitializerNode >( next_init(), initlist );
    100                 return new ListInit( initlist, designlist, maybeConstructed );
    101         } else {
    102                 if ( get_expression() ) {
    103                         assertf( get_expression()->expr, "The expression of initializer must have value" );
    104                         return new SingleInit( maybeBuild( get_expression() ), maybeConstructed );
    105                 } // if
     103                std::vector<ast::ptr<ast::Init>> initlist;
     104                buildList( next_init(), initlist );
     105                return new ast::ListInit( location,
     106                        std::move( initlist ),
     107                        std::move( designlist ),
     108                        toConstructFlag( maybeConstructed )
     109                );
     110        } else if ( get_expression() ) {
     111                assertf( get_expression()->expr, "The expression of initializer must have value" );
     112                return new ast::SingleInit( location,
     113                        maybeBuild( get_expression() ),
     114                        toConstructFlag( maybeConstructed )
     115                );
    106116        } // if
    107117        return nullptr;
  • src/Parser/ParseNode.h

    rff71057 re02e13f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 13:28:16 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar 29 08:40:27 2023
    13 // Update Count     : 948
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Mon Apr  3 17:55:00 2023
     13// Update Count     : 942
    1414//
    1515
     
    2424#include <string>                  // for string
    2525
     26#include "AST/Expr.hpp"            // for Expr, NameExpr LogicalFlag
     27#include "AST/Fwd.hpp"             // for ptr, Decl, DeclWithType,
     28#include "AST/Stmt.hpp"            // for Stmt
    2629#include "Common/CodeLocation.h"   // for CodeLocation
    2730#include "Common/SemanticError.h"  // for SemanticError
    2831#include "Common/UniqueName.h"     // for UniqueName
    2932#include "Common/utility.h"        // for maybeClone
    30 #include "Parser/parserutility.h"  // for maybeBuild
    31 #include "SynTree/LinkageSpec.h"   // for Spec
    32 #include "SynTree/Declaration.h"   // for Aggregate
    33 #include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
    34 #include "SynTree/Label.h"         // for Label
    35 #include "SynTree/Statement.h"     // for Statement, BranchStmt, BranchStmt:...
    36 #include "SynTree/Type.h"          // for Type, Type::FuncSpecifiers, Type::...
     33#include "Parser/parserutility.h"  // for maybeBuild, maybeCopy
    3734
    3835class Attribute;
     
    108105        void printOneLine( std::ostream & ) const;
    109106
    110         virtual Initializer * build() const;
     107        virtual ast::Init * build() const;
    111108  private:
    112109        ExpressionNode * expr;
     
    122119class ExpressionNode final : public ParseNode {
    123120  public:
    124         ExpressionNode( Expression * expr = nullptr ) : expr( expr ) {}
     121        ExpressionNode( ast::Expr * expr = nullptr ) : expr( expr ) {}
    125122        virtual ~ExpressionNode() {}
    126         virtual ExpressionNode * clone() const override { return expr ? static_cast<ExpressionNode*>((new ExpressionNode( expr->clone() ))->set_next( maybeClone( get_next() ) )) : nullptr; }
     123        virtual ExpressionNode * clone() const override {
     124                if ( nullptr == expr ) return nullptr;
     125                return static_cast<ExpressionNode*>(
     126                        (new ExpressionNode( ast::shallowCopy( expr.get() ) ))->set_next( maybeCopy( get_next() ) ));
     127        }
    127128
    128129        bool get_extension() const { return extension; }
     
    137138        bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); }
    138139
    139         Expression * build() const {
    140                 Expression * node = const_cast<ExpressionNode *>(this)->expr.release();
     140        ast::Expr * build() const {
     141                ast::Expr * node = const_cast<ExpressionNode *>(this)->expr.release();
    141142                node->set_extension( this->get_extension() );
    142143                node->location = this->location;
     
    144145        }
    145146
    146         std::unique_ptr<Expression> expr;                                       // public because of lifetime implications
     147        // Public because of lifetime implications (what lifetime implications?)
     148        std::unique_ptr<ast::Expr> expr;
    147149  private:
    148150        bool extension = false;
     
    164166
    165167struct LabelNode {
    166         std::list< Label > labels;
     168        std::vector<ast::Label> labels;
    167169};
    168170
    169 Expression * build_constantInteger( std::string & str ); // these 4 routines modify the string
    170 Expression * build_constantFloat( std::string & str );
    171 Expression * build_constantChar( std::string & str );
    172 Expression * build_constantStr( std::string & str );
    173 Expression * build_field_name_FLOATING_FRACTIONconstant( const std::string & str );
    174 Expression * build_field_name_FLOATING_DECIMALconstant( const std::string & str );
    175 Expression * build_field_name_FLOATINGconstant( const std::string & str );
    176 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts );
    177 
    178 NameExpr * build_varref( const std::string * name );
    179 QualifiedNameExpr * build_qualified_expr( const DeclarationNode * decl_node, const NameExpr * name );
    180 QualifiedNameExpr * build_qualified_expr( const EnumDecl * decl, const NameExpr * name );
    181 DimensionExpr * build_dimensionref( const std::string * name );
    182 
    183 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
    184 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node );
    185 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node );
    186 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member );
    187 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member );
    188 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member );
    189 Expression * build_and( ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
    190 Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind );
    191 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node );
    192 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
    193 Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
    194 Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
    195 Expression * build_tuple( ExpressionNode * expr_node = nullptr );
    196 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node );
    197 Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids );
     171// These 4 routines modify the string:
     172ast::Expr * build_constantInteger( const CodeLocation &, std::string & );
     173ast::Expr * build_constantFloat( const CodeLocation &, std::string & );
     174ast::Expr * build_constantChar( const CodeLocation &, std::string & );
     175ast::Expr * build_constantStr( const CodeLocation &, std::string & );
     176ast::Expr * build_field_name_FLOATING_FRACTIONconstant( const CodeLocation &, const std::string & str );
     177ast::Expr * build_field_name_FLOATING_DECIMALconstant( const CodeLocation &, const std::string & str );
     178ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation &, const std::string & str );
     179ast::Expr * build_field_name_fraction_constants( const CodeLocation &, ast::Expr * fieldName, ExpressionNode * fracts );
     180
     181ast::NameExpr * build_varref( const CodeLocation &, const std::string * name );
     182ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const DeclarationNode * decl_node, const ast::NameExpr * name );
     183ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const ast::EnumDecl * decl, const ast::NameExpr * name );
     184ast::DimensionExpr * build_dimensionref( const CodeLocation &, const std::string * name );
     185
     186ast::Expr * build_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node );
     187ast::Expr * build_keyword_cast( const CodeLocation &, ast::AggregateDecl::Aggregate target, ExpressionNode * expr_node );
     188ast::Expr * build_virtual_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node );
     189ast::Expr * build_fieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member );
     190ast::Expr * build_pfieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member );
     191ast::Expr * build_offsetOf( const CodeLocation &, DeclarationNode * decl_node, ast::NameExpr * member );
     192ast::Expr * build_and( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
     193ast::Expr * build_and_or( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ast::LogicalFlag flag );
     194ast::Expr * build_unary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node );
     195ast::Expr * build_binary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
     196ast::Expr * build_binary_ptr( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 );
     197ast::Expr * build_cond( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 );
     198ast::Expr * build_tuple( const CodeLocation &, ExpressionNode * expr_node = nullptr );
     199ast::Expr * build_func( const CodeLocation &, ExpressionNode * function, ExpressionNode * expr_node );
     200ast::Expr * build_compoundLiteral( const CodeLocation &, DeclarationNode * decl_node, InitializerNode * kids );
    198201
    199202//##############################################################################
     
    219222        static const char * builtinTypeNames[];
    220223
    221         static DeclarationNode * newStorageClass( Type::StorageClasses );
    222         static DeclarationNode * newFuncSpecifier( Type::FuncSpecifiers );
    223         static DeclarationNode * newTypeQualifier( Type::Qualifiers );
     224        static DeclarationNode * newStorageClass( ast::Storage::Classes );
     225        static DeclarationNode * newFuncSpecifier( ast::Function::Specs );
     226        static DeclarationNode * newTypeQualifier( ast::CV::Qualifiers );
    224227        static DeclarationNode * newBasicType( BasicType );
    225228        static DeclarationNode * newComplexType( ComplexType );
     
    232235        static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * );
    233236        static DeclarationNode * newFunction( const std::string * name, DeclarationNode * ret, DeclarationNode * param, StatementNode * body );
    234         static DeclarationNode * newAggregate( AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
     237        static DeclarationNode * newAggregate( ast::AggregateDecl::Aggregate kind, const std::string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body );
    235238        static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible );
    236239        static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant );
     
    239242        static DeclarationNode * newName( const std::string * );
    240243        static DeclarationNode * newFromTypeGen( const std::string *, ExpressionNode * params );
    241         static DeclarationNode * newTypeParam( TypeDecl::Kind, const std::string * );
     244        static DeclarationNode * newTypeParam( ast::TypeDecl::Kind, const std::string * );
    242245        static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts );
    243246        static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params );
     
    253256        static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement
    254257        static DeclarationNode * newAsmStmt( StatementNode * stmt ); // gcc external asm statement
    255         static DeclarationNode * newStaticAssert( ExpressionNode * condition, Expression * message );
     258        static DeclarationNode * newStaticAssert( ExpressionNode * condition, ast::Expr * message );
    256259
    257260        DeclarationNode();
     
    294297        virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override;
    295298
    296         Declaration * build() const;
    297         Type * buildType() const;
    298 
    299         LinkageSpec::Spec get_linkage() const { return linkage; }
     299        ast::Decl * build() const;
     300        ast::Type * buildType() const;
     301
     302        ast::Linkage::Spec get_linkage() const { return linkage; }
    300303        DeclarationNode * extractAggregate() const;
    301304        bool has_enumeratorValue() const { return (bool)enumeratorValue; }
     
    312315        struct Variable_t {
    313316//              const std::string * name;
    314                 TypeDecl::Kind tyClass;
     317                ast::TypeDecl::Kind tyClass;
    315318                DeclarationNode * assertions;
    316319                DeclarationNode * initializer;
     
    320323        struct StaticAssert_t {
    321324                ExpressionNode * condition;
    322                 Expression * message;
     325                ast::Expr * message;
    323326        };
    324327        StaticAssert_t assert;
     
    330333        bool inLine = false;
    331334        bool enumInLine = false;
    332         Type::FuncSpecifiers funcSpecs;
    333         Type::StorageClasses storageClasses;
     335        ast::Function::Specs funcSpecs;
     336        ast::Storage::Classes storageClasses;
    334337
    335338        ExpressionNode * bitfieldWidth = nullptr;
    336339        std::unique_ptr<ExpressionNode> enumeratorValue;
    337340        bool hasEllipsis = false;
    338         LinkageSpec::Spec linkage;
    339         Expression * asmName = nullptr;
    340         std::list< Attribute * > attributes;
     341        ast::Linkage::Spec linkage;
     342        ast::Expr * asmName = nullptr;
     343        std::vector<ast::ptr<ast::Attribute>> attributes;
    341344        InitializerNode * initializer = nullptr;
    342345        bool extension = false;
     
    348351}; // DeclarationNode
    349352
    350 Type * buildType( TypeData * type );
    351 
    352 static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {
    353         Type * ret = orig ? orig->buildType() : nullptr;
     353ast::Type * buildType( TypeData * type );
     354
     355static inline ast::Type * maybeMoveBuildType( const DeclarationNode * orig ) {
     356        ast::Type * ret = orig ? orig->buildType() : nullptr;
    354357        delete orig;
    355358        return ret;
     
    359362
    360363struct StatementNode final : public ParseNode {
    361         StatementNode() { stmt = nullptr; }
    362         StatementNode( Statement * stmt ) : stmt( stmt ) {}
     364        StatementNode() :
     365                stmt( nullptr ), clause( nullptr ) {}
     366        StatementNode( ast::Stmt * stmt ) :
     367                stmt( stmt ), clause( nullptr ) {}
     368        StatementNode( ast::StmtClause * clause ) :
     369                stmt( nullptr ), clause( clause ) {}
    363370        StatementNode( DeclarationNode * decl );
    364371        virtual ~StatementNode() {}
    365372
    366373        virtual StatementNode * clone() const final { assert( false ); return nullptr; }
    367         Statement * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
    368 
    369         virtual StatementNode * add_label( const std::string * name, DeclarationNode * attr = nullptr ) {
    370                 stmt->get_labels().emplace_back( * name, nullptr, attr ? std::move( attr->attributes ) : std::list< Attribute * > {} );
     374        ast::Stmt * build() const { return const_cast<StatementNode *>(this)->stmt.release(); }
     375
     376        virtual StatementNode * add_label(
     377                        const CodeLocation & location,
     378                        const std::string * name,
     379                        DeclarationNode * attr = nullptr ) {
     380                stmt->labels.emplace_back( location,
     381                        *name,
     382                        attr ? std::move( attr->attributes )
     383                                : std::vector<ast::ptr<ast::Attribute>>{} );
    371384                delete attr;
    372385                delete name;
     
    380393        }
    381394
    382         std::unique_ptr<Statement> stmt;
     395        std::unique_ptr<ast::Stmt> stmt;
     396        std::unique_ptr<ast::StmtClause> clause;
    383397}; // StatementNode
    384398
    385 Statement * build_expr( ExpressionNode * ctl );
     399ast::Stmt * build_expr( CodeLocation const &, ExpressionNode * ctl );
    386400
    387401struct CondCtl {
     
    402416};
    403417
    404 Expression * build_if_control( CondCtl * ctl, std::list< Statement * > & init );
    405 Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ );
    406 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
    407 Statement * build_case( ExpressionNode * ctl );
    408 Statement * build_default();
    409 Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
    410 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
    411 Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
    412 Statement * build_branch( BranchStmt::Type kind );
    413 Statement * build_branch( std::string * identifier, BranchStmt::Type kind );
    414 Statement * build_computedgoto( ExpressionNode * ctl );
    415 Statement * build_return( ExpressionNode * ctl );
    416 Statement * build_throw( ExpressionNode * ctl );
    417 Statement * build_resume( ExpressionNode * ctl );
    418 Statement * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
    419 Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
    420 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
    421 Statement * build_finally( StatementNode * stmt );
    422 Statement * build_compound( StatementNode * first );
    423 StatementNode * maybe_build_compound( StatementNode * first );
    424 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
    425 Statement * build_directive( std::string * directive );
    426 SuspendStmt * build_suspend( StatementNode *, SuspendStmt::Type = SuspendStmt::None);
    427 WaitForStmt * build_waitfor( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt );
    428 WaitForStmt * build_waitfor_else( WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt );
    429 WaitForStmt * build_waitfor_timeout( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );
    430 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt );
    431 Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt );
    432 
    433 //##############################################################################
    434 
    435 template< typename SynTreeType, typename NodeType, template< typename, typename...> class Container, typename... Args >
    436 void buildList( const NodeType * firstNode, Container< SynTreeType *, Args... > & outputList ) {
     418ast::Stmt * build_if( const CodeLocation &, CondCtl * ctl, StatementNode * then, StatementNode * else_ );
     419ast::Stmt * build_switch( const CodeLocation &, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt );
     420ast::CaseClause * build_case( ExpressionNode * ctl );
     421ast::CaseClause * build_default( const CodeLocation & );
     422ast::Stmt * build_while( const CodeLocation &, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
     423ast::Stmt * build_do_while( const CodeLocation &, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr );
     424ast::Stmt * build_for( const CodeLocation &, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr );
     425ast::Stmt * build_branch( const CodeLocation &, ast::BranchStmt::Kind kind );
     426ast::Stmt * build_branch( const CodeLocation &, std::string * identifier, ast::BranchStmt::Kind kind );
     427ast::Stmt * build_computedgoto( ExpressionNode * ctl );
     428ast::Stmt * build_return( const CodeLocation &, ExpressionNode * ctl );
     429ast::Stmt * build_throw( const CodeLocation &, ExpressionNode * ctl );
     430ast::Stmt * build_resume( const CodeLocation &, ExpressionNode * ctl );
     431ast::Stmt * build_resume_at( ExpressionNode * ctl , ExpressionNode * target );
     432ast::Stmt * build_try( const CodeLocation &, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ );
     433ast::CatchClause * build_catch( const CodeLocation &, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body );
     434ast::FinallyClause * build_finally( const CodeLocation &, StatementNode * stmt );
     435ast::Stmt * build_compound( const CodeLocation &, StatementNode * first );
     436StatementNode * maybe_build_compound( const CodeLocation &, StatementNode * first );
     437ast::Stmt * build_asm( const CodeLocation &, bool voltile, ast::Expr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr );
     438ast::Stmt * build_directive( const CodeLocation &, std::string * directive );
     439ast::SuspendStmt * build_suspend( const CodeLocation &, StatementNode *, ast::SuspendStmt::Type );
     440ast::WaitForStmt * build_waitfor( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt );
     441ast::WaitForStmt * build_waitfor_else( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt );
     442ast::WaitForStmt * build_waitfor_timeout( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );
     443ast::Stmt * build_with( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
     444ast::Stmt * build_mutex( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
     445
     446//##############################################################################
     447
     448template<typename AstType, typename NodeType,
     449        template<typename, typename...> class Container, typename... Args>
     450void buildList( const NodeType * firstNode,
     451                Container<ast::ptr<AstType>, Args...> & output ) {
    437452        SemanticErrorException errors;
    438         std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );
     453        std::back_insert_iterator<Container<ast::ptr<AstType>, Args...>> out( output );
    439454        const NodeType * cur = firstNode;
    440455
    441456        while ( cur ) {
    442457                try {
    443                         SynTreeType * result = dynamic_cast< SynTreeType * >( maybeBuild( cur ) );
    444                         if ( result ) {
    445                                 result->location = cur->location;
    446                                 * out++ = result;
     458                        if ( auto result = dynamic_cast<AstType *>( maybeBuild( cur ) ) ) {
     459                                *out++ = result;
    447460                        } else {
     461                                assertf(false, __PRETTY_FUNCTION__ );
    448462                                SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
    449463                        } // if
     
    451465                        errors.append( e );
    452466                } // try
    453                 const ParseNode * temp = (cur->get_next());
    454                 cur = dynamic_cast< const NodeType * >( temp ); // should not return nullptr
    455                 if ( ! cur && temp ) {                                                  // non-homogeneous nodes ?
     467                const ParseNode * temp = cur->get_next();
     468                // Should not return nullptr, then it is non-homogeneous:
     469                cur = dynamic_cast<const NodeType *>( temp );
     470                if ( !cur && temp ) {
    456471                        SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
    457472                } // if
     
    463478
    464479// in DeclarationNode.cc
    465 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList );
    466 void buildList( const DeclarationNode * firstNode, std::list< DeclarationWithType * > & outputList );
    467 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList );
    468 
    469 template< typename SynTreeType, typename NodeType >
    470 void buildMoveList( const NodeType * firstNode, std::list< SynTreeType * > & outputList ) {
    471         buildList( firstNode, outputList );
     480void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Decl>> & outputList );
     481void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList );
     482void buildTypeList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Type>> & outputList );
     483
     484template<typename AstType, typename NodeType,
     485        template<typename, typename...> class Container, typename... Args>
     486void buildMoveList( const NodeType * firstNode,
     487                Container<ast::ptr<AstType>, Args...> & output ) {
     488        buildList<AstType, NodeType, Container, Args...>( firstNode, output );
    472489        delete firstNode;
    473490}
  • src/Parser/ParserTypes.h

    rff71057 re02e13f  
    44// The contents of this file are covered under the licence agreement in the
    55// file "LICENCE" distributed with Cforall.
    6 // 
    7 // parser.hh -- 
    8 // 
     6//
     7// parser.hh --
     8//
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep 22 08:58:10 2001
  • src/Parser/RunParser.cpp

    rff71057 re02e13f  
    1010// Created On       : Mon Dec 19 11:00:00 2022
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Feb 16 10:08:00 2023
    13 // Update Count     : 2
     12// Last Modified On : Mon Mar  6  9:42:00 2023
     13// Update Count     : 3
    1414//
    1515
     
    4646
    4747ast::TranslationUnit buildUnit(void) {
    48         std::list<Declaration *> translationUnit;
    49         buildList( parseTree, translationUnit );
    50 
     48        std::vector<ast::ptr<ast::Decl>> decls;
     49        buildList( parseTree, decls );
    5150        delete parseTree;
    5251        parseTree = nullptr;
    5352
    54         // When the parse/buildList code is translated to the new ast, these
    55         // fill passes (and the one after 'Hoist Type Decls') should be redundent
    56         // because the code locations should already be filled.
    57         CodeTools::fillLocations( translationUnit );
    58         ast::TranslationUnit transUnit = convert( std::move( translationUnit ) );
    59         forceFillCodeLocations( transUnit );
     53        ast::TranslationUnit transUnit;
     54        for ( auto decl : decls ) {
     55                transUnit.decls.emplace_back( std::move( decl ) );
     56        }
    6057        return transUnit;
    6158}
  • src/Parser/StatementNode.cc

    rff71057 re02e13f  
    1010// Author           : Rodolfo G. Esteves
    1111// Created On       : Sat May 16 14:59:41 2015
    12 // Last Modified By : Peter A. Buhr
    13 // Last Modified On : Wed Mar 29 08:51:23 2023
    14 // Update Count     : 454
     12// Last Modified By : Andrew Beach
     13// Last Modified On : Tue Apr  4 11:40:00 2023
     14// Update Count     : 427
    1515//
    1616
    1717#include <cassert>                 // for assert, strict_dynamic_cast, assertf
    18 #include <list>                    // for list
    1918#include <memory>                  // for unique_ptr
    2019#include <string>                  // for string
    2120
     21#include "AST/Label.hpp"           // for Label
     22#include "AST/Stmt.hpp"            // for Stmt, AsmStmt, BranchStmt, CaseCla...
    2223#include "Common/SemanticError.h"  // for SemanticError
    2324#include "Common/utility.h"        // for maybeMoveBuild, maybeBuild
    2425#include "ParseNode.h"             // for StatementNode, ExpressionNode, bui...
    25 #include "SynTree/Expression.h"    // for Expression, ConstantExpr
    26 #include "SynTree/Label.h"         // for Label, noLabels
    27 #include "SynTree/Declaration.h"
    28 #include "SynTree/Statement.h"     // for Statement, BranchStmt, CaseStmt
    2926#include "parserutility.h"         // for notZeroExpr
    3027
     
    3229
    3330using namespace std;
    34 
    3531
    3632StatementNode::StatementNode( DeclarationNode * decl ) {
     
    3834        DeclarationNode * agg = decl->extractAggregate();
    3935        if ( agg ) {
    40                 StatementNode * nextStmt = new StatementNode( new DeclStmt( maybeBuild( decl ) ) );
     36                StatementNode * nextStmt = new StatementNode(
     37                        new ast::DeclStmt( decl->location, maybeBuild( decl ) ) );
    4138                set_next( nextStmt );
    4239                if ( decl->get_next() ) {
     
    5148                agg = decl;
    5249        } // if
    53         stmt.reset( new DeclStmt( maybeMoveBuild( agg ) ) );
     50        // Local copy to avoid accessing the pointer after it is moved from.
     51        CodeLocation declLocation = agg->location;
     52        stmt.reset( new ast::DeclStmt( declLocation, maybeMoveBuild( agg ) ) );
    5453} // StatementNode::StatementNode
    5554
     
    5958        for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) {
    6059                StatementNode * node = strict_dynamic_cast< StatementNode * >(curr);
    61                 assert( dynamic_cast< CaseStmt * >(node->stmt.get()) );
     60                assert( nullptr == node->stmt.get() );
     61                assert( dynamic_cast<ast::CaseClause *>( node->clause.get() ) );
    6262                prev = curr;
    6363        } // for
    6464        // convert from StatementNode list to Statement list
    6565        StatementNode * node = dynamic_cast< StatementNode * >(prev);
    66         list< Statement * > stmts;
     66        std::vector<ast::ptr<ast::Stmt>> stmts;
    6767        buildMoveList( stmt, stmts );
    6868        // splice any new Statements to end of current Statements
    69         CaseStmt * caseStmt = dynamic_cast< CaseStmt * >(node->stmt.get());
    70         caseStmt->get_statements().splice( caseStmt->get_statements().end(), stmts );
     69        auto caseStmt = strict_dynamic_cast<ast::CaseClause *>( node->clause.get() );
     70        for ( auto const & newStmt : stmts ) {
     71                caseStmt->stmts.emplace_back( newStmt );
     72        }
     73        stmts.clear();
    7174        return this;
    7275} // StatementNode::append_last_case
    7376
    74 Statement * build_expr( ExpressionNode * ctl ) {
    75         Expression * e = maybeMoveBuild( ctl );
    76 
    77         if ( e ) return new ExprStmt( e );
    78         else return new NullStmt();
     77ast::Stmt * build_expr( CodeLocation const & location, ExpressionNode * ctl ) {
     78        if ( ast::Expr * e = maybeMoveBuild( ctl ) ) {
     79                return new ast::ExprStmt( location, e );
     80        } else {
     81                return new ast::NullStmt( location );
     82        }
    7983} // build_expr
    8084
    81 Expression * build_if_control( CondCtl * ctl, list< Statement * > & init ) {
    82         if ( ctl->init != 0 ) {
    83                 buildMoveList( ctl->init, init );
    84         } // if
    85 
    86         Expression * cond = nullptr;
     85static ast::Expr * build_if_control( CondCtl * ctl,
     86                std::vector<ast::ptr<ast::Stmt>> & inits ) {
     87        assert( inits.empty() );
     88        if ( nullptr != ctl->init ) {
     89                buildMoveList( ctl->init, inits );
     90        } // if
     91
     92        ast::Expr * cond = nullptr;
    8793        if ( ctl->condition ) {
    8894                // compare the provided condition against 0
    8995                cond = notZeroExpr( maybeMoveBuild( ctl->condition ) );
    9096        } else {
    91                 for ( Statement * stmt : init ) {
     97                for ( ast::ptr<ast::Stmt> & stmt : inits ) {
    9298                        // build the && of all of the declared variables compared against 0
    93                         DeclStmt * declStmt = strict_dynamic_cast< DeclStmt * >( stmt );
    94                         DeclarationWithType * dwt = strict_dynamic_cast< DeclarationWithType * >( declStmt->decl );
    95                         Expression * nze = notZeroExpr( new VariableExpr( dwt ) );
    96                         cond = cond ? new LogicalExpr( cond, nze, true ) : nze;
     99                        //auto declStmt = strict_dynamic_cast<ast::DeclStmt *>( stmt );
     100                        auto declStmt = stmt.strict_as<ast::DeclStmt>();
     101                        //ast::DeclWithType * dwt = strict_dynamic_cast<ast::DeclWithType *>( declStmt->decl );
     102                        auto dwt = declStmt->decl.strict_as<ast::DeclWithType>();
     103                        ast::Expr * nze = notZeroExpr( new ast::VariableExpr( dwt->location, dwt ) );
     104                        cond = cond ? new ast::LogicalExpr( dwt->location, cond, nze, ast::AndExpr ) : nze;
    97105                }
    98106        }
     
    101109} // build_if_control
    102110
    103 Statement * build_if( CondCtl * ctl, StatementNode * then, StatementNode * else_ ) {
    104         list< Statement * > astinit;                                            // maybe empty
    105         Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
    106 
    107         Statement * astthen, * astelse = nullptr;
    108         list< Statement * > aststmt;
    109         buildMoveList< Statement, StatementNode >( then, aststmt );
     111ast::Stmt * build_if( const CodeLocation & location, CondCtl * ctl, StatementNode * then, StatementNode * else_ ) {
     112        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
     113        ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
     114
     115        std::vector<ast::ptr<ast::Stmt>> aststmt;
     116        buildMoveList( then, aststmt );
    110117        assert( aststmt.size() == 1 );
    111         astthen = aststmt.front();
    112 
     118        ast::Stmt const * astthen = aststmt.front().release();
     119
     120        ast::Stmt const * astelse = nullptr;
    113121        if ( else_ ) {
    114                 list< Statement * > aststmt;
    115                 buildMoveList< Statement, StatementNode >( else_, aststmt );
     122                std::vector<ast::ptr<ast::Stmt>> aststmt;
     123                buildMoveList( else_, aststmt );
    116124                assert( aststmt.size() == 1 );
    117                 astelse = aststmt.front();
    118         } // if
    119 
    120         return new IfStmt( astcond, astthen, astelse, astinit );
     125                astelse = aststmt.front().release();
     126        } // if
     127
     128        return new ast::IfStmt( location, astcond, astthen, astelse,
     129                std::move( astinit )
     130        );
    121131} // build_if
    122132
    123 Statement * build_switch( bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) {
    124         list< Statement * > aststmt;
    125         buildMoveList< Statement, StatementNode >( stmt, aststmt );
    126         if ( ! isSwitch ) {                                                                     // choose statement
    127                 for ( Statement * stmt : aststmt ) {
    128                         CaseStmt * caseStmt = strict_dynamic_cast< CaseStmt * >( stmt );
    129                         if ( ! caseStmt->stmts.empty() ) {                      // code after "case" => end of case list
    130                                 CompoundStmt * block = strict_dynamic_cast< CompoundStmt * >( caseStmt->stmts.front() );
    131                                 block->kids.push_back( new BranchStmt( "", BranchStmt::Break ) );
     133// Temporary work around. Split StmtClause off from StatementNode.
     134template<typename clause_t>
     135static void buildMoveClauseList( StatementNode * firstNode,
     136                std::vector<ast::ptr<clause_t>> & output ) {
     137        SemanticErrorException errors;
     138        std::back_insert_iterator<std::vector<ast::ptr<clause_t>>>
     139                out( output );
     140        StatementNode * cur = firstNode;
     141
     142        while ( cur ) {
     143                try {
     144                        auto clause = cur->clause.release();
     145                        if ( auto result = dynamic_cast<clause_t *>( clause ) ) {
     146                                *out++ = result;
     147                        } else {
     148                                assertf(false, __PRETTY_FUNCTION__ );
     149                                SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." );
     150                        } // if
     151                } catch( SemanticErrorException & e ) {
     152                        errors.append( e );
     153                } // try
     154                ParseNode * temp = cur->get_next();
     155                // Should not return nullptr, then it is non-homogeneous:
     156                cur = dynamic_cast<StatementNode *>( temp );
     157                if ( !cur && temp ) {
     158                        SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." );
     159                } // if
     160        } // while
     161        if ( ! errors.isEmpty() ) {
     162                throw errors;
     163        } // if
     164        // Usually in the wrapper.
     165        delete firstNode;
     166}
     167
     168ast::Stmt * build_switch( const CodeLocation & location, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ) {
     169        std::vector<ast::ptr<ast::CaseClause>> aststmt;
     170        buildMoveClauseList( stmt, aststmt );
     171        // If it is not a switch it is a choose statement.
     172        if ( ! isSwitch ) {
     173                for ( ast::ptr<ast::CaseClause> & stmt : aststmt ) {
     174                        // Code after "case" is the end of case list.
     175                        if ( !stmt->stmts.empty() ) {
     176                                auto mutStmt = ast::mutate( stmt.get() );
     177                                // I believe the stmts are actually always one block.
     178                                auto stmts = mutStmt->stmts.front().get_and_mutate();
     179                                auto block = strict_dynamic_cast<ast::CompoundStmt *>( stmts );
     180                                block->kids.push_back( new ast::BranchStmt( block->location,
     181                                        ast::BranchStmt::Break,
     182                                        ast::Label( block->location ) ) );
     183                                stmt = mutStmt;
    132184                        } // if
    133185                } // for
    134186        } // if
    135187        // aststmt.size() == 0 for switch (...) {}, i.e., no declaration or statements
    136         return new SwitchStmt( maybeMoveBuild( ctl ), aststmt );
     188        return new ast::SwitchStmt( location,
     189                maybeMoveBuild( ctl ), std::move( aststmt ) );
    137190} // build_switch
    138191
    139 Statement * build_case( ExpressionNode * ctl ) {
    140         return new CaseStmt( maybeMoveBuild( ctl ), {} ); // stmt starts empty and then added to
     192ast::CaseClause * build_case( ExpressionNode * ctl ) {
     193        // stmt starts empty and then added to
     194        auto expr = maybeMoveBuild( ctl );
     195        return new ast::CaseClause( expr->location, expr, {} );
    141196} // build_case
    142197
    143 Statement * build_default() {
    144         return new CaseStmt( nullptr, {}, true );                       // stmt starts empty and then added to
     198ast::CaseClause * build_default( const CodeLocation & location ) {
     199        // stmt starts empty and then added to
     200        return new ast::CaseClause( location, nullptr, {} );
    145201} // build_default
    146202
    147 Statement * build_while( CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) {
    148         list< Statement * > astinit;                                            // maybe empty
    149         Expression * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
    150 
    151         list< Statement * > aststmt;                                            // loop body, compound created if empty
    152         buildMoveList< Statement, StatementNode >( stmt, aststmt );
     203ast::Stmt * build_while( const CodeLocation & location, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) {
     204        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
     205        ast::Expr * astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set
     206
     207        std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
     208        buildMoveList( stmt, aststmt );
    153209        assert( aststmt.size() == 1 );
    154210
    155         list< Statement * > astelse;                                            // else clause, maybe empty
    156         buildMoveList< Statement, StatementNode >( else_, astelse );
    157 
    158         return new WhileDoStmt( astcond, aststmt.front(), astelse.front(), astinit, false );
     211        std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
     212        buildMoveList( else_, astelse );
     213        assert( astelse.size() <= 1 );
     214
     215        return new ast::WhileDoStmt( location,
     216                astcond,
     217                aststmt.front(),
     218                astelse.empty() ? nullptr : astelse.front().release(),
     219                std::move( astinit ),
     220                false
     221        );
    159222} // build_while
    160223
    161 Statement * build_do_while( ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) {
    162         list< Statement * > aststmt;                                            // loop body, compound created if empty
    163         buildMoveList< Statement, StatementNode >( stmt, aststmt );
     224ast::Stmt * build_do_while( const CodeLocation & location, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) {
     225        std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
     226        buildMoveList( stmt, aststmt );
    164227        assert( aststmt.size() == 1 );                                          // compound created if empty
    165228
    166         list< Statement * > astelse;                                            // else clause, maybe empty
    167         buildMoveList< Statement, StatementNode >( else_, astelse );
     229        std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
     230        buildMoveList( else_, astelse );
     231        assert( astelse.size() <= 1 );
    168232
    169233        // do-while cannot have declarations in the contitional, so init is always empty
    170         return new WhileDoStmt( notZeroExpr( maybeMoveBuild( ctl ) ), aststmt.front(), astelse.front(), {}, true );
     234        return new ast::WhileDoStmt( location,
     235                notZeroExpr( maybeMoveBuild( ctl ) ),
     236                aststmt.front(),
     237                astelse.empty() ? nullptr : astelse.front().release(),
     238                {},
     239                true
     240        );
    171241} // build_do_while
    172242
    173 Statement * build_for( ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {
    174         list< Statement * > astinit;                                            // maybe empty
     243ast::Stmt * build_for( const CodeLocation & location, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {
     244        std::vector<ast::ptr<ast::Stmt>> astinit;                                               // maybe empty
    175245        buildMoveList( forctl->init, astinit );
    176246
    177         Expression * astcond = nullptr;                                         // maybe empty
     247        ast::Expr * astcond = nullptr;                                          // maybe empty
    178248        astcond = notZeroExpr( maybeMoveBuild( forctl->condition ) );
    179249
    180         Expression * astincr = nullptr;                                         // maybe empty
     250        ast::Expr * astincr = nullptr;                                          // maybe empty
    181251        astincr = maybeMoveBuild( forctl->change );
    182252        delete forctl;
    183253
    184         list< Statement * > aststmt;                                            // loop body, compound created if empty
    185         buildMoveList< Statement, StatementNode >( stmt, aststmt );
     254        std::vector<ast::ptr<ast::Stmt>> aststmt;                                               // loop body, compound created if empty
     255        buildMoveList( stmt, aststmt );
    186256        assert( aststmt.size() == 1 );
    187257
    188         list< Statement * > astelse;                                            // else clause, maybe empty
    189         buildMoveList< Statement, StatementNode >( else_, astelse );
    190 
    191         return new ForStmt( astinit, astcond, astincr, aststmt.front(), astelse.front() );
     258        std::vector<ast::ptr<ast::Stmt>> astelse;                                               // else clause, maybe empty
     259        buildMoveList( else_, astelse );
     260        assert( astelse.size() <= 1 );
     261
     262        return new ast::ForStmt( location,
     263                std::move( astinit ),
     264                astcond,
     265                astincr,
     266                aststmt.front(),
     267                astelse.empty() ? nullptr : astelse.front().release()
     268        );
    192269} // build_for
    193270
    194 Statement * build_branch( BranchStmt::Type kind ) {
    195         Statement * ret = new BranchStmt( "", kind );
     271ast::Stmt * build_branch( const CodeLocation & location, ast::BranchStmt::Kind kind ) {
     272        return new ast::BranchStmt( location,
     273                kind,
     274                ast::Label( location )
     275        );
     276} // build_branch
     277
     278ast::Stmt * build_branch( const CodeLocation & location, string * identifier, ast::BranchStmt::Kind kind ) {
     279        ast::Stmt * ret = new ast::BranchStmt( location,
     280                kind,
     281                ast::Label( location, *identifier )
     282        );
     283        delete identifier;                                                                      // allocated by lexer
    196284        return ret;
    197285} // build_branch
    198286
    199 Statement * build_branch( string * identifier, BranchStmt::Type kind ) {
    200         Statement * ret = new BranchStmt( * identifier, kind );
    201         delete identifier;                                                                      // allocated by lexer
    202         return ret;
    203 } // build_branch
    204 
    205 Statement * build_computedgoto( ExpressionNode * ctl ) {
    206         return new BranchStmt( maybeMoveBuild( ctl ), BranchStmt::Goto );
     287ast::Stmt * build_computedgoto( ExpressionNode * ctl ) {
     288        ast::Expr * expr = maybeMoveBuild( ctl );
     289        return new ast::BranchStmt( expr->location, expr );
    207290} // build_computedgoto
    208291
    209 Statement * build_return( ExpressionNode * ctl ) {
    210         list< Expression * > exps;
     292ast::Stmt * build_return( const CodeLocation & location, ExpressionNode * ctl ) {
     293        std::vector<ast::ptr<ast::Expr>> exps;
    211294        buildMoveList( ctl, exps );
    212         return new ReturnStmt( exps.size() > 0 ? exps.back() : nullptr );
     295        return new ast::ReturnStmt( location,
     296                exps.size() > 0 ? exps.back().release() : nullptr
     297        );
    213298} // build_return
    214299
    215 Statement * build_throw( ExpressionNode * ctl ) {
    216         list< Expression * > exps;
     300static ast::Stmt * build_throw_stmt(
     301                const CodeLocation & location,
     302                ExpressionNode * ctl,
     303                ast::ExceptionKind kind ) {
     304        std::vector<ast::ptr<ast::Expr>> exps;
    217305        buildMoveList( ctl, exps );
    218306        assertf( exps.size() < 2, "CFA internal error: leaking memory" );
    219         return new ThrowStmt( ThrowStmt::Terminate, !exps.empty() ? exps.back() : nullptr );
     307        return new ast::ThrowStmt( location,
     308                kind,
     309                !exps.empty() ? exps.back().release() : nullptr,
     310                (ast::Expr *)nullptr
     311        );
     312}
     313
     314ast::Stmt * build_throw( const CodeLocation & loc, ExpressionNode * ctl ) {
     315        return build_throw_stmt( loc, ctl, ast::Terminate );
    220316} // build_throw
    221317
    222 Statement * build_resume( ExpressionNode * ctl ) {
    223         list< Expression * > exps;
    224         buildMoveList( ctl, exps );
    225         assertf( exps.size() < 2, "CFA internal error: leaking memory" );
    226         return new ThrowStmt( ThrowStmt::Resume, !exps.empty() ? exps.back() : nullptr );
     318ast::Stmt * build_resume( const CodeLocation & loc, ExpressionNode * ctl ) {
     319        return build_throw_stmt( loc, ctl, ast::Resume );
    227320} // build_resume
    228321
    229 Statement * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {
     322ast::Stmt * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {
    230323        (void)ctl;
    231324        (void)target;
     
    233326} // build_resume_at
    234327
    235 Statement * build_try( StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) {
    236         list< CatchStmt * > aststmt;
    237         buildMoveList< CatchStmt, StatementNode >( catch_, aststmt );
    238         CompoundStmt * tryBlock = strict_dynamic_cast< CompoundStmt * >( maybeMoveBuild( try_ ) );
    239         FinallyStmt * finallyBlock = dynamic_cast< FinallyStmt * >( maybeMoveBuild( finally_ ) );
    240         return new TryStmt( tryBlock, aststmt, finallyBlock );
     328ast::Stmt * build_try( const CodeLocation & location, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ) {
     329        std::vector<ast::ptr<ast::CatchClause>> aststmt;
     330        buildMoveClauseList( catch_, aststmt );
     331        ast::CompoundStmt * tryBlock = strict_dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( try_ ) );
     332        ast::FinallyClause * finallyBlock = nullptr;
     333        if ( finally_ ) {
     334                finallyBlock = dynamic_cast<ast::FinallyClause *>( finally_->clause.release() );
     335        }
     336        return new ast::TryStmt( location,
     337                tryBlock,
     338                std::move( aststmt ),
     339                finallyBlock
     340        );
    241341} // build_try
    242342
    243 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {
    244         list< Statement * > aststmt;
    245         buildMoveList< Statement, StatementNode >( body, aststmt );
     343ast::CatchClause * build_catch( const CodeLocation & location, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {
     344        std::vector<ast::ptr<ast::Stmt>> aststmt;
     345        buildMoveList( body, aststmt );
    246346        assert( aststmt.size() == 1 );
    247         return new CatchStmt( kind, maybeMoveBuild( decl ), maybeMoveBuild( cond ), aststmt.front() );
     347        return new ast::CatchClause( location,
     348                kind,
     349                maybeMoveBuild( decl ),
     350                maybeMoveBuild( cond ),
     351                aststmt.front().release()
     352        );
    248353} // build_catch
    249354
    250 Statement * build_finally( StatementNode * stmt ) {
    251         list< Statement * > aststmt;
    252         buildMoveList< Statement, StatementNode >( stmt, aststmt );
     355ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) {
     356        std::vector<ast::ptr<ast::Stmt>> aststmt;
     357        buildMoveList( stmt, aststmt );
    253358        assert( aststmt.size() == 1 );
    254         return new FinallyStmt( dynamic_cast< CompoundStmt * >( aststmt.front() ) );
     359        return new ast::FinallyClause( location,
     360                aststmt.front().strict_as<ast::CompoundStmt>()
     361        );
    255362} // build_finally
    256363
    257 SuspendStmt * build_suspend( StatementNode * then, SuspendStmt::Type type ) {
    258         auto node = new SuspendStmt();
    259 
    260         node->type = type;
    261 
    262         list< Statement * > stmts;
    263         buildMoveList< Statement, StatementNode >( then, stmts );
     364ast::SuspendStmt * build_suspend( const CodeLocation & location, StatementNode * then, ast::SuspendStmt::Type type ) {
     365        std::vector<ast::ptr<ast::Stmt>> stmts;
     366        buildMoveList( then, stmts );
     367        ast::CompoundStmt const * then2 = nullptr;
    264368        if(!stmts.empty()) {
    265369                assert( stmts.size() == 1 );
    266                 node->then = dynamic_cast< CompoundStmt * >( stmts.front() );
     370                then2 = stmts.front().strict_as<ast::CompoundStmt>();
    267371        }
    268 
     372        auto node = new ast::SuspendStmt( location, then2, ast::SuspendStmt::None );
     373        node->type = type;
    269374        return node;
    270375} // build_suspend
    271376
    272 WaitForStmt * build_waitfor( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
    273         WaitForStmt::Target target;
    274         target.function = maybeBuild( targetExpr );
     377ast::WaitForStmt * build_waitfor( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
     378        auto clause = new ast::WaitForClause( location );
     379        clause->target_func = maybeBuild( targetExpr );
     380        clause->stmt = maybeMoveBuild( stmt );
     381        clause->cond = notZeroExpr( maybeMoveBuild( when ) );
    275382
    276383        ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() );
    277384        targetExpr->set_next( nullptr );
    278         buildMoveList< Expression >( next, target.arguments );
     385        buildMoveList( next, clause->target_args );
    279386
    280387        delete targetExpr;
    281388
    282         existing->clauses.insert( existing->clauses.begin(), WaitForStmt::Clause{
    283                 std::move( target ),
    284                 maybeMoveBuild( stmt ),
    285                 notZeroExpr( maybeMoveBuild( when ) )
    286         });
     389        existing->clauses.insert( existing->clauses.begin(), clause );
    287390
    288391        return existing;
    289392} // build_waitfor
    290393
    291 WaitForStmt * build_waitfor_else( WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) {
    292         existing->orelse.statement  = maybeMoveBuild( stmt );
    293         existing->orelse.condition  = notZeroExpr( maybeMoveBuild( when ) );
    294 
     394ast::WaitForStmt * build_waitfor_else( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ) {
     395        existing->else_stmt = maybeMoveBuild( stmt );
     396        existing->else_cond = notZeroExpr( maybeMoveBuild( when ) );
     397
     398        (void)location;
    295399        return existing;
    296400} // build_waitfor_else
    297401
    298 WaitForStmt * build_waitfor_timeout( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
    299         existing->timeout.time      = maybeMoveBuild( timeout );
    300         existing->timeout.statement = maybeMoveBuild( stmt );
    301         existing->timeout.condition = notZeroExpr( maybeMoveBuild( when ) );
    302 
     402ast::WaitForStmt * build_waitfor_timeout( const CodeLocation & location, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
     403        existing->timeout_time = maybeMoveBuild( timeout );
     404        existing->timeout_stmt = maybeMoveBuild( stmt );
     405        existing->timeout_cond = notZeroExpr( maybeMoveBuild( when ) );
     406
     407        (void)location;
    303408        return existing;
    304409} // build_waitfor_timeout
    305410
    306 Statement * build_with( ExpressionNode * exprs, StatementNode * stmt ) {
    307         list< Expression * > e;
     411ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) {
     412        std::vector<ast::ptr<ast::Expr>> e;
    308413        buildMoveList( exprs, e );
    309         Statement * s = maybeMoveBuild( stmt );
    310         return new DeclStmt( new WithStmt( e, s ) );
     414        ast::Stmt * s = maybeMoveBuild( stmt );
     415        return new ast::DeclStmt( location, new ast::WithStmt( location, std::move( e ), s ) );
    311416} // build_with
    312417
    313 Statement * build_compound( StatementNode * first ) {
    314         CompoundStmt * cs = new CompoundStmt();
    315         buildMoveList( first, cs->get_kids() );
     418ast::Stmt * build_compound( const CodeLocation & location, StatementNode * first ) {
     419        auto cs = new ast::CompoundStmt( location );
     420        buildMoveList( first, cs->kids );
    316421        return cs;
    317422} // build_compound
     
    321426// statement and wrap it into a compound statement to insert additional code. Hence, all control structures have a
    322427// conical form for code generation.
    323 StatementNode * maybe_build_compound( StatementNode * first ) {
     428StatementNode * maybe_build_compound( const CodeLocation & location, StatementNode * first ) {
    324429        // Optimization: if the control-structure statement is a compound statement, do not wrap it.
    325430        // e.g., if (...) {...} do not wrap the existing compound statement.
    326         if ( ! dynamic_cast<CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr
    327                 CompoundStmt * cs = new CompoundStmt();
    328                 buildMoveList( first, cs->get_kids() );
    329                 return new StatementNode( cs );
     431        if ( !dynamic_cast<ast::CompoundStmt *>( first->stmt.get() ) ) { // unique_ptr
     432                return new StatementNode( build_compound( location, first ) );
    330433        } // if
    331434        return first;
     
    333436
    334437// Question
    335 Statement * build_asm( bool voltile, Expression * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
    336         list< Expression * > out, in;
    337         list< ConstantExpr * > clob;
     438ast::Stmt * build_asm( const CodeLocation & location, bool voltile, ast::Expr * instruction, ExpressionNode * output, ExpressionNode * input, ExpressionNode * clobber, LabelNode * gotolabels ) {
     439        std::vector<ast::ptr<ast::Expr>> out, in;
     440        std::vector<ast::ptr<ast::ConstantExpr>> clob;
    338441
    339442        buildMoveList( output, out );
    340443        buildMoveList( input, in );
    341444        buildMoveList( clobber, clob );
    342         return new AsmStmt( voltile, instruction, out, in, clob, gotolabels ? gotolabels->labels : noLabels );
     445        return new ast::AsmStmt( location,
     446                voltile,
     447                instruction,
     448                std::move( out ),
     449                std::move( in ),
     450                std::move( clob ),
     451                gotolabels ? gotolabels->labels : std::vector<ast::Label>()
     452        );
    343453} // build_asm
    344454
    345 Statement * build_directive( string * directive ) {
    346         return new DirectiveStmt( *directive );
     455ast::Stmt * build_directive( const CodeLocation & location, string * directive ) {
     456        auto stmt = new ast::DirectiveStmt( location, *directive );
     457        delete directive;
     458        return stmt;
    347459} // build_directive
    348460
    349 Statement * build_mutex( ExpressionNode * exprs, StatementNode * stmt ) {
    350         list< Expression * > expList;
     461ast::Stmt * build_mutex( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) {
     462        std::vector<ast::ptr<ast::Expr>> expList;
    351463        buildMoveList( exprs, expList );
    352         Statement * body = maybeMoveBuild( stmt );
    353         return new MutexStmt( body, expList );
     464        ast::Stmt * body = maybeMoveBuild( stmt );
     465        return new ast::MutexStmt( location, body, std::move( expList ) );
    354466} // build_mutex
    355467
  • src/Parser/TypeData.cc

    rff71057 re02e13f  
    99// Author           : Rodolfo G. Esteves
    1010// Created On       : Sat May 16 15:12:51 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Feb 19 11:00:46 2023
    13 // Update Count     : 679
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr  4 13:39:00 2023
     13// Update Count     : 680
    1414//
     15
     16#include "TypeData.h"
    1517
    1618#include <cassert>                 // for assert
    1719#include <ostream>                 // for operator<<, ostream, basic_ostream
    1820
     21#include "AST/Decl.hpp"            // for AggregateDecl, ObjectDecl, TypeDe...
     22#include "AST/Init.hpp"            // for SingleInit, ListInit
     23#include "AST/Print.hpp"           // for print
    1924#include "Common/SemanticError.h"  // for SemanticError
    20 #include "Common/utility.h"        // for maybeClone, maybeBuild, maybeMoveB...
     25#include "Common/utility.h"        // for splice, spliceBegin
     26#include "Parser/parserutility.h"  // for maybeCopy, maybeBuild, maybeMoveB...
    2127#include "Parser/ParseNode.h"      // for DeclarationNode, ExpressionNode
    22 #include "SynTree/Declaration.h"   // for TypeDecl, ObjectDecl, FunctionDecl
    23 #include "SynTree/Expression.h"    // for Expression, ConstantExpr (ptr only)
    24 #include "SynTree/Initializer.h"   // for SingleInit, Initializer (ptr only)
    25 #include "SynTree/Statement.h"     // for CompoundStmt, Statement
    26 #include "SynTree/Type.h"          // for BasicType, Type, Type::ForallList
    27 #include "TypeData.h"
    2828
    2929class Attribute;
     
    6060                break;
    6161        case Aggregate:
    62                 aggregate.kind = AggregateDecl::NoAggregate;
     62                aggregate.kind = ast::AggregateDecl::NoAggregate;
    6363                aggregate.name = nullptr;
    6464                aggregate.params = nullptr;
     
    8989                typeexpr = nullptr;
    9090                break;
     91        case Vtable:
    9192        case Builtin:
    92         case Vtable:
    9393                // No unique data to initialize.
    9494                break;
     
    111111        case EnumConstant:
    112112        case GlobalScope:
     113        case Basic:
    113114                // No unique data to deconstruct.
    114                 break;
    115         case Basic:
    116115                break;
    117116        case Array:
     
    250249
    251250void TypeData::print( ostream &os, int indent ) const {
    252         for ( int i = 0; i < Type::NumTypeQualifier; i += 1 ) {
    253                 if ( qualifiers[i] ) os << Type::QualifiersNames[ i ] << ' ';
    254         } // for
     251        ast::print( os, qualifiers );
    255252
    256253        if ( forall ) {
     
    325322                break;
    326323        case Aggregate:
    327                 os << AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;
     324                os << ast::AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;
    328325                if ( aggregate.params ) {
    329326                        os << string( indent + 2, ' ' ) << "with type parameters" << endl;
     
    472469
    473470
    474 template< typename ForallList >
    475 void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) {
    476         buildList( firstNode, outputList );
     471void buildForall(
     472                const DeclarationNode * firstNode,
     473                std::vector<ast::ptr<ast::TypeInstType>> &outputList ) {
     474        {
     475                std::vector<ast::ptr<ast::Type>> tmpList;
     476                buildTypeList( firstNode, tmpList );
     477                for ( auto tmp : tmpList ) {
     478                        outputList.emplace_back(
     479                                strict_dynamic_cast<const ast::TypeInstType *>(
     480                                        tmp.release() ) );
     481                }
     482        }
    477483        auto n = firstNode;
    478         for ( typename ForallList::iterator i = outputList.begin(); i != outputList.end(); ++i, n = (DeclarationNode*)n->get_next() ) {
    479                 TypeDecl * td = static_cast<TypeDecl *>(*i);
    480                 if ( n->variable.tyClass == TypeDecl::Otype ) {
    481                         // add assertion parameters to `type' tyvars in reverse order
    482                         // add dtor:  void ^?{}(T *)
    483                         FunctionType * dtorType = new FunctionType( Type::Qualifiers(), false );
    484                         dtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
    485                         td->get_assertions().push_front( new FunctionDecl( "^?{}", Type::StorageClasses(), LinkageSpec::Cforall, dtorType, nullptr ) );
    486 
    487                         // add copy ctor:  void ?{}(T *, T)
    488                         FunctionType * copyCtorType = new FunctionType( Type::Qualifiers(), false );
    489                         copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
    490                         copyCtorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
    491                         td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, copyCtorType, nullptr ) );
    492 
    493                         // add default ctor:  void ?{}(T *)
    494                         FunctionType * ctorType = new FunctionType( Type::Qualifiers(), false );
    495                         ctorType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
    496                         td->get_assertions().push_front( new FunctionDecl( "?{}", Type::StorageClasses(), LinkageSpec::Cforall, ctorType, nullptr ) );
    497 
    498                         // add assignment operator:  T * ?=?(T *, T)
    499                         FunctionType * assignType = new FunctionType( Type::Qualifiers(), false );
    500                         assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), new TypeInstType( Type::Qualifiers(), td->get_name(), *i ) ), nullptr ) );
    501                         assignType->get_parameters().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
    502                         assignType->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new TypeInstType( Type::Qualifiers(), td->get_name(), *i ), nullptr ) );
    503                         td->get_assertions().push_front( new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Cforall, assignType, nullptr ) );
    504                 } // if
     484        for ( auto i = outputList.begin() ;
     485                        i != outputList.end() ;
     486                        ++i, n = (DeclarationNode*)n->get_next() ) {
     487                // Only the object type class adds additional assertions.
     488                if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
     489                        continue;
     490                }
     491
     492                ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
     493                std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
     494                auto mutTypeDecl = ast::mutate( td );
     495                const CodeLocation & location = mutTypeDecl->location;
     496                *i = mutTypeDecl;
     497
     498                // add assertion parameters to `type' tyvars in reverse order
     499                // add assignment operator:  T * ?=?(T *, T)
     500                newAssertions.push_back( new ast::FunctionDecl(
     501                        location,
     502                        "?=?",
     503                        {}, // forall
     504                        {}, // assertions
     505                        {
     506                                new ast::ObjectDecl(
     507                                        location,
     508                                        "",
     509                                        new ast::ReferenceType( i->get() ),
     510                                        (ast::Init *)nullptr,
     511                                        ast::Storage::Classes(),
     512                                        ast::Linkage::Cforall,
     513                                        (ast::Expr *)nullptr
     514                                ),
     515                                new ast::ObjectDecl(
     516                                        location,
     517                                        "",
     518                                        i->get(),
     519                                        (ast::Init *)nullptr,
     520                                        ast::Storage::Classes(),
     521                                        ast::Linkage::Cforall,
     522                                        (ast::Expr *)nullptr
     523                                ),
     524                        }, // params
     525                        {
     526                                new ast::ObjectDecl(
     527                                        location,
     528                                        "",
     529                                        i->get(),
     530                                        (ast::Init *)nullptr,
     531                                        ast::Storage::Classes(),
     532                                        ast::Linkage::Cforall,
     533                                        (ast::Expr *)nullptr
     534                                ),
     535                        }, // returns
     536                        (ast::CompoundStmt *)nullptr,
     537                        ast::Storage::Classes(),
     538                        ast::Linkage::Cforall
     539                ) );
     540
     541                // add default ctor:  void ?{}(T *)
     542                newAssertions.push_back( new ast::FunctionDecl(
     543                        location,
     544                        "?{}",
     545                        {}, // forall
     546                        {}, // assertions
     547                        {
     548                                new ast::ObjectDecl(
     549                                        location,
     550                                        "",
     551                                        new ast::ReferenceType( i->get() ),
     552                                        (ast::Init *)nullptr,
     553                                        ast::Storage::Classes(),
     554                                        ast::Linkage::Cforall,
     555                                        (ast::Expr *)nullptr
     556                                ),
     557                        }, // params
     558                        {}, // returns
     559                        (ast::CompoundStmt *)nullptr,
     560                        ast::Storage::Classes(),
     561                        ast::Linkage::Cforall
     562                ) );
     563
     564                // add copy ctor:  void ?{}(T *, T)
     565                newAssertions.push_back( new ast::FunctionDecl(
     566                        location,
     567                        "?{}",
     568                        {}, // forall
     569                        {}, // assertions
     570                        {
     571                                new ast::ObjectDecl(
     572                                        location,
     573                                        "",
     574                                        new ast::ReferenceType( i->get() ),
     575                                        (ast::Init *)nullptr,
     576                                        ast::Storage::Classes(),
     577                                        ast::Linkage::Cforall,
     578                                        (ast::Expr *)nullptr
     579                                ),
     580                                new ast::ObjectDecl(
     581                                        location,
     582                                        "",
     583                                        i->get(),
     584                                        (ast::Init *)nullptr,
     585                                        ast::Storage::Classes(),
     586                                        ast::Linkage::Cforall,
     587                                        (ast::Expr *)nullptr
     588                                ),
     589                        }, // params
     590                        {}, // returns
     591                        (ast::CompoundStmt *)nullptr,
     592                        ast::Storage::Classes(),
     593                        ast::Linkage::Cforall
     594                ) );
     595
     596                // add dtor:  void ^?{}(T *)
     597                newAssertions.push_back( new ast::FunctionDecl(
     598                        location,
     599                        "^?{}",
     600                        {}, // forall
     601                        {}, // assertions
     602                        {
     603                                new ast::ObjectDecl(
     604                                        location,
     605                                        "",
     606                                        new ast::ReferenceType( i->get() ),
     607                                        (ast::Init *)nullptr,
     608                                        ast::Storage::Classes(),
     609                                        ast::Linkage::Cforall,
     610                                        (ast::Expr *)nullptr
     611                                ),
     612                        }, // params
     613                        {}, // returns
     614                        (ast::CompoundStmt *)nullptr,
     615                        ast::Storage::Classes(),
     616                        ast::Linkage::Cforall
     617                ) );
     618
     619                spliceBegin( mutTypeDecl->assertions, newAssertions );
     620        } // for
     621}
     622
     623
     624void buildForall(
     625                const DeclarationNode * firstNode,
     626                std::vector<ast::ptr<ast::TypeDecl>> &outputForall ) {
     627        buildList( firstNode, outputForall );
     628        auto n = firstNode;
     629        for ( auto i = outputForall.begin() ;
     630                        i != outputForall.end() ;
     631                        ++i, n = (DeclarationNode*)n->get_next() ) {
     632                // Only the object type class adds additional assertions.
     633                if ( n->variable.tyClass != ast::TypeDecl::Otype ) {
     634                        continue;
     635                }
     636
     637                ast::TypeDecl const * td = i->strict_as<ast::TypeDecl>();
     638                std::vector<ast::ptr<ast::DeclWithType>> newAssertions;
     639                auto mutTypeDecl = ast::mutate( td );
     640                const CodeLocation & location = mutTypeDecl->location;
     641                *i = mutTypeDecl;
     642
     643                // add assertion parameters to `type' tyvars in reverse order
     644                // add assignment operator:  T * ?=?(T *, T)
     645                newAssertions.push_back( new ast::FunctionDecl(
     646                        location,
     647                        "?=?",
     648                        {}, // forall
     649                        {}, // assertions
     650                        {
     651                                new ast::ObjectDecl(
     652                                        location,
     653                                        "",
     654                                        new ast::ReferenceType( new ast::TypeInstType( td->name, *i ) ),
     655                                        (ast::Init *)nullptr,
     656                                        ast::Storage::Classes(),
     657                                        ast::Linkage::Cforall,
     658                                        (ast::Expr *)nullptr
     659                                ),
     660                                new ast::ObjectDecl(
     661                                        location,
     662                                        "",
     663                                        new ast::TypeInstType( td->name, *i ),
     664                                        (ast::Init *)nullptr,
     665                                        ast::Storage::Classes(),
     666                                        ast::Linkage::Cforall,
     667                                        (ast::Expr *)nullptr
     668                                ),
     669                        }, // params
     670                        {
     671                                new ast::ObjectDecl(
     672                                        location,
     673                                        "",
     674                                        new ast::TypeInstType( td->name, *i ),
     675                                        (ast::Init *)nullptr,
     676                                        ast::Storage::Classes(),
     677                                        ast::Linkage::Cforall,
     678                                        (ast::Expr *)nullptr
     679                                ),
     680                        }, // returns
     681                        (ast::CompoundStmt *)nullptr,
     682                        ast::Storage::Classes(),
     683                        ast::Linkage::Cforall
     684                ) );
     685
     686                // add default ctor:  void ?{}(T *)
     687                newAssertions.push_back( new ast::FunctionDecl(
     688                        location,
     689                        "?{}",
     690                        {}, // forall
     691                        {}, // assertions
     692                        {
     693                                new ast::ObjectDecl(
     694                                        location,
     695                                        "",
     696                                        new ast::ReferenceType(
     697                                                new ast::TypeInstType( td->name, i->get() ) ),
     698                                        (ast::Init *)nullptr,
     699                                        ast::Storage::Classes(),
     700                                        ast::Linkage::Cforall,
     701                                        (ast::Expr *)nullptr
     702                                ),
     703                        }, // params
     704                        {}, // returns
     705                        (ast::CompoundStmt *)nullptr,
     706                        ast::Storage::Classes(),
     707                        ast::Linkage::Cforall
     708                ) );
     709
     710                // add copy ctor:  void ?{}(T *, T)
     711                newAssertions.push_back( new ast::FunctionDecl(
     712                        location,
     713                        "?{}",
     714                        {}, // forall
     715                        {}, // assertions
     716                        {
     717                                new ast::ObjectDecl(
     718                                        location,
     719                                        "",
     720                                        new ast::ReferenceType(
     721                                                new ast::TypeInstType( td->name, *i ) ),
     722                                        (ast::Init *)nullptr,
     723                                        ast::Storage::Classes(),
     724                                        ast::Linkage::Cforall,
     725                                        (ast::Expr *)nullptr
     726                                ),
     727                                new ast::ObjectDecl(
     728                                        location,
     729                                        "",
     730                                        new ast::TypeInstType( td->name, *i ),
     731                                        (ast::Init *)nullptr,
     732                                        ast::Storage::Classes(),
     733                                        ast::Linkage::Cforall,
     734                                        (ast::Expr *)nullptr
     735                                ),
     736                        }, // params
     737                        {}, // returns
     738                        (ast::CompoundStmt *)nullptr,
     739                        ast::Storage::Classes(),
     740                        ast::Linkage::Cforall
     741                ) );
     742
     743                // add dtor:  void ^?{}(T *)
     744                newAssertions.push_back( new ast::FunctionDecl(
     745                        location,
     746                        "^?{}",
     747                        {}, // forall
     748                        {}, // assertions
     749                        {
     750                                new ast::ObjectDecl(
     751                                        location,
     752                                        "",
     753                                        new ast::ReferenceType(
     754                                                new ast::TypeInstType( i->get() )
     755                                        ),
     756                                        (ast::Init *)nullptr,
     757                                        ast::Storage::Classes(),
     758                                        ast::Linkage::Cforall,
     759                                        (ast::Expr *)nullptr
     760                                ),
     761                        }, // params
     762                        {}, // returns
     763                        (ast::CompoundStmt *)nullptr,
     764                        ast::Storage::Classes(),
     765                        ast::Linkage::Cforall
     766                ) );
     767
     768                spliceBegin( mutTypeDecl->assertions, newAssertions );
    505769        } // for
    506770} // buildForall
    507771
    508772
    509 Type * typebuild( const TypeData * td ) {
     773ast::Type * typebuild( const TypeData * td ) {
    510774        assert( td );
    511775        switch ( td->kind ) {
    512776        case TypeData::Unknown:
    513777                // fill in implicit int
    514                 return new BasicType( buildQualifiers( td ), BasicType::SignedInt );
     778                return new ast::BasicType(
     779                        ast::BasicType::SignedInt,
     780                        buildQualifiers( td )
     781                );
    515782        case TypeData::Basic:
    516783                return buildBasicType( td );
     
    522789                return buildReference( td );
    523790        case TypeData::Function:
    524                 return buildFunction( td );
     791                return buildFunctionType( td );
    525792        case TypeData::AggregateInst:
    526793                return buildAggInst( td );
    527794        case TypeData::EnumConstant:
    528                 return new EnumInstType( buildQualifiers( td ), "" );
     795                return new ast::EnumInstType( "", buildQualifiers( td ) );
    529796        case TypeData::SymbolicInst:
    530797                return buildSymbolicInst( td );
     
    539806                switch ( td->builtintype ) {
    540807                case DeclarationNode::Zero:
    541                         return new ZeroType( noQualifiers );
     808                        return new ast::ZeroType();
    542809                case DeclarationNode::One:
    543                         return new OneType( noQualifiers );
     810                        return new ast::OneType();
    544811                default:
    545                         return new VarArgsType( buildQualifiers( td ) );
     812                        return new ast::VarArgsType( buildQualifiers( td ) );
    546813                } // switch
    547814        case TypeData::GlobalScope:
    548                 return new GlobalScopeType();
     815                return new ast::GlobalScopeType();
    549816        case TypeData::Qualified:
    550                 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) );
     817                return new ast::QualifiedType(
     818                        typebuild( td->qualified.parent ),
     819                        typebuild( td->qualified.child ),
     820                        buildQualifiers( td )
     821                );
    551822        case TypeData::Symbolic:
    552823        case TypeData::Enum:
     
    587858
    588859
    589 Type::Qualifiers buildQualifiers( const TypeData * td ) {
     860ast::CV::Qualifiers buildQualifiers( const TypeData * td ) {
    590861        return td->qualifiers;
    591862} // buildQualifiers
     
    596867} // genTSError
    597868
    598 Type * buildBasicType( const TypeData * td ) {
    599         BasicType::Kind ret;
     869ast::Type * buildBasicType( const TypeData * td ) {
     870        ast::BasicType::Kind ret;
    600871
    601872        switch ( td->basictype ) {
     
    607878                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
    608879                } // if
    609                 return new VoidType( buildQualifiers( td ) );
     880                return new ast::VoidType( buildQualifiers( td ) );
    610881                break;
    611882
     
    618889                } // if
    619890
    620                 ret = BasicType::Bool;
     891                ret = ast::BasicType::Bool;
    621892                break;
    622893
     
    625896                // character types. The implementation shall define char to have the same range, representation, and behavior as
    626897                // either signed char or unsigned char.
    627                 static BasicType::Kind chartype[] = { BasicType::SignedChar, BasicType::UnsignedChar, BasicType::Char };
     898                static ast::BasicType::Kind chartype[] = { ast::BasicType::SignedChar, ast::BasicType::UnsignedChar, ast::BasicType::Char };
    628899
    629900                if ( td->length != DeclarationNode::NoLength ) {
     
    635906
    636907        case DeclarationNode::Int:
    637                 static BasicType::Kind inttype[2][4] = {
    638                         { BasicType::ShortSignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt },
    639                         { BasicType::ShortUnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt },
     908                static ast::BasicType::Kind inttype[2][4] = {
     909                        { ast::BasicType::ShortSignedInt, ast::BasicType::LongSignedInt, ast::BasicType::LongLongSignedInt, ast::BasicType::SignedInt },
     910                        { ast::BasicType::ShortUnsignedInt, ast::BasicType::LongUnsignedInt, ast::BasicType::LongLongUnsignedInt, ast::BasicType::UnsignedInt },
    640911                };
    641912
     
    648919
    649920        case DeclarationNode::Int128:
    650                 ret = td->signedness == DeclarationNode::Unsigned ? BasicType::UnsignedInt128 : BasicType::SignedInt128;
     921                ret = td->signedness == DeclarationNode::Unsigned ? ast::BasicType::UnsignedInt128 : ast::BasicType::SignedInt128;
    651922                if ( td->length != DeclarationNode::NoLength ) {
    652923                        genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype );
     
    666937        case DeclarationNode::uFloat128:
    667938        case DeclarationNode::uFloat128x:
    668                 static BasicType::Kind floattype[2][12] = {
    669                         { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex, (BasicType::Kind)-1, (BasicType::Kind)-1, BasicType::uFloat16Complex, BasicType::uFloat32Complex, BasicType::uFloat32xComplex, BasicType::uFloat64Complex, BasicType::uFloat64xComplex, BasicType::uFloat128Complex, BasicType::uFloat128xComplex, },
    670                         { BasicType::Float, BasicType::Double, BasicType::LongDouble, BasicType::uuFloat80, BasicType::uuFloat128, BasicType::uFloat16, BasicType::uFloat32, BasicType::uFloat32x, BasicType::uFloat64, BasicType::uFloat64x, BasicType::uFloat128, BasicType::uFloat128x, },
     939                static ast::BasicType::Kind floattype[2][12] = {
     940                        { ast::BasicType::FloatComplex, ast::BasicType::DoubleComplex, ast::BasicType::LongDoubleComplex, (ast::BasicType::Kind)-1, (ast::BasicType::Kind)-1, ast::BasicType::uFloat16Complex, ast::BasicType::uFloat32Complex, ast::BasicType::uFloat32xComplex, ast::BasicType::uFloat64Complex, ast::BasicType::uFloat64xComplex, ast::BasicType::uFloat128Complex, ast::BasicType::uFloat128xComplex, },
     941                        { ast::BasicType::Float, ast::BasicType::Double, ast::BasicType::LongDouble, ast::BasicType::uuFloat80, ast::BasicType::uuFloat128, ast::BasicType::uFloat16, ast::BasicType::uFloat32, ast::BasicType::uFloat32x, ast::BasicType::uFloat64, ast::BasicType::uFloat64x, ast::BasicType::uFloat128, ast::BasicType::uFloat128x, },
    671942                };
    672943
     
    709980        } // switch
    710981
    711         BasicType * bt = new BasicType( buildQualifiers( td ), ret );
    712         buildForall( td->forall, bt->get_forall() );
     982        ast::BasicType * bt = new ast::BasicType( ret, buildQualifiers( td ) );
    713983        return bt;
    714984} // buildBasicType
    715985
    716986
    717 PointerType * buildPointer( const TypeData * td ) {
    718         PointerType * pt;
     987ast::PointerType * buildPointer( const TypeData * td ) {
     988        ast::PointerType * pt;
    719989        if ( td->base ) {
    720                 pt = new PointerType( buildQualifiers( td ), typebuild( td->base ) );
     990                pt = new ast::PointerType(
     991                        typebuild( td->base ),
     992                        buildQualifiers( td )
     993                );
    721994        } else {
    722                 pt = new PointerType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     995                pt = new ast::PointerType(
     996                        new ast::BasicType( ast::BasicType::SignedInt ),
     997                        buildQualifiers( td )
     998                );
    723999        } // if
    724         buildForall( td->forall, pt->get_forall() );
    7251000        return pt;
    7261001} // buildPointer
    7271002
    7281003
    729 ArrayType * buildArray( const TypeData * td ) {
    730         ArrayType * at;
     1004ast::ArrayType * buildArray( const TypeData * td ) {
     1005        ast::ArrayType * at;
    7311006        if ( td->base ) {
    732                 at = new ArrayType( buildQualifiers( td ), typebuild( td->base ), maybeBuild( td->array.dimension ),
    733                                                         td->array.isVarLen, td->array.isStatic );
     1007                at = new ast::ArrayType(
     1008                        typebuild( td->base ),
     1009                        maybeBuild( td->array.dimension ),
     1010                        td->array.isVarLen ? ast::VariableLen : ast::FixedLen,
     1011                        td->array.isStatic ? ast::StaticDim : ast::DynamicDim,
     1012                        buildQualifiers( td )
     1013                );
    7341014        } else {
    735                 at = new ArrayType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ),
    736                                                         maybeBuild( td->array.dimension ), td->array.isVarLen, td->array.isStatic );
     1015                at = new ast::ArrayType(
     1016                        new ast::BasicType( ast::BasicType::SignedInt ),
     1017                        maybeBuild( td->array.dimension ),
     1018                        td->array.isVarLen ? ast::VariableLen : ast::FixedLen,
     1019                        td->array.isStatic ? ast::StaticDim : ast::DynamicDim,
     1020                        buildQualifiers( td )
     1021                );
    7371022        } // if
    738         buildForall( td->forall, at->get_forall() );
    7391023        return at;
    7401024} // buildArray
    7411025
    7421026
    743 ReferenceType * buildReference( const TypeData * td ) {
    744         ReferenceType * rt;
     1027ast::ReferenceType * buildReference( const TypeData * td ) {
     1028        ast::ReferenceType * rt;
    7451029        if ( td->base ) {
    746                 rt = new ReferenceType( buildQualifiers( td ), typebuild( td->base ) );
     1030                rt = new ast::ReferenceType(
     1031                        typebuild( td->base ),
     1032                        buildQualifiers( td )
     1033                );
    7471034        } else {
    748                 rt = new ReferenceType( buildQualifiers( td ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     1035                rt = new ast::ReferenceType(
     1036                        new ast::BasicType( ast::BasicType::SignedInt ),
     1037                        buildQualifiers( td )
     1038                );
    7491039        } // if
    750         buildForall( td->forall, rt->get_forall() );
    7511040        return rt;
    7521041} // buildReference
    7531042
    7541043
    755 AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
     1044ast::AggregateDecl * buildAggregate( const TypeData * td, std::vector<ast::ptr<ast::Attribute>> attributes, ast::Linkage::Spec linkage ) {
    7561045        assert( td->kind == TypeData::Aggregate );
    757         AggregateDecl * at;
     1046        ast::AggregateDecl * at;
    7581047        switch ( td->aggregate.kind ) {
    759         case AggregateDecl::Struct:
    760         case AggregateDecl::Coroutine:
    761         case AggregateDecl::Exception:
    762         case AggregateDecl::Generator:
    763         case AggregateDecl::Monitor:
    764         case AggregateDecl::Thread:
    765                 at = new StructDecl( *td->aggregate.name, td->aggregate.kind, attributes, linkage );
    766                 buildForall( td->aggregate.params, at->get_parameters() );
    767                 break;
    768         case AggregateDecl::Union:
    769                 at = new UnionDecl( *td->aggregate.name, attributes, linkage );
    770                 buildForall( td->aggregate.params, at->get_parameters() );
    771                 break;
    772         case AggregateDecl::Trait:
    773                 at = new TraitDecl( *td->aggregate.name, attributes, linkage );
    774                 buildList( td->aggregate.params, at->get_parameters() );
     1048        case ast::AggregateDecl::Struct:
     1049        case ast::AggregateDecl::Coroutine:
     1050        case ast::AggregateDecl::Exception:
     1051        case ast::AggregateDecl::Generator:
     1052        case ast::AggregateDecl::Monitor:
     1053        case ast::AggregateDecl::Thread:
     1054                at = new ast::StructDecl( td->location,
     1055                        *td->aggregate.name,
     1056                        td->aggregate.kind,
     1057                        std::move( attributes ),
     1058                        linkage
     1059                );
     1060                buildForall( td->aggregate.params, at->params );
     1061                break;
     1062        case ast::AggregateDecl::Union:
     1063                at = new ast::UnionDecl( td->location,
     1064                        *td->aggregate.name,
     1065                        std::move( attributes ),
     1066                        linkage
     1067                );
     1068                buildForall( td->aggregate.params, at->params );
     1069                break;
     1070        case ast::AggregateDecl::Trait:
     1071                at = new ast::TraitDecl( td->location,
     1072                        *td->aggregate.name,
     1073                        std::move( attributes ),
     1074                        linkage
     1075                );
     1076                buildList( td->aggregate.params, at->params );
    7751077                break;
    7761078        default:
     
    7781080        } // switch
    7791081
    780         buildList( td->aggregate.fields, at->get_members() );
     1082        buildList( td->aggregate.fields, at->members );
    7811083        at->set_body( td->aggregate.body );
    7821084
     
    7851087
    7861088
    787 ReferenceToType * buildComAggInst( const TypeData * type, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
     1089ast::BaseInstType * buildComAggInst(
     1090                const TypeData * type,
     1091                std::vector<ast::ptr<ast::Attribute>> && attributes,
     1092                ast::Linkage::Spec linkage ) {
    7881093        switch ( type->kind ) {
    7891094        case TypeData::Enum:
    7901095                if ( type->enumeration.body ) {
    791                         EnumDecl * typedecl = buildEnum( type, attributes, linkage );
    792                         return new EnumInstType( buildQualifiers( type ), typedecl );
     1096                        ast::EnumDecl * typedecl =
     1097                                buildEnum( type, std::move( attributes ), linkage );
     1098                        return new ast::EnumInstType(
     1099                                typedecl,
     1100                                buildQualifiers( type )
     1101                        );
    7931102                } else {
    794                         return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
    795                 } // if
     1103                        return new ast::EnumInstType(
     1104                                *type->enumeration.name,
     1105                                buildQualifiers( type )
     1106                        );
     1107                } // if
     1108                break;
    7961109        case TypeData::Aggregate:
    7971110                if ( type->aggregate.body ) {
    798                         AggregateDecl * typedecl = buildAggregate( type, attributes, linkage );
     1111                        ast::AggregateDecl * typedecl =
     1112                                buildAggregate( type, std::move( attributes ), linkage );
    7991113                        switch ( type->aggregate.kind ) {
    800                         case AggregateDecl::Struct:
    801                         case AggregateDecl::Coroutine:
    802                         case AggregateDecl::Monitor:
    803                         case AggregateDecl::Thread:
    804                                 return new StructInstType( buildQualifiers( type ), (StructDecl *)typedecl );
    805                         case AggregateDecl::Union:
    806                                 return new UnionInstType( buildQualifiers( type ), (UnionDecl *)typedecl );
    807                         case AggregateDecl::Trait:
     1114                        case ast::AggregateDecl::Struct:
     1115                        case ast::AggregateDecl::Coroutine:
     1116                        case ast::AggregateDecl::Monitor:
     1117                        case ast::AggregateDecl::Thread:
     1118                                return new ast::StructInstType(
     1119                                        strict_dynamic_cast<ast::StructDecl *>( typedecl ),
     1120                                        buildQualifiers( type )
     1121                                );
     1122                        case ast::AggregateDecl::Union:
     1123                                return new ast::UnionInstType(
     1124                                        strict_dynamic_cast<ast::UnionDecl *>( typedecl ),
     1125                                        buildQualifiers( type )
     1126                                );
     1127                        case ast::AggregateDecl::Trait:
    8081128                                assert( false );
    809                                 //return new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl );
    8101129                                break;
    8111130                        default:
     
    8141133                } else {
    8151134                        switch ( type->aggregate.kind ) {
    816                         case AggregateDecl::Struct:
    817                         case AggregateDecl::Coroutine:
    818                         case AggregateDecl::Monitor:
    819                         case AggregateDecl::Thread:
    820                                 return new StructInstType( buildQualifiers( type ), *type->aggregate.name );
    821                         case AggregateDecl::Union:
    822                                 return new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
    823                         case AggregateDecl::Trait:
    824                                 return new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
     1135                        case ast::AggregateDecl::Struct:
     1136                        case ast::AggregateDecl::Coroutine:
     1137                        case ast::AggregateDecl::Monitor:
     1138                        case ast::AggregateDecl::Thread:
     1139                                return new ast::StructInstType(
     1140                                        *type->aggregate.name,
     1141                                        buildQualifiers( type )
     1142                                );
     1143                        case ast::AggregateDecl::Union:
     1144                                return new ast::UnionInstType(
     1145                                        *type->aggregate.name,
     1146                                        buildQualifiers( type )
     1147                                );
     1148                        case ast::AggregateDecl::Trait:
     1149                                return new ast::TraitInstType(
     1150                                        *type->aggregate.name,
     1151                                        buildQualifiers( type )
     1152                                );
    8251153                        default:
    8261154                                assert( false );
    8271155                        } // switch
    828                 } // if
    829                 return nullptr;
     1156                        break;
     1157                } // if
     1158                break;
    8301159        default:
    8311160                assert( false );
    8321161        } // switch
     1162        assert( false );
    8331163} // buildAggInst
    8341164
    8351165
    836 ReferenceToType * buildAggInst( const TypeData * td ) {
     1166ast::BaseInstType * buildAggInst( const TypeData * td ) {
    8371167        assert( td->kind == TypeData::AggregateInst );
    8381168
    839         // ReferenceToType * ret = buildComAggInst( td->aggInst.aggregate, std::list< Attribute * >() );
    840         ReferenceToType * ret = nullptr;
     1169        ast::BaseInstType * ret = nullptr;
    8411170        TypeData * type = td->aggInst.aggregate;
    8421171        switch ( type->kind ) {
    8431172        case TypeData::Enum:
    844                 return new EnumInstType( buildQualifiers( type ), *type->enumeration.name );
     1173                return new ast::EnumInstType(
     1174                        *type->enumeration.name,
     1175                        buildQualifiers( type )
     1176                );
    8451177        case TypeData::Aggregate:
    8461178                switch ( type->aggregate.kind ) {
    847                 case AggregateDecl::Struct:
    848                 case AggregateDecl::Coroutine:
    849                 case AggregateDecl::Monitor:
    850                 case AggregateDecl::Thread:
    851                         ret = new StructInstType( buildQualifiers( type ), *type->aggregate.name );
     1179                case ast::AggregateDecl::Struct:
     1180                case ast::AggregateDecl::Coroutine:
     1181                case ast::AggregateDecl::Monitor:
     1182                case ast::AggregateDecl::Thread:
     1183                        ret = new ast::StructInstType(
     1184                                *type->aggregate.name,
     1185                                buildQualifiers( type )
     1186                        );
    8521187                        break;
    853                 case AggregateDecl::Union:
    854                         ret = new UnionInstType( buildQualifiers( type ), *type->aggregate.name );
     1188                case ast::AggregateDecl::Union:
     1189                        ret = new ast::UnionInstType(
     1190                                *type->aggregate.name,
     1191                                buildQualifiers( type )
     1192                        );
    8551193                        break;
    856                 case AggregateDecl::Trait:
    857                         ret = new TraitInstType( buildQualifiers( type ), *type->aggregate.name );
     1194                case ast::AggregateDecl::Trait:
     1195                        ret = new ast::TraitInstType(
     1196                                *type->aggregate.name,
     1197                                buildQualifiers( type )
     1198                        );
    8581199                        break;
    8591200                default:
     
    8651206        } // switch
    8661207
    867         ret->set_hoistType( td->aggInst.hoistType );
    868         buildList( td->aggInst.params, ret->get_parameters() );
    869         buildForall( td->forall, ret->get_forall() );
     1208        ret->hoistType = td->aggInst.hoistType;
     1209        buildList( td->aggInst.params, ret->params );
    8701210        return ret;
    8711211} // buildAggInst
    8721212
    8731213
    874 NamedTypeDecl * buildSymbolic( const TypeData * td, std::list< Attribute * > attributes, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) {
     1214ast::NamedTypeDecl * buildSymbolic(
     1215                const TypeData * td,
     1216                std::vector<ast::ptr<ast::Attribute>> attributes,
     1217                const std::string & name,
     1218                ast::Storage::Classes scs,
     1219                ast::Linkage::Spec linkage ) {
    8751220        assert( td->kind == TypeData::Symbolic );
    876         NamedTypeDecl * ret;
     1221        ast::NamedTypeDecl * ret;
    8771222        assert( td->base );
    8781223        if ( td->symbolic.isTypedef ) {
    879                 ret = new TypedefDecl( name, td->location, scs, typebuild( td->base ), linkage );
     1224                ret = new ast::TypedefDecl(
     1225                        td->location,
     1226                        name,
     1227                        scs,
     1228                        typebuild( td->base ),
     1229                        linkage
     1230                );
    8801231        } else {
    881                 ret = new TypeDecl( name, scs, typebuild( td->base ), TypeDecl::Dtype, true );
     1232                ret = new ast::TypeDecl(
     1233                        td->location,
     1234                        name,
     1235                        scs,
     1236                        typebuild( td->base ),
     1237                        ast::TypeDecl::Dtype,
     1238                        true
     1239                );
    8821240        } // if
    883         buildList( td->symbolic.assertions, ret->get_assertions() );
    884         ret->base->attributes.splice( ret->base->attributes.end(), attributes );
     1241        buildList( td->symbolic.assertions, ret->assertions );
     1242        splice( ret->base.get_and_mutate()->attributes, attributes );
    8851243        return ret;
    8861244} // buildSymbolic
    8871245
    8881246
    889 EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {
     1247ast::EnumDecl * buildEnum(
     1248                const TypeData * td,
     1249                std::vector<ast::ptr<ast::Attribute>> && attributes,
     1250                ast::Linkage::Spec linkage ) {
    8901251        assert( td->kind == TypeData::Enum );
    891         Type * baseType = td->base ? typebuild(td->base) : nullptr;
    892         EnumDecl * ret = new EnumDecl( *td->enumeration.name, attributes, td->enumeration.typed, linkage, baseType );
    893         buildList( td->enumeration.constants, ret->get_members() );
    894         list< Declaration * >::iterator members = ret->get_members().begin();
    895         ret->hide = td->enumeration.hiding == EnumHiding::Hide ? EnumDecl::EnumHiding::Hide : EnumDecl::EnumHiding::Visible;
     1252        ast::Type * baseType = td->base ? typebuild(td->base) : nullptr;
     1253        ast::EnumDecl * ret = new ast::EnumDecl(
     1254                td->location,
     1255                *td->enumeration.name,
     1256                td->enumeration.typed,
     1257                std::move( attributes ),
     1258                linkage,
     1259                baseType
     1260        );
     1261        buildList( td->enumeration.constants, ret->members );
     1262        auto members = ret->members.begin();
     1263        ret->hide = td->enumeration.hiding == EnumHiding::Hide ? ast::EnumDecl::EnumHiding::Hide : ast::EnumDecl::EnumHiding::Visible;
    8961264        for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) {
    8971265                if ( cur->enumInLine ) {
     
    9001268                        SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." );
    9011269                } else if ( cur->has_enumeratorValue() ) {
    902                         ObjectDecl * member = dynamic_cast< ObjectDecl * >(* members);
    903                         member->set_init( new SingleInit( maybeMoveBuild( cur->consume_enumeratorValue() ) ) );
     1270                        ast::Decl * member = members->get_and_mutate();
     1271                        ast::ObjectDecl * object = strict_dynamic_cast<ast::ObjectDecl *>( member );
     1272                        object->init = new ast::SingleInit(
     1273                                td->location,
     1274                                maybeMoveBuild( cur->consume_enumeratorValue() ),
     1275                                ast::NoConstruct
     1276                        );
    9041277                } else if ( !cur->initializer ) {
    905                         if ( baseType && (!dynamic_cast<BasicType *>(baseType) || !dynamic_cast<BasicType *>(baseType)->isInteger())) {
     1278                        if ( baseType && (!dynamic_cast<ast::BasicType *>(baseType) || !dynamic_cast<ast::BasicType *>(baseType)->isInteger())) {
    9061279                                SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." );
    9071280                        }
     
    9101283                // if
    9111284        } // for
    912         ret->set_body( td->enumeration.body );
     1285        ret->body = td->enumeration.body;
    9131286        return ret;
    9141287} // buildEnum
    9151288
    9161289
    917 TypeInstType * buildSymbolicInst( const TypeData * td ) {
     1290ast::TypeInstType * buildSymbolicInst( const TypeData * td ) {
    9181291        assert( td->kind == TypeData::SymbolicInst );
    919         TypeInstType * ret = new TypeInstType( buildQualifiers( td ), *td->symbolic.name, false );
    920         buildList( td->symbolic.actuals, ret->get_parameters() );
    921         buildForall( td->forall, ret->get_forall() );
     1292        ast::TypeInstType * ret = new ast::TypeInstType(
     1293                *td->symbolic.name,
     1294                ast::TypeDecl::Dtype,
     1295                buildQualifiers( td )
     1296        );
     1297        buildList( td->symbolic.actuals, ret->params );
    9221298        return ret;
    9231299} // buildSymbolicInst
    9241300
    9251301
    926 TupleType * buildTuple( const TypeData * td ) {
     1302ast::TupleType * buildTuple( const TypeData * td ) {
    9271303        assert( td->kind == TypeData::Tuple );
    928         std::list< Type * > types;
     1304        std::vector<ast::ptr<ast::Type>> types;
    9291305        buildTypeList( td->tuple, types );
    930         TupleType * ret = new TupleType( buildQualifiers( td ), types );
    931         buildForall( td->forall, ret->get_forall() );
     1306        ast::TupleType * ret = new ast::TupleType(
     1307                std::move( types ),
     1308                buildQualifiers( td )
     1309        );
    9321310        return ret;
    9331311} // buildTuple
    9341312
    9351313
    936 TypeofType * buildTypeof( const TypeData * td ) {
     1314ast::TypeofType * buildTypeof( const TypeData * td ) {
    9371315        assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof );
    9381316        assert( td->typeexpr );
    939         // assert( td->typeexpr->expr );
    940         return new TypeofType{ buildQualifiers( td ), td->typeexpr->build(), td->kind == TypeData::Basetypeof };
     1317        return new ast::TypeofType(
     1318                td->typeexpr->build(),
     1319                td->kind == TypeData::Typeof
     1320                        ? ast::TypeofType::Typeof : ast::TypeofType::Basetypeof,
     1321                buildQualifiers( td )
     1322        );
    9411323} // buildTypeof
    9421324
    9431325
    944 VTableType * buildVtable( const TypeData * td ) {
     1326ast::VTableType * buildVtable( const TypeData * td ) {
    9451327        assert( td->base );
    946         return new VTableType{ buildQualifiers( td ), typebuild( td->base ) };
     1328        return new ast::VTableType(
     1329                typebuild( td->base ),
     1330                buildQualifiers( td )
     1331        );
    9471332} // buildVtable
    9481333
    9491334
    950 Declaration * buildDecl( const TypeData * td, const string &name, Type::StorageClasses scs, Expression * bitfieldWidth, Type::FuncSpecifiers funcSpec, LinkageSpec::Spec linkage, Expression *asmName, Initializer * init, std::list< Attribute * > attributes ) {
     1335ast::FunctionDecl * buildFunctionDecl(
     1336                const TypeData * td,
     1337                const string &name,
     1338                ast::Storage::Classes scs,
     1339                ast::Function::Specs funcSpec,
     1340                ast::Linkage::Spec linkage,
     1341                ast::Expr * asmName,
     1342                std::vector<ast::ptr<ast::Attribute>> && attributes ) {
     1343        assert( td->kind == TypeData::Function );
     1344        // For some reason FunctionDecl takes a bool instead of an ArgumentFlag.
     1345        bool isVarArgs = !td->function.params || td->function.params->hasEllipsis;
     1346        ast::CV::Qualifiers cvq = buildQualifiers( td );
     1347        std::vector<ast::ptr<ast::TypeDecl>> forall;
     1348        std::vector<ast::ptr<ast::DeclWithType>> assertions;
     1349        std::vector<ast::ptr<ast::DeclWithType>> params;
     1350        std::vector<ast::ptr<ast::DeclWithType>> returns;
     1351        buildList( td->function.params, params );
     1352        buildForall( td->forall, forall );
     1353        // Functions do not store their assertions there anymore.
     1354        for ( ast::ptr<ast::TypeDecl> & type_param : forall ) {
     1355                auto mut = type_param.get_and_mutate();
     1356                splice( assertions, mut->assertions );
     1357        }
     1358        if ( td->base ) {
     1359                switch ( td->base->kind ) {
     1360                case TypeData::Tuple:
     1361                        buildList( td->base->tuple, returns );
     1362                        break;
     1363                default:
     1364                        returns.push_back( dynamic_cast<ast::DeclWithType *>(
     1365                                buildDecl(
     1366                                        td->base,
     1367                                        "",
     1368                                        ast::Storage::Classes(),
     1369                                        (ast::Expr *)nullptr, // bitfieldWidth
     1370                                        ast::Function::Specs(),
     1371                                        ast::Linkage::Cforall,
     1372                                        (ast::Expr *)nullptr // asmName
     1373                                )
     1374                        ) );
     1375                } // switch
     1376        } else {
     1377                returns.push_back( new ast::ObjectDecl(
     1378                        td->location,
     1379                        "",
     1380                        new ast::BasicType( ast::BasicType::SignedInt ),
     1381                        (ast::Init *)nullptr,
     1382                        ast::Storage::Classes(),
     1383                        ast::Linkage::Cforall
     1384                ) );
     1385        } // if
     1386        ast::Stmt * stmt = maybeBuild( td->function.body );
     1387        ast::CompoundStmt * body = dynamic_cast<ast::CompoundStmt *>( stmt );
     1388        ast::FunctionDecl * decl = new ast::FunctionDecl( td->location,
     1389                name,
     1390                std::move( forall ),
     1391                std::move( assertions ),
     1392                std::move( params ),
     1393                std::move( returns ),
     1394                body,
     1395                scs,
     1396                linkage,
     1397                std::move( attributes ),
     1398                funcSpec,
     1399                isVarArgs
     1400        );
     1401        buildList( td->function.withExprs, decl->withExprs );
     1402        decl->asmName = asmName;
     1403        // This may be redundant on a declaration.
     1404        decl->type.get_and_mutate()->qualifiers = cvq;
     1405        return decl;
     1406} // buildFunctionDecl
     1407
     1408
     1409ast::Decl * buildDecl(
     1410                const TypeData * td,
     1411                const string &name,
     1412                ast::Storage::Classes scs,
     1413                ast::Expr * bitfieldWidth,
     1414                ast::Function::Specs funcSpec,
     1415                ast::Linkage::Spec linkage,
     1416                ast::Expr * asmName,
     1417                ast::Init * init,
     1418                std::vector<ast::ptr<ast::Attribute>> && attributes ) {
    9511419        if ( td->kind == TypeData::Function ) {
    9521420                if ( td->function.idList ) {                                    // KR function ?
     
    9541422                } // if
    9551423
    956                 FunctionDecl * decl;
    957                 Statement * stmt = maybeBuild( td->function.body );
    958                 CompoundStmt * body = dynamic_cast< CompoundStmt * >( stmt );
    959                 decl = new FunctionDecl( name, scs, linkage, buildFunction( td ), body, attributes, funcSpec );
    960                 buildList( td->function.withExprs, decl->withExprs );
    961                 return decl->set_asmName( asmName );
     1424                return buildFunctionDecl(
     1425                        td, name, scs, funcSpec, linkage,
     1426                        asmName, std::move( attributes ) );
    9621427        } else if ( td->kind == TypeData::Aggregate ) {
    963                 return buildAggregate( td, attributes, linkage );
     1428                return buildAggregate( td, std::move( attributes ), linkage );
    9641429        } else if ( td->kind == TypeData::Enum ) {
    965                 return buildEnum( td, attributes, linkage );
     1430                return buildEnum( td, std::move( attributes ), linkage );
    9661431        } else if ( td->kind == TypeData::Symbolic ) {
    967                 return buildSymbolic( td, attributes, name, scs, linkage );
     1432                return buildSymbolic( td, std::move( attributes ), name, scs, linkage );
    9681433        } else {
    969                 return (new ObjectDecl( name, scs, linkage, bitfieldWidth, typebuild( td ), init, attributes ))->set_asmName( asmName );
     1434                auto ret = new ast::ObjectDecl( td->location,
     1435                        name,
     1436                        typebuild( td ),
     1437                        init,
     1438                        scs,
     1439                        linkage,
     1440                        bitfieldWidth,
     1441                        std::move( attributes )
     1442                );
     1443                ret->asmName = asmName;
     1444                return ret;
    9701445        } // if
    9711446        return nullptr;
     
    9731448
    9741449
    975 FunctionType * buildFunction( const TypeData * td ) {
     1450ast::FunctionType * buildFunctionType( const TypeData * td ) {
    9761451        assert( td->kind == TypeData::Function );
    977         FunctionType * ft = new FunctionType( buildQualifiers( td ), ! td->function.params || td->function.params->hasEllipsis );
    978         buildList( td->function.params, ft->parameters );
     1452        ast::FunctionType * ft = new ast::FunctionType(
     1453                ( !td->function.params || td->function.params->hasEllipsis )
     1454                        ? ast::VariableArgs : ast::FixedArgs,
     1455                buildQualifiers( td )
     1456        );
     1457        buildTypeList( td->function.params, ft->params );
    9791458        buildForall( td->forall, ft->forall );
    9801459        if ( td->base ) {
    9811460                switch ( td->base->kind ) {
    9821461                case TypeData::Tuple:
    983                         buildList( td->base->tuple, ft->returnVals );
     1462                        buildTypeList( td->base->tuple, ft->returns );
    9841463                        break;
    9851464                default:
    986                         ft->get_returnVals().push_back( dynamic_cast< DeclarationWithType * >( buildDecl( td->base, "", Type::StorageClasses(), nullptr, Type::FuncSpecifiers(), LinkageSpec::Cforall, nullptr ) ) );
     1465                        ft->returns.push_back( typebuild( td->base ) );
     1466                        break;
    9871467                } // switch
    9881468        } else {
    989                 ft->get_returnVals().push_back( new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nullptr ) );
     1469                ft->returns.push_back(
     1470                        new ast::BasicType( ast::BasicType::SignedInt ) );
    9901471        } // if
    9911472        return ft;
    992 } // buildFunction
     1473} // buildFunctionType
    9931474
    9941475
     
    10211502                                param->type = decl->type;                               // set copy declaration type to parameter type
    10221503                                decl->type = nullptr;                                   // reset declaration type
    1023                                 param->attributes.splice( param->attributes.end(), decl->attributes ); // copy and reset attributes from declaration to parameter
     1504                                // Copy and reset attributes from declaration to parameter:
     1505                                splice( param->attributes, decl->attributes );
    10241506                        } // if
    10251507                } // for
  • src/Parser/TypeData.h

    rff71057 re02e13f  
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat May 16 15:18:36 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Feb 24 14:25:02 2023
    13 // Update Count     : 205
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Mar  1 10:44:00 2023
     13// Update Count     : 206
    1414//
    1515
     
    2020#include <string>                                                                               // for string
    2121
     22#include "AST/Type.hpp"                                                                 // for Type
    2223#include "ParseNode.h"                                                                  // for DeclarationNode, DeclarationNode::Ag...
    23 #include "SynTree/LinkageSpec.h"                                                // for Spec
    24 #include "SynTree/Type.h"                                                               // for Type, ReferenceToType (ptr only)
    25 #include "SynTree/SynTree.h"                                                    // for Visitor Nodes
    2624
    2725struct TypeData {
     
    3028
    3129        struct Aggregate_t {
    32                 AggregateDecl::Aggregate kind;
     30                ast::AggregateDecl::Aggregate kind;
    3331                const std::string * name = nullptr;
    3432                DeclarationNode * params = nullptr;
     
    4139        };
    4240
    43         struct AggInst_t {                                                                      // handles SUE
     41        struct AggInst_t {
    4442                TypeData * aggregate = nullptr;
    4543                ExpressionNode * params = nullptr;
     
    9391        DeclarationNode::BuiltinType builtintype = DeclarationNode::NoBuiltinType;
    9492
    95         Type::Qualifiers qualifiers;
     93        ast::CV::Qualifiers qualifiers;
    9694        DeclarationNode * forall = nullptr;
    9795
     
    114112};
    115113
    116 Type * typebuild( const TypeData * );
     114ast::Type * typebuild( const TypeData * );
    117115TypeData * typeextractAggregate( const TypeData * td, bool toplevel = true );
    118 Type::Qualifiers buildQualifiers( const TypeData * td );
    119 Type * buildBasicType( const TypeData * );
    120 PointerType * buildPointer( const TypeData * );
    121 ArrayType * buildArray( const TypeData * );
    122 ReferenceType * buildReference( const TypeData * );
    123 AggregateDecl * buildAggregate( const TypeData *, std::list< Attribute * > );
    124 ReferenceToType * buildComAggInst( const TypeData *, std::list< Attribute * > attributes, LinkageSpec::Spec linkage );
    125 ReferenceToType * buildAggInst( const TypeData * );
    126 TypeDecl * buildVariable( const TypeData * );
    127 EnumDecl * buildEnum( const TypeData *, std::list< Attribute * >, LinkageSpec::Spec );
    128 TypeInstType * buildSymbolicInst( const TypeData * );
    129 TupleType * buildTuple( const TypeData * );
    130 TypeofType * buildTypeof( const TypeData * );
    131 VTableType * buildVtable( const TypeData * );
    132 Declaration * buildDecl(
    133         const TypeData *, const std::string &, Type::StorageClasses, Expression *,
    134         Type::FuncSpecifiers funcSpec, LinkageSpec::Spec, Expression * asmName,
    135         Initializer * init = nullptr, std::list< class Attribute * > attributes = std::list< class Attribute * >() );
    136 FunctionType * buildFunction( const TypeData * );
    137 Declaration * addEnumBase( Declaration *, const TypeData * );
     116ast::CV::Qualifiers buildQualifiers( const TypeData * td );
     117ast::Type * buildBasicType( const TypeData * );
     118ast::PointerType * buildPointer( const TypeData * );
     119ast::ArrayType * buildArray( const TypeData * );
     120ast::ReferenceType * buildReference( const TypeData * );
     121ast::AggregateDecl * buildAggregate( const TypeData *, std::vector<ast::ptr<ast::Attribute>> );
     122ast::BaseInstType * buildComAggInst( const TypeData *, std::vector<ast::ptr<ast::Attribute>> && attributes, ast::Linkage::Spec linkage );
     123ast::BaseInstType * buildAggInst( const TypeData * );
     124ast::TypeDecl * buildVariable( const TypeData * );
     125ast::EnumDecl * buildEnum( const TypeData *, std::vector<ast::ptr<ast::Attribute>> &&, ast::Linkage::Spec );
     126ast::TypeInstType * buildSymbolicInst( const TypeData * );
     127ast::TupleType * buildTuple( const TypeData * );
     128ast::TypeofType * buildTypeof( const TypeData * );
     129ast::VTableType * buildVtable( const TypeData * );
     130ast::Decl * buildDecl(
     131        const TypeData *, const std::string &, ast::Storage::Classes, ast::Expr *,
     132        ast::Function::Specs funcSpec, ast::Linkage::Spec, ast::Expr * asmName,
     133        ast::Init * init = nullptr, std::vector<ast::ptr<ast::Attribute>> && attributes = std::vector<ast::ptr<ast::Attribute>>() );
     134ast::FunctionType * buildFunctionType( const TypeData * );
     135ast::Decl * addEnumBase( Declaration *, const TypeData * );
    138136void buildKRFunction( const TypeData::Function_t & function );
    139137
  • src/Parser/lex.ll

    rff71057 re02e13f  
    2323// line-number directives) and C/C++ style comments, which are ignored.
    2424
    25 //**************************** Includes and Defines ****************************
     25// *************************** Includes and Defines ****************************
    2626
    2727#ifdef __clang__
  • src/Parser/parser.yy

    rff71057 re02e13f  
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep  1 20:22:55 2001
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 30 21:28:25 2023
    13 // Update Count     : 6328
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Apr  4 14:02:00 2023
     13// Update Count     : 6329
    1414//
    1515
     
    6464
    6565extern DeclarationNode * parseTree;
    66 extern LinkageSpec::Spec linkage;
     66extern ast::Linkage::Spec linkage;
    6767extern TypedefTable typedefTable;
    6868
    69 stack<LinkageSpec::Spec> linkageStack;
     69stack<ast::Linkage::Spec> linkageStack;
    7070
    7171bool appendStr( string & to, string & from ) {
     
    200200} // fieldDecl
    201201
    202 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )
    203 #define NEW_ONE  new ExpressionNode( build_constantInteger( *new string( "1" ) ) )
     202#define NEW_ZERO new ExpressionNode( build_constantInteger( yylloc, *new string( "0" ) ) )
     203#define NEW_ONE  new ExpressionNode( build_constantInteger( yylloc, *new string( "1" ) ) )
    204204#define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
    205205#define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body."
     
    208208
    209209static ForCtrl * makeForCtrl(
     210                const CodeLocation & location,
    210211                DeclarationNode * init,
    211212                enum OperKinds compop,
     
    213214                ExpressionNode * inc ) {
    214215        // Wrap both comp/inc if they are non-null.
    215         if ( comp ) comp = new ExpressionNode( build_binary_val(
     216        if ( comp ) comp = new ExpressionNode( build_binary_val( location,
    216217                compop,
    217                 new ExpressionNode( build_varref( new string( *init->name ) ) ),
     218                new ExpressionNode( build_varref( location, new string( *init->name ) ) ),
    218219                comp ) );
    219         if ( inc ) inc = new ExpressionNode( build_binary_val(
     220        if ( inc ) inc = new ExpressionNode( build_binary_val( location,
    220221                // choose += or -= for upto/downto
    221222                compop == OperKinds::LThan || compop == OperKinds::LEThan ? OperKinds::PlusAssn : OperKinds::MinusAssn,
    222                 new ExpressionNode( build_varref( new string( *init->name ) ) ),
     223                new ExpressionNode( build_varref( location, new string( *init->name ) ) ),
    223224                inc ) );
    224225        // The StatementNode call frees init->name, it must happen later.
     
    226227}
    227228
    228 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     229ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    229230        if ( index->initializer ) {
    230231                SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
     
    234235        } // if
    235236        DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) );
    236         return makeForCtrl( initDecl, compop, comp, inc );
     237        return makeForCtrl( location, initDecl, compop, comp, inc );
    237238} // forCtrl
    238239
    239 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    240         ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
    241         if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) {
    242                 type = new ExpressionNode( new CastExpr( maybeMoveBuild( type ), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) );
     240ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     241        ast::ConstantExpr * constant = dynamic_cast<ast::ConstantExpr *>(type->expr.get());
     242        if ( constant && (constant->rep == "0" || constant->rep == "1") ) {
     243                type = new ExpressionNode( new ast::CastExpr( location, maybeMoveBuild(type), new ast::BasicType( ast::BasicType::SignedInt ) ) );
    243244        } // if
    244245        DeclarationNode * initDecl = distAttr(
     
    246247                DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) )
    247248        );
    248         return makeForCtrl( initDecl, compop, comp, inc );
     249        return makeForCtrl( location, initDecl, compop, comp, inc );
    249250} // forCtrl
    250251
    251 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    252         if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->expr.get()) ) {
    253                 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
    254         } else if ( CommaExpr * commaExpr = dynamic_cast<CommaExpr *>(index->expr.get()) ) {
    255                 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(commaExpr->arg1 ) ) {
    256                         return forCtrl( type, new string( identifier->name ), start, compop, comp, inc );
     252ForCtrl * forCtrl( const CodeLocation & location, ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
     253        if ( auto identifier = dynamic_cast<ast::NameExpr *>(index->expr.get()) ) {
     254                return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
     255        } else if ( auto commaExpr = dynamic_cast<ast::CommaExpr *>( index->expr.get() ) ) {
     256                if ( auto identifier = commaExpr->arg1.as<ast::NameExpr>() ) {
     257                        return forCtrl( location, type, new string( identifier->name ), start, compop, comp, inc );
    257258                } else {
    258259                        SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr;
     
    299300        ExpressionNode * en;
    300301        DeclarationNode * decl;
    301         AggregateDecl::Aggregate aggKey;
    302         TypeDecl::Kind tclass;
     302        ast::AggregateDecl::Aggregate aggKey;
     303        ast::TypeDecl::Kind tclass;
    303304        StatementNode * sn;
    304         WaitForStmt * wfs;
    305         Expression * constant;
     305        ast::WaitForStmt * wfs;
     306        ast::Expr * constant;
    306307        CondCtl * ifctl;
    307308        ForCtrl * fctl;
     
    313314        bool flag;
    314315        EnumHiding hide;
    315         CatchStmt::Kind catch_kind;
    316         GenericExpr * genexpr;
     316        ast::ExceptionKind catch_kind;
     317        ast::GenericExpr * genexpr;
    317318}
    318319
    319 //************************* TERMINAL TOKENS ********************************
     320// ************************ TERMINAL TOKENS ********************************
    320321
    321322// keywords
     
    611612constant:
    612613                // ENUMERATIONconstant is not included here; it is treated as a variable with type "enumeration constant".
    613         INTEGERconstant                                                         { $$ = new ExpressionNode( build_constantInteger( *$1 ) ); }
    614         | FLOATING_DECIMALconstant                                      { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    615         | FLOATING_FRACTIONconstant                                     { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    616         | FLOATINGconstant                                                      { $$ = new ExpressionNode( build_constantFloat( *$1 ) ); }
    617         | CHARACTERconstant                                                     { $$ = new ExpressionNode( build_constantChar( *$1 ) ); }
     614        INTEGERconstant                                                         { $$ = new ExpressionNode( build_constantInteger( yylloc, *$1 ) ); }
     615        | FLOATING_DECIMALconstant                                      { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
     616        | FLOATING_FRACTIONconstant                                     { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
     617        | FLOATINGconstant                                                      { $$ = new ExpressionNode( build_constantFloat( yylloc, *$1 ) ); }
     618        | CHARACTERconstant                                                     { $$ = new ExpressionNode( build_constantChar( yylloc, *$1 ) ); }
    618619        ;
    619620
     
    641642
    642643string_literal:
    643         string_literal_list                                                     { $$ = build_constantStr( *$1 ); }
     644        string_literal_list                                                     { $$ = build_constantStr( yylloc, *$1 ); }
    644645        ;
    645646
     
    658659primary_expression:
    659660        IDENTIFIER                                                                                      // typedef name cannot be used as a variable name
    660                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     661                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    661662        | quasi_keyword
    662                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     663                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    663664        | TYPEDIMname                                                                           // CFA, generic length argument
    664665                // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); }
    665666                // { $$ = new ExpressionNode( build_varref( $1 ) ); }
    666                 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); }
     667                { $$ = new ExpressionNode( build_dimensionref( yylloc, $1 ) ); }
    667668        | tuple
    668669        | '(' comma_expression ')'
    669670                { $$ = $2; }
    670671        | '(' compound_statement ')'                                            // GCC, lambda expression
    671                 { $$ = new ExpressionNode( new StmtExpr( dynamic_cast<CompoundStmt *>(maybeMoveBuild( $2 ) ) ) ); }
     672                { $$ = new ExpressionNode( new ast::StmtExpr( yylloc, dynamic_cast<ast::CompoundStmt *>( maybeMoveBuild( $2 ) ) ) ); }
    672673        | type_name '.' identifier                                                      // CFA, nested type
    673                 { $$ = new ExpressionNode( build_qualified_expr( $1, build_varref( $3 ) ) ); }
     674                { $$ = new ExpressionNode( build_qualified_expr( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    674675        | type_name '.' '[' field_name_list ']'                         // CFA, nested type / tuple field selector
    675676                { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; }
     
    703704                {
    704705                        // steal the association node from the singleton and delete the wrapper
    705                         $1->associations.splice($1->associations.end(), $3->associations);
     706                        assert( 1 == $3->associations.size() );
     707                        $1->associations.push_back( $3->associations.front() );
    706708                        delete $3;
    707709                        $$ = $1;
     
    713715                {
    714716                        // create a GenericExpr wrapper with one association pair
    715                         $$ = new GenericExpr( nullptr, { { maybeMoveBuildType($1), maybeMoveBuild( $3 ) } } );
     717                        $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuildType( $1 ), maybeMoveBuild( $3 ) } } );
    716718                }
    717719        | DEFAULT ':' assignment_expression
    718                 { $$ = new GenericExpr( nullptr, { { maybeMoveBuild( $3 ) } } ); }
     720                { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); }
    719721        ;
    720722
     
    725727                // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts.
    726728                // Current: Commas in subscripts make tuples.
    727                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
     729                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $5 ) ) )) ) ); }
    728730        | postfix_expression '[' assignment_expression ']'
    729731                // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a
     
    731733                // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is
    732734                // equivalent to the old x[i,j].
    733                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
     735                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    734736        | constant '[' assignment_expression ']'                        // 3[a], 'a'[a], 3.5[a]
    735                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, $1, $3 ) ); }
     737                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, $1, $3 ) ); }
    736738        | string_literal '[' assignment_expression ']'          // "abc"[3], 3["abc"]
    737                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }
     739                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Index, new ExpressionNode( $1 ), $3 ) ); }
    738740        | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call
    739741                {
    740742                        Token fn;
    741743                        fn.str = new std::string( "?{}" );                      // location undefined - use location of '{'?
    742                         $$ = new ExpressionNode( new ConstructorExpr( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
     744                        $$ = new ExpressionNode( new ast::ConstructorExpr( yylloc, build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $1 )->set_last( $3 ) ) ) );
    743745                }
    744746        | postfix_expression '(' argument_expression_list_opt ')'
    745                 { $$ = new ExpressionNode( build_func( $1, $3 ) ); }
     747                { $$ = new ExpressionNode( build_func( yylloc, $1, $3 ) ); }
    746748        | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')'
    747749                // { SemanticError( yylloc, "va_arg is currently unimplemented." ); $$ = nullptr; }
    748                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( new string( "__builtin_va_arg") ) ),
     750                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, new string( "__builtin_va_arg") ) ),
    749751                                                                                           (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); }
    750752        | postfix_expression '`' identifier                                     // CFA, postfix call
    751                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     753                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    752754        | constant '`' identifier                                                       // CFA, postfix call
    753                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), $1 ) ); }
     755                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), $1 ) ); }
    754756        | string_literal '`' identifier                                         // CFA, postfix call
    755                 { $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }
     757                { $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, build_postfix_name( $3 ) ) ), new ExpressionNode( $1 ) ) ); }
    756758        | postfix_expression '.' identifier
    757                 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref( $3 ) ) ); }
     759                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    758760        | postfix_expression '.' INTEGERconstant                        // CFA, tuple index
    759                 { $$ = new ExpressionNode( build_fieldSel( $1, build_constantInteger( *$3 ) ) ); }
     761                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
    760762        | postfix_expression FLOATING_FRACTIONconstant          // CFA, tuple index
    761                 { $$ = new ExpressionNode( build_fieldSel( $1, build_field_name_FLOATING_FRACTIONconstant( *$2 ) ) ); }
     763                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 ) ) ); }
    762764        | postfix_expression '.' '[' field_name_list ']'        // CFA, tuple field selector
    763                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
     765                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    764766        | postfix_expression '.' aggregate_control
    765                 { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); }
     767                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $3, $1 ) ); }
    766768        | postfix_expression ARROW identifier
    767                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); }
     769                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); }
    768770        | postfix_expression ARROW INTEGERconstant                      // CFA, tuple index
    769                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); }
     771                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_constantInteger( yylloc, *$3 ) ) ); }
    770772        | postfix_expression ARROW '[' field_name_list ']'      // CFA, tuple field selector
    771                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
     773                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    772774        | postfix_expression ICR
    773                 { $$ = new ExpressionNode( build_unary_val( OperKinds::IncrPost, $1 ) ); }
     775                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::IncrPost, $1 ) ); }
    774776        | postfix_expression DECR
    775                 { $$ = new ExpressionNode( build_unary_val( OperKinds::DecrPost, $1 ) ); }
     777                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::DecrPost, $1 ) ); }
    776778        | '(' type_no_function ')' '{' initializer_list_opt comma_opt '}' // C99, compound-literal
    777                 { $$ = new ExpressionNode( build_compoundLiteral( $2, new InitializerNode( $5, true ) ) ); }
     779                { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, new InitializerNode( $5, true ) ) ); }
    778780        | '(' type_no_function ')' '@' '{' initializer_list_opt comma_opt '}' // CFA, explicit C compound-literal
    779                 { $$ = new ExpressionNode( build_compoundLiteral( $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
     781                { $$ = new ExpressionNode( build_compoundLiteral( yylloc, $2, (new InitializerNode( $6, true ))->set_maybeConstructed( false ) ) ); }
    780782        | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call
    781783                {
    782784                        Token fn;
    783785                        fn.str = new string( "^?{}" );                          // location undefined
    784                         $$ = new ExpressionNode( build_func( new ExpressionNode( build_varref( fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
     786                        $$ = new ExpressionNode( build_func( yylloc, new ExpressionNode( build_varref( yylloc, fn ) ), (ExpressionNode *)( $2 )->set_last( $4 ) ) );
    785787                }
    786788        ;
     
    813815        field_name
    814816        | FLOATING_DECIMALconstant field
    815                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), maybeMoveBuild( $2 ) ) ); }
     817                { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), maybeMoveBuild( $2 ) ) ); }
    816818        | FLOATING_DECIMALconstant '[' field_name_list ']'
    817                 { $$ = new ExpressionNode( build_fieldSel( new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( *$1 ) ), build_tuple( $3 ) ) ); }
     819                { $$ = new ExpressionNode( build_fieldSel( yylloc, new ExpressionNode( build_field_name_FLOATING_DECIMALconstant( yylloc, *$1 ) ), build_tuple( yylloc, $3 ) ) ); }
    818820        | field_name '.' field
    819                 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild( $3 ) ) ); }
     821                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
    820822        | field_name '.' '[' field_name_list ']'
    821                 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); }
     823                { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    822824        | field_name ARROW field
    823                 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild( $3 ) ) ); }
     825                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); }
    824826        | field_name ARROW '[' field_name_list ']'
    825                 { $$ = new ExpressionNode( build_pfieldSel( $1, build_tuple( $4 ) ) ); }
     827                { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_tuple( yylloc, $4 ) ) ); }
    826828        ;
    827829
    828830field_name:
    829831        INTEGERconstant fraction_constants_opt
    830                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_constantInteger( *$1 ), $2 ) ); }
     832                { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_constantInteger( yylloc, *$1 ), $2 ) ); }
    831833        | FLOATINGconstant fraction_constants_opt
    832                 { $$ = new ExpressionNode( build_field_name_fraction_constants( build_field_name_FLOATINGconstant( *$1 ), $2 ) ); }
     834                { $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_field_name_FLOATINGconstant( yylloc, *$1 ), $2 ) ); }
    833835        | identifier_at fraction_constants_opt                          // CFA, allow anonymous fields
    834836                {
    835                         $$ = new ExpressionNode( build_field_name_fraction_constants( build_varref( $1 ), $2 ) );
     837                        $$ = new ExpressionNode( build_field_name_fraction_constants( yylloc, build_varref( yylloc, $1 ), $2 ) );
    836838                }
    837839        ;
     
    842844        | fraction_constants_opt FLOATING_FRACTIONconstant
    843845                {
    844                         Expression * constant = build_field_name_FLOATING_FRACTIONconstant( *$2 );
    845                         $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( $1, constant ) ) : new ExpressionNode( constant );
     846                        ast::Expr * constant = build_field_name_FLOATING_FRACTIONconstant( yylloc, *$2 );
     847                        $$ = $1 != nullptr ? new ExpressionNode( build_fieldSel( yylloc, $1, constant ) ) : new ExpressionNode( constant );
    846848                }
    847849        ;
     
    862864                {
    863865                        switch ( $1 ) {
    864                           case OperKinds::AddressOf:
    865                                 $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild( $2 ) ) );
     866                        case OperKinds::AddressOf:
     867                                $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) );
    866868                                break;
    867                           case OperKinds::PointTo:
    868                                 $$ = new ExpressionNode( build_unary_val( $1, $2 ) );
     869                        case OperKinds::PointTo:
     870                                $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) );
    869871                                break;
    870                           case OperKinds::And:
    871                                 $$ = new ExpressionNode( new AddressExpr( new AddressExpr( maybeMoveBuild( $2 ) ) ) );
     872                        case OperKinds::And:
     873                                $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) );
    872874                                break;
    873                           default:
     875                        default:
    874876                                assert( false );
    875877                        }
    876878                }
    877879        | unary_operator cast_expression
    878                 { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); }
     880                { $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); }
    879881        | ICR unary_expression
    880                 { $$ = new ExpressionNode( build_unary_val( OperKinds::Incr, $2 ) ); }
     882                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Incr, $2 ) ); }
    881883        | DECR unary_expression
    882                 { $$ = new ExpressionNode( build_unary_val( OperKinds::Decr, $2 ) ); }
     884                { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Decr, $2 ) ); }
    883885        | SIZEOF unary_expression
    884                 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuild( $2 ) ) ); }
     886                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
    885887        | SIZEOF '(' type_no_function ')'
    886                 { $$ = new ExpressionNode( new SizeofExpr( maybeMoveBuildType( $3 ) ) ); }
     888                { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
    887889        | ALIGNOF unary_expression                                                      // GCC, variable alignment
    888                 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuild( $2 ) ) ); }
     890                { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); }
    889891        | ALIGNOF '(' type_no_function ')'                                      // GCC, type alignment
    890                 { $$ = new ExpressionNode( new AlignofExpr( maybeMoveBuildType( $3 ) ) ); }
     892                { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); }
    891893        | OFFSETOF '(' type_no_function ',' identifier ')'
    892                 { $$ = new ExpressionNode( build_offsetOf( $3, build_varref( $5 ) ) ); }
     894                { $$ = new ExpressionNode( build_offsetOf( yylloc, $3, build_varref( yylloc, $5 ) ) ); }
    893895        | TYPEID '(' type_no_function ')'
    894896                {
     
    915917        unary_expression
    916918        | '(' type_no_function ')' cast_expression
    917                 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     919                { $$ = new ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
    918920        | '(' aggregate_control '&' ')' cast_expression         // CFA
    919                 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
     921                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
    920922        | '(' aggregate_control '*' ')' cast_expression         // CFA
    921                 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }
     923                { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); }
    922924        | '(' VIRTUAL ')' cast_expression                                       // CFA
    923                 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }
     925                { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }
    924926        | '(' VIRTUAL type_no_function ')' cast_expression      // CFA
    925                 { $$ = new ExpressionNode( new VirtualCastExpr( maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }
     927                { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $5 ), maybeMoveBuildType( $3 ) ) ); }
    926928        | '(' RETURN type_no_function ')' cast_expression       // CFA
    927929                { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; }
     
    931933                { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; }
    932934//      | '(' type_no_function ')' tuple
    933 //              { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }
     935//              { $$ = new ast::ExpressionNode( build_cast( yylloc, $2, $4 ) ); }
    934936        ;
    935937
     
    949951        cast_expression
    950952        | exponential_expression '\\' cast_expression
    951                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Exp, $1, $3 ) ); }
     953                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Exp, $1, $3 ) ); }
    952954        ;
    953955
     
    955957        exponential_expression
    956958        | multiplicative_expression '*' exponential_expression
    957                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mul, $1, $3 ) ); }
     959                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mul, $1, $3 ) ); }
    958960        | multiplicative_expression '/' exponential_expression
    959                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Div, $1, $3 ) ); }
     961                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Div, $1, $3 ) ); }
    960962        | multiplicative_expression '%' exponential_expression
    961                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Mod, $1, $3 ) ); }
     963                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Mod, $1, $3 ) ); }
    962964        ;
    963965
     
    965967        multiplicative_expression
    966968        | additive_expression '+' multiplicative_expression
    967                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Plus, $1, $3 ) ); }
     969                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Plus, $1, $3 ) ); }
    968970        | additive_expression '-' multiplicative_expression
    969                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Minus, $1, $3 ) ); }
     971                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Minus, $1, $3 ) ); }
    970972        ;
    971973
     
    973975        additive_expression
    974976        | shift_expression LS additive_expression
    975                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LShift, $1, $3 ) ); }
     977                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LShift, $1, $3 ) ); }
    976978        | shift_expression RS additive_expression
    977                 { $$ = new ExpressionNode( build_binary_val( OperKinds::RShift, $1, $3 ) ); }
     979                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::RShift, $1, $3 ) ); }
    978980        ;
    979981
     
    981983        shift_expression
    982984        | relational_expression '<' shift_expression
    983                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LThan, $1, $3 ) ); }
     985                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LThan, $1, $3 ) ); }
    984986        | relational_expression '>' shift_expression
    985                 { $$ = new ExpressionNode( build_binary_val( OperKinds::GThan, $1, $3 ) ); }
     987                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GThan, $1, $3 ) ); }
    986988        | relational_expression LE shift_expression
    987                 { $$ = new ExpressionNode( build_binary_val( OperKinds::LEThan, $1, $3 ) ); }
     989                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::LEThan, $1, $3 ) ); }
    988990        | relational_expression GE shift_expression
    989                 { $$ = new ExpressionNode( build_binary_val( OperKinds::GEThan, $1, $3 ) ); }
     991                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::GEThan, $1, $3 ) ); }
    990992        ;
    991993
     
    993995        relational_expression
    994996        | equality_expression EQ relational_expression
    995                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Eq, $1, $3 ) ); }
     997                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Eq, $1, $3 ) ); }
    996998        | equality_expression NE relational_expression
    997                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Neq, $1, $3 ) ); }
     999                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Neq, $1, $3 ) ); }
    9981000        ;
    9991001
     
    10011003        equality_expression
    10021004        | AND_expression '&' equality_expression
    1003                 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitAnd, $1, $3 ) ); }
     1005                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitAnd, $1, $3 ) ); }
    10041006        ;
    10051007
     
    10071009        AND_expression
    10081010        | exclusive_OR_expression '^' AND_expression
    1009                 { $$ = new ExpressionNode( build_binary_val( OperKinds::Xor, $1, $3 ) ); }
     1011                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::Xor, $1, $3 ) ); }
    10101012        ;
    10111013
     
    10131015        exclusive_OR_expression
    10141016        | inclusive_OR_expression '|' exclusive_OR_expression
    1015                 { $$ = new ExpressionNode( build_binary_val( OperKinds::BitOr, $1, $3 ) ); }
     1017                { $$ = new ExpressionNode( build_binary_val( yylloc, OperKinds::BitOr, $1, $3 ) ); }
    10161018        ;
    10171019
     
    10191021        inclusive_OR_expression
    10201022        | logical_AND_expression ANDAND inclusive_OR_expression
    1021                 { $$ = new ExpressionNode( build_and_or( $1, $3, true ) ); }
     1023                { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::AndExpr ) ); }
    10221024        ;
    10231025
     
    10251027        logical_AND_expression
    10261028        | logical_OR_expression OROR logical_AND_expression
    1027                 { $$ = new ExpressionNode( build_and_or( $1, $3, false ) ); }
     1029                { $$ = new ExpressionNode( build_and_or( yylloc, $1, $3, ast::OrExpr ) ); }
    10281030        ;
    10291031
     
    10311033        logical_OR_expression
    10321034        | logical_OR_expression '?' comma_expression ':' conditional_expression
    1033                 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); }
     1035                { $$ = new ExpressionNode( build_cond( yylloc, $1, $3, $5 ) ); }
    10341036                // FIX ME: computes $1 twice
    10351037        | logical_OR_expression '?' /* empty */ ':' conditional_expression // GCC, omitted first operand
    1036                 { $$ = new ExpressionNode( build_cond( $1, $1, $4 ) ); }
     1038                { $$ = new ExpressionNode( build_cond( yylloc, $1, $1, $4 ) ); }
    10371039        ;
    10381040
     
    10491051//                              SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr;
    10501052//                      } else {
    1051                                 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) );
     1053                                $$ = new ExpressionNode( build_binary_val( yylloc, $2, $1, $3 ) );
    10521054//                      } // if
    10531055                }
     
    10941096//              { $$ = new ExpressionNode( build_tuple( $3 ) ); }
    10951097        '[' ',' tuple_expression_list ']'
    1096                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
     1098                { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $3 ) ) ); }
    10971099        | '[' push assignment_expression pop ',' tuple_expression_list ']'
    1098                 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)($3->set_last( $6 ) ) )); }
     1100                { $$ = new ExpressionNode( build_tuple( yylloc, (ExpressionNode *)($3->set_last( $6 ) ) )); }
    10991101        ;
    11001102
     
    11121114        assignment_expression
    11131115        | comma_expression ',' assignment_expression
    1114                 { $$ = new ExpressionNode( new CommaExpr( maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     1116                { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    11151117        ;
    11161118
     
    11391141        | asm_statement
    11401142        | DIRECTIVE
    1141                 { $$ = new StatementNode( build_directive( $1 ) ); }
     1143                { $$ = new StatementNode( build_directive( yylloc, $1 ) ); }
    11421144        ;
    11431145
     
    11451147                // labels cannot be identifiers 0 or 1
    11461148        identifier_or_type_name ':' attribute_list_opt statement
    1147                 { $$ = $4->add_label( $1, $3 ); }
     1149                { $$ = $4->add_label( yylloc, $1, $3 ); }
    11481150        | identifier_or_type_name ':' attribute_list_opt error // syntax error
    11491151                {
     
    11571159compound_statement:
    11581160        '{' '}'
    1159                 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }
     1161                { $$ = new StatementNode( build_compound( yylloc, (StatementNode *)0 ) ); }
    11601162        | '{' push
    11611163          local_label_declaration_opt                                           // GCC, local labels appear at start of block
    11621164          statement_decl_list                                                           // C99, intermix declarations and statements
    11631165          pop '}'
    1164                 { $$ = new StatementNode( build_compound( $4 ) ); }
     1166                { $$ = new StatementNode( build_compound( yylloc, $4 ) ); }
    11651167        ;
    11661168
     
    11931195expression_statement:
    11941196        comma_expression_opt ';'
    1195                 { $$ = new StatementNode( build_expr( $1 ) ); }
     1197                { $$ = new StatementNode( build_expr( yylloc, $1 ) ); }
    11961198        ;
    11971199
     
    12021204                { $$ = $2; }
    12031205        | SWITCH '(' comma_expression ')' case_clause
    1204                 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }
     1206                { $$ = new StatementNode( build_switch( yylloc, true, $3, $5 ) ); }
    12051207        | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    12061208                {
    1207                         StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) );
     1209                        StatementNode *sw = new StatementNode( build_switch( yylloc, true, $3, $8 ) );
    12081210                        // The semantics of the declaration list is changed to include associated initialization, which is performed
    12091211                        // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound
     
    12111213                        // therefore, are removed from the grammar even though C allows it. The change also applies to choose
    12121214                        // statement.
    1213                         $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
     1215                        $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    12141216                }
    12151217        | SWITCH '(' comma_expression ')' '{' error '}'         // CFA, syntax error
    12161218                { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; }
    12171219        | CHOOSE '(' comma_expression ')' case_clause           // CFA
    1218                 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }
     1220                { $$ = new StatementNode( build_switch( yylloc, false, $3, $5 ) ); }
    12191221        | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA
    12201222                {
    1221                         StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) );
    1222                         $$ = $7 ? new StatementNode( build_compound( (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
     1223                        StatementNode *sw = new StatementNode( build_switch( yylloc, false, $3, $8 ) );
     1224                        $$ = $7 ? new StatementNode( build_compound( yylloc, (StatementNode *)((new StatementNode( $7 ))->set_last( sw )) ) ) : sw;
    12231225                }
    12241226        | CHOOSE '(' comma_expression ')' '{' error '}'         // CFA, syntax error
     
    12291231        IF '(' conditional_declaration ')' statement            %prec THEN
    12301232                // explicitly deal with the shift/reduce conflict on if/else
    1231                 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), nullptr ) ); }
     1233                { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), nullptr ) ); }
    12321234        | IF '(' conditional_declaration ')' statement ELSE statement
    1233                 { $$ = new StatementNode( build_if( $3, maybe_build_compound( $5 ), maybe_build_compound( $7 ) ) ); }
     1235                { $$ = new StatementNode( build_if( yylloc, $3, maybe_build_compound( yylloc, $5 ), maybe_build_compound( yylloc, $7 ) ) ); }
    12341236        ;
    12351237
     
    12511253        constant_expression                                                     { $$ = $1; }
    12521254        | constant_expression ELLIPSIS constant_expression      // GCC, subrange
    1253                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     1255                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    12541256        | subrange                                                                                      // CFA, subrange
    12551257        ;
     
    12671269        | CASE case_value_list error                                            // syntax error
    12681270                { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; }
    1269         | DEFAULT ':'                                                           { $$ = new StatementNode( build_default() ); }
     1271        | DEFAULT ':'                                                           { $$ = new StatementNode( build_default( yylloc ) ); }
    12701272                // A semantic check is required to ensure only one default clause per switch/choose statement.
    12711273        | DEFAULT error                                                                         //  syntax error
     
    12791281
    12801282case_clause:                                                                                    // CFA
    1281         case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( $2 ) ); }
     1283        case_label_list statement                                       { $$ = $1->append_last_case( maybe_build_compound( yylloc, $2 ) ); }
    12821284        ;
    12831285
     
    12901292switch_clause_list:                                                                             // CFA
    12911293        case_label_list statement_list_nodecl
    1292                 { $$ = $1->append_last_case( new StatementNode( build_compound( $2 ) ) ); }
     1294                { $$ = $1->append_last_case( new StatementNode( build_compound( yylloc, $2 ) ) ); }
    12931295        | switch_clause_list case_label_list statement_list_nodecl
    1294                 { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( $3 ) ) ) ) ); }
     1296                { $$ = (StatementNode *)( $1->set_last( $2->append_last_case( new StatementNode( build_compound( yylloc, $3 ) ) ) ) ); }
    12951297        ;
    12961298
    12971299iteration_statement:
    12981300        WHILE '(' ')' statement                                                         %prec THEN // CFA => while ( 1 )
    1299                 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); }
     1301                { $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) ); }
    13001302        | WHILE '(' ')' statement ELSE statement                        // CFA
    13011303                {
    1302                         $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) );
     1304                        $$ = new StatementNode( build_while( yylloc, new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( yylloc, $4 ) ) );
    13031305                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    13041306                }
    13051307        | WHILE '(' conditional_declaration ')' statement       %prec THEN
    1306                 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ) ) ); }
     1308                { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    13071309        | WHILE '(' conditional_declaration ')' statement ELSE statement // CFA
    1308                 { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
     1310                { $$ = new StatementNode( build_while( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
    13091311        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    1310                 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); }
     1312                { $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) ); }
    13111313        | DO statement WHILE '(' ')' ELSE statement                     // CFA
    13121314                {
    1313                         $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) );
     1315                        $$ = new StatementNode( build_do_while( yylloc, NEW_ONE, maybe_build_compound( yylloc, $2 ) ) );
    13141316                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    13151317                }
    13161318        | DO statement WHILE '(' comma_expression ')' ';'
    1317                 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ) ) ); }
     1319                { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ) ) ); }
    13181320        | DO statement WHILE '(' comma_expression ')' ELSE statement // CFA
    1319                 { $$ = new StatementNode( build_do_while( $5, maybe_build_compound( $2 ), $8 ) ); }
     1321                { $$ = new StatementNode( build_do_while( yylloc, $5, maybe_build_compound( yylloc, $2 ), $8 ) ); }
    13201322        | FOR '(' ')' statement                                                         %prec THEN // CFA => for ( ;; )
    1321                 { $$ = new StatementNode( build_for( new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( $4 ) ) ); }
     1323                { $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) ); }
    13221324        | FOR '(' ')' statement ELSE statement                          // CFA
    13231325                {
    1324                         $$ = new StatementNode( build_for( new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( $4 ) ) );
     1326                        $$ = new StatementNode( build_for( yylloc, new ForCtrl( nullptr, nullptr, nullptr ), maybe_build_compound( yylloc, $4 ) ) );
    13251327                        SemanticWarning( yylloc, Warning::SuperfluousElse );
    13261328                }
    13271329        | FOR '(' for_control_expression_list ')' statement     %prec THEN
    1328                 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ) ) ); }
     1330                { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    13291331        | FOR '(' for_control_expression_list ')' statement ELSE statement // CFA
    1330                 { $$ = new StatementNode( build_for( $3, maybe_build_compound( $5 ), $7 ) ); }
     1332                { $$ = new StatementNode( build_for( yylloc, $3, maybe_build_compound( yylloc, $5 ), $7 ) ); }
    13311333        ;
    13321334
     
    13421344                        if ( $1->condition ) {
    13431345                                if ( $3->condition ) {
    1344                                         $1->condition->expr.reset( new LogicalExpr( $1->condition->expr.release(), $3->condition->expr.release(), true ) );
     1346                                        $1->condition->expr.reset( new ast::LogicalExpr( yylloc, $1->condition->expr.release(), $3->condition->expr.release(), ast::AndExpr ) );
    13451347                                } // if
    13461348                        } else $1->condition = $3->condition;
    13471349                        if ( $1->change ) {
    13481350                                if ( $3->change ) {
    1349                                         $1->change->expr.reset( new CommaExpr( $1->change->expr.release(), $3->change->expr.release() ) );
     1351                                        $1->change->expr.reset( new ast::CommaExpr( yylloc, $1->change->expr.release(), $3->change->expr.release() ) );
    13501352                                } // if
    13511353                        } else $1->change = $3->change;
     
    13591361        | comma_expression ';' comma_expression_opt ';' comma_expression_opt
    13601362                {
    1361                         StatementNode * init = $1 ? new StatementNode( new ExprStmt( maybeMoveBuild( $1 ) ) ) : nullptr;
     1363                        StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr;
    13621364                        $$ = new ForCtrl( init, $3, $5 );
    13631365                }
     
    13711373
    13721374        | comma_expression                                                                      // CFA, anonymous loop-index
    1373                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
     1375                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
    13741376        | downupdowneq comma_expression                                         // CFA, anonymous loop-index
    1375                 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
     1377                { $$ = forCtrl( yylloc, $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
    13761378
    13771379        | comma_expression updowneq comma_expression            // CFA, anonymous loop-index
    1378                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
     1380                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
    13791381        | '@' updowneq comma_expression                                         // CFA, anonymous loop-index
    13801382                {
    13811383                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1382                         else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
     1384                        else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
    13831385                }
    13841386        | comma_expression updowneq '@'                                         // CFA, anonymous loop-index
     
    13881390                }
    13891391        | comma_expression updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    1390                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
     1392                { $$ = forCtrl( yylloc, $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
    13911393        | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index
    13921394                {
    13931395                        if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1394                         else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
     1396                        else $$ = forCtrl( yylloc, $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
    13951397                }
    13961398        | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index
     
    14111413
    14121414        | comma_expression ';' comma_expression                         // CFA
    1413                 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
     1415                { $$ = forCtrl( yylloc, $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
    14141416        | comma_expression ';' downupdowneq comma_expression // CFA
    1415                 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
     1417                { $$ = forCtrl( yylloc, $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
    14161418
    14171419        | comma_expression ';' comma_expression updowneq comma_expression // CFA
    1418                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
     1420                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
    14191421        | comma_expression ';' '@' updowneq comma_expression // CFA
    14201422                {
    14211423                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1422                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
     1424                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
    14231425                }
    14241426        | comma_expression ';' comma_expression updowneq '@' // CFA
     
    14261428                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14271429                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1428                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
     1430                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
    14291431                }
    14301432        | comma_expression ';' '@' updowneq '@'                         // CFA, error
     
    14321434
    14331435        | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
    1434                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
     1436                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
    14351437        | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error
    14361438                {
    14371439                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1438                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );
     1440                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, $7 );
    14391441                }
    14401442        | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA
     
    14421444                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14431445                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1444                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 );
     1446                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, $7 );
    14451447                }
    14461448        | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA
    1447                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
     1449                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
    14481450        | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error
    14491451                {
    14501452                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1451                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );
     1453                        else $$ = forCtrl( yylloc, $5, $1, $5->clone(), $4, nullptr, nullptr );
    14521454                }
    14531455        | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA
     
    14551457                        if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14561458                        else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1457                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr );
     1459                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, nullptr );
    14581460                }
    14591461        | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
     
    14611463
    14621464        | declaration comma_expression                                          // CFA
    1463                 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
     1465                { $$ = forCtrl( yylloc, $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
    14641466        | declaration downupdowneq comma_expression                     // CFA
    1465                 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
     1467                { $$ = forCtrl( yylloc, $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
    14661468
    14671469        | declaration comma_expression updowneq comma_expression // CFA
    1468                 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
     1470                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
    14691471        | declaration '@' updowneq comma_expression                     // CFA
    14701472                {
    14711473                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1472                         else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );
     1474                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, NEW_ONE );
    14731475                }
    14741476        | declaration comma_expression updowneq '@'                     // CFA
     
    14761478                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14771479                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1478                         else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE );
     1480                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, NEW_ONE );
    14791481                }
    14801482
    14811483        | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA
    1482                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
     1484                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
    14831485        | declaration '@' updowneq comma_expression '~' comma_expression // CFA
    14841486                {
    14851487                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1486                         else $$ = forCtrl( $1, $4, $3, nullptr, $6 );
     1488                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, $6 );
    14871489                }
    14881490        | declaration comma_expression updowneq '@' '~' comma_expression // CFA
     
    14901492                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14911493                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1492                         else $$ = forCtrl( $1, $2, $3, nullptr, $6 );
     1494                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, $6 );
    14931495                }
    14941496        | declaration comma_expression updowneq comma_expression '~' '@' // CFA
    1495                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
     1497                { $$ = forCtrl( yylloc, $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
    14961498        | declaration '@' updowneq comma_expression '~' '@' // CFA
    14971499                {
    14981500                        if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
    1499                         else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );
     1501                        else $$ = forCtrl( yylloc, $1, $4, $3, nullptr, nullptr );
    15001502                }
    15011503        | declaration comma_expression updowneq '@' '~' '@'     // CFA
     
    15031505                        if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    15041506                        else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing high value is meaningless. Use \"~\"." ); $$ = nullptr; }
    1505                         else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );
     1507                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, nullptr );
    15061508                }
    15071509        | declaration '@' updowneq '@' '~' '@'                          // CFA, error
     
    15461548jump_statement:
    15471549        GOTO identifier_or_type_name ';'
    1548                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Goto ) ); }
     1550                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); }
    15491551        | GOTO '*' comma_expression ';'                                         // GCC, computed goto
    15501552                // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3);
     
    15531555                // A semantic check is required to ensure fallthru appears only in the body of a choose statement.
    15541556        | fall_through_name ';'                                                         // CFA
    1555                 { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); }
     1557                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); }
    15561558        | fall_through_name identifier_or_type_name ';'         // CFA
    1557                 { $$ = new StatementNode( build_branch( $2, BranchStmt::FallThrough ) ); }
     1559                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::FallThrough ) ); }
    15581560        | fall_through_name DEFAULT ';'                                         // CFA
    1559                 { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); }
     1561                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); }
    15601562        | CONTINUE ';'
    15611563                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    1562                 { $$ = new StatementNode( build_branch( BranchStmt::Continue ) ); }
     1564                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Continue ) ); }
    15631565        | CONTINUE identifier_or_type_name ';'                          // CFA, multi-level continue
    15641566                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15651567                // the target of the transfer appears only at the start of an iteration statement.
    1566                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Continue ) ); }
     1568                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Continue ) ); }
    15671569        | BREAK ';'
    15681570                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    1569                 { $$ = new StatementNode( build_branch( BranchStmt::Break ) ); }
     1571                { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::Break ) ); }
    15701572        | BREAK identifier_or_type_name ';'                                     // CFA, multi-level exit
    15711573                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    15721574                // the target of the transfer appears only at the start of an iteration statement.
    1573                 { $$ = new StatementNode( build_branch( $2, BranchStmt::Break ) ); }
     1575                { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Break ) ); }
    15741576        | RETURN comma_expression_opt ';'
    1575                 { $$ = new StatementNode( build_return( $2 ) ); }
     1577                { $$ = new StatementNode( build_return( yylloc, $2 ) ); }
    15761578        | RETURN '{' initializer_list_opt comma_opt '}' ';'
    15771579                { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; }
    15781580        | SUSPEND ';'
    1579                 { $$ = new StatementNode( build_suspend( nullptr ) ); }
     1581                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None ) ); }
    15801582        | SUSPEND compound_statement
    1581                 { $$ = new StatementNode( build_suspend( $2 ) ); }
     1583                { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None ) ); }
    15821584        | SUSPEND COROUTINE ';'
    1583                 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Coroutine ) ); }
     1585                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); }
    15841586        | SUSPEND COROUTINE compound_statement
    1585                 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Coroutine ) ); }
     1587                { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); }
    15861588        | SUSPEND GENERATOR ';'
    1587                 { $$ = new StatementNode( build_suspend( nullptr, SuspendStmt::Generator ) ); }
     1589                { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); }
    15881590        | SUSPEND GENERATOR compound_statement
    1589                 { $$ = new StatementNode( build_suspend( $3, SuspendStmt::Generator ) ); }
     1591                { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); }
    15901592        | THROW assignment_expression_opt ';'                           // handles rethrow
    1591                 { $$ = new StatementNode( build_throw( $2 ) ); }
     1593                { $$ = new StatementNode( build_throw( yylloc, $2 ) ); }
    15921594        | THROWRESUME assignment_expression_opt ';'                     // handles reresume
    1593                 { $$ = new StatementNode( build_resume( $2 ) ); }
     1595                { $$ = new StatementNode( build_resume( yylloc, $2 ) ); }
    15941596        | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume
    15951597                { $$ = new StatementNode( build_resume_at( $2, $4 ) ); }
     
    16031605with_statement:
    16041606        WITH '(' tuple_expression_list ')' statement
    1605                 { $$ = new StatementNode( build_with( $3, $5 ) ); }
     1607                { $$ = new StatementNode( build_with( yylloc, $3, $5 ) ); }
    16061608        ;
    16071609
     
    16111613                {
    16121614                        if ( ! $3 ) { SemanticError( yylloc, "mutex argument list cannot be empty." ); $$ = nullptr; }
    1613                         $$ = new StatementNode( build_mutex( $3, $5 ) );
     1615                        $$ = new StatementNode( build_mutex( yylloc, $3, $5 ) );
    16141616                }
    16151617        ;
     
    16501652        when_clause_opt waitfor statement                                       %prec THEN
    16511653                // Called first: create header for WaitForStmt.
    1652                 { $$ = build_waitfor( new WaitForStmt(), $1, $2, maybe_build_compound( $3 ) ); }
     1654                { $$ = build_waitfor( yylloc, new ast::WaitForStmt( yylloc ), $1, $2, maybe_build_compound( yylloc, $3 ) ); }
    16531655        | wor_waitfor_clause wor when_clause_opt waitfor statement
    1654                 { $$ = build_waitfor( $1, $3, $4, maybe_build_compound( $5 ) ); }
     1656                { $$ = build_waitfor( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); }
    16551657        | wor_waitfor_clause wor when_clause_opt ELSE statement
    1656                 { $$ = build_waitfor_else( $1, $3, maybe_build_compound( $5 ) ); }
     1658                { $$ = build_waitfor_else( yylloc, $1, $3, maybe_build_compound( yylloc, $5 ) ); }
    16571659        | wor_waitfor_clause wor when_clause_opt timeout statement      %prec THEN
    1658                 { $$ = build_waitfor_timeout( $1, $3, $4, maybe_build_compound( $5 ) ); }
     1660                { $$ = build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); }
    16591661        // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
    16601662        | wor_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error
    16611663                { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    16621664        | wor_waitfor_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
    1663                 { $$ = build_waitfor_else( build_waitfor_timeout( $1, $3, $4, maybe_build_compound( $5 ) ), $7, maybe_build_compound( $9 ) ); }
     1665                { $$ = build_waitfor_else( yylloc, build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ), $7, maybe_build_compound( yylloc, $9 ) ); }
     1666        ;
    16641667
    16651668waitfor_statement:
     
    17111714        wor_waituntil_clause                                                            %prec THEN
    17121715                // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement.
    1713                 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }
     1716                { $$ = new StatementNode( build_compound( yylloc, nullptr ) ); }
    17141717        ;
    17151718
    17161719exception_statement:
    1717         TRY compound_statement handler_clause                           %prec THEN
    1718                 { $$ = new StatementNode( build_try( $2, $3, nullptr ) ); }
     1720        TRY compound_statement handler_clause                                   %prec THEN
     1721                { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr ) ); }
    17191722        | TRY compound_statement finally_clause
    1720                 { $$ = new StatementNode( build_try( $2, nullptr, $3 ) ); }
     1723                { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); }
    17211724        | TRY compound_statement handler_clause finally_clause
    1722                 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }
     1725                { $$ = new StatementNode( build_try( yylloc, $2, $3, $4 ) ); }
    17231726        ;
    17241727
    17251728handler_clause:
    17261729        handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1727                 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }
     1730                { $$ = new StatementNode( build_catch( yylloc, $1, $4, $6, $8 ) ); }
    17281731        | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement
    1729                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); }
     1732                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( yylloc, $2, $5, $7, $9 ) ) ); }
    17301733        ;
    17311734
     
    17371740
    17381741handler_key:
    1739         CATCH                                                                           { $$ = CatchStmt::Terminate; }
    1740         | RECOVER                                                                       { $$ = CatchStmt::Terminate; }
    1741         | CATCHRESUME                                                           { $$ = CatchStmt::Resume; }
    1742         | FIXUP                                                                         { $$ = CatchStmt::Resume; }
     1742        CATCH                                                                           { $$ = ast::Terminate; }
     1743        | RECOVER                                                                       { $$ = ast::Terminate; }
     1744        | CATCHRESUME                                                           { $$ = ast::Resume; }
     1745        | FIXUP                                                                         { $$ = ast::Resume; }
    17431746        ;
    17441747
    17451748finally_clause:
    1746         FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( $2 ) ); }
     1749        FINALLY compound_statement                                      { $$ = new StatementNode( build_finally( yylloc, $2 ) ); }
    17471750        ;
    17481751
     
    17701773asm_statement:
    17711774        ASM asm_volatile_opt '(' string_literal ')' ';'
    1772                 { $$ = new StatementNode( build_asm( $2, $4, nullptr ) ); }
     1775                { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr ) ); }
    17731776        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ')' ';' // remaining GCC
    1774                 { $$ = new StatementNode( build_asm( $2, $4, $6 ) ); }
     1777                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6 ) ); }
    17751778        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ')' ';'
    1776                 { $$ = new StatementNode( build_asm( $2, $4, $6, $8 ) ); }
     1779                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8 ) ); }
    17771780        | ASM asm_volatile_opt '(' string_literal ':' asm_operands_opt ':' asm_operands_opt ':' asm_clobbers_list_opt ')' ';'
    1778                 { $$ = new StatementNode( build_asm( $2, $4, $6, $8, $10 ) ); }
     1781                { $$ = new StatementNode( build_asm( yylloc, $2, $4, $6, $8, $10 ) ); }
    17791782        | ASM asm_volatile_opt GOTO '(' string_literal ':' ':' asm_operands_opt ':' asm_clobbers_list_opt ':' label_list ')' ';'
    1780                 { $$ = new StatementNode( build_asm( $2, $5, nullptr, $8, $10, $12 ) ); }
     1783                { $$ = new StatementNode( build_asm( yylloc, $2, $5, nullptr, $8, $10, $12 ) ); }
    17811784        ;
    17821785
     
    18021805asm_operand:                                                                                    // GCC
    18031806        string_literal '(' constant_expression ')'
    1804                 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild( $3 ) ) ); }
     1807                { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", $1, maybeMoveBuild( $3 ) ) ); }
    18051808        | '[' IDENTIFIER ']' string_literal '(' constant_expression ')'
    1806                 { $$ = new ExpressionNode( new AsmExpr( $2, $4, maybeMoveBuild( $6 ) ) ); }
     1809                {
     1810                        $$ = new ExpressionNode( new ast::AsmExpr( yylloc, *$2.str, $4, maybeMoveBuild( $6 ) ) );
     1811                        delete $2.str;
     1812                }
    18071813        ;
    18081814
     
    18191825        identifier
    18201826                {
    1821                         $$ = new LabelNode(); $$->labels.push_back( *$1 );
     1827                        $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 );
    18221828                        delete $1;                                                                      // allocated by lexer
    18231829                }
    18241830        | label_list ',' identifier
    18251831                {
    1826                         $$ = $1; $1->labels.push_back( *$3 );
     1832                        $$ = $1; $1->labels.emplace_back( yylloc, *$3 );
    18271833                        delete $3;                                                                      // allocated by lexer
    18281834                }
     
    18871893                { $$ = DeclarationNode::newStaticAssert( $3, $5 ); }
    18881894        | STATICASSERT '(' constant_expression ')' ';'          // CFA
    1889                 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }
     1895                { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); }
    18901896
    18911897// C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function
     
    20872093                {
    20882094                        SemanticError( yylloc, ::toString( "Missing ';' after end of ",
    2089                                 $1->type->enumeration.name ? "enum" : AggregateDecl::aggrString( $1->type->aggregate.kind ),
     2095                                $1->type->enumeration.name ? "enum" : ast::AggregateDecl::aggrString( $1->type->aggregate.kind ),
    20902096                                " declaration" ) );
    20912097                        $$ = nullptr;
     
    23212327                { $$ = DeclarationNode::newTypeof( $3 ); }
    23222328        | BASETYPEOF '(' type ')'                                                       // CFA: basetypeof( x ) y;
    2323                 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); }
     2329                { $$ = DeclarationNode::newTypeof( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ), true ); }
    23242330        | BASETYPEOF '(' comma_expression ')'                           // CFA: basetypeof( a+b ) y;
    23252331                { $$ = DeclarationNode::newTypeof( $3, true ); }
     
    25152521aggregate_data:
    25162522        STRUCT vtable_opt
    2517                 { $$ = AggregateDecl::Struct; }
     2523                { $$ = ast::AggregateDecl::Struct; }
    25182524        | UNION
    2519                 { $$ = AggregateDecl::Union; }
     2525                { $$ = ast::AggregateDecl::Union; }
    25202526        | EXCEPTION                                                                                     // CFA
    2521                 { $$ = AggregateDecl::Exception; }
    2522           //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2527                { $$ = ast::AggregateDecl::Exception; }
     2528          //            { SemanticError( yylloc, "exception aggregate is currently unimplemented." ); $$ = ast::AggregateDecl::NoAggregate; }
    25232529        ;
    25242530
    25252531aggregate_control:                                                                              // CFA
    25262532        MONITOR
    2527                 { $$ = AggregateDecl::Monitor; }
     2533                { $$ = ast::AggregateDecl::Monitor; }
    25282534        | MUTEX STRUCT
    2529                 { $$ = AggregateDecl::Monitor; }
     2535                { $$ = ast::AggregateDecl::Monitor; }
    25302536        | GENERATOR
    2531                 { $$ = AggregateDecl::Generator; }
     2537                { $$ = ast::AggregateDecl::Generator; }
    25322538        | MUTEX GENERATOR
    2533                 { SemanticError( yylloc, "monitor generator is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2539                {
     2540                        SemanticError( yylloc, "monitor generator is currently unimplemented." );
     2541                        $$ = ast::AggregateDecl::NoAggregate;
     2542                }
    25342543        | COROUTINE
    2535                 { $$ = AggregateDecl::Coroutine; }
     2544                { $$ = ast::AggregateDecl::Coroutine; }
    25362545        | MUTEX COROUTINE
    2537                 { SemanticError( yylloc, "monitor coroutine is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2546                {
     2547                        SemanticError( yylloc, "monitor coroutine is currently unimplemented." );
     2548                        $$ = ast::AggregateDecl::NoAggregate;
     2549                }
    25382550        | THREAD
    2539                 { $$ = AggregateDecl::Thread; }
     2551                { $$ = ast::AggregateDecl::Thread; }
    25402552        | MUTEX THREAD
    2541                 { SemanticError( yylloc, "monitor thread is currently unimplemented." ); $$ = AggregateDecl::NoAggregate; }
     2553                {
     2554                        SemanticError( yylloc, "monitor thread is currently unimplemented." );
     2555                        $$ = ast::AggregateDecl::NoAggregate;
     2556                }
    25422557        ;
    25432558
     
    28892904        designator_list ':'                                                                     // C99, CFA uses ":" instead of "="
    28902905        | identifier_at ':'                                                                     // GCC, field name
    2891                 { $$ = new ExpressionNode( build_varref( $1 ) ); }
     2906                { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); }
    28922907        ;
    28932908
     
    29012916designator:
    29022917        '.' identifier_at                                                                       // C99, field name
    2903                 { $$ = new ExpressionNode( build_varref( $2 ) ); }
     2918                { $$ = new ExpressionNode( build_varref( yylloc, $2 ) ); }
    29042919        | '[' push assignment_expression pop ']'                        // C99, single array element
    29052920                // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple.
     
    29082923                { $$ = $3; }
    29092924        | '[' push constant_expression ELLIPSIS constant_expression pop ']' // GCC, multiple array elements
    2910                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }
     2925                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $3 ), maybeMoveBuild( $5 ) ) ); }
    29112926        | '.' '[' push field_name_list pop ']'                          // CFA, tuple field selector
    29122927                { $$ = $4; }
     
    29482963                {
    29492964                        typedefTable.addToScope( *$2, TYPEDEFname, "9" );
    2950                         if ( $1 == TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
    2951                         if ( $1 == TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
    2952                         if ( $1 == TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
     2965                        if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
     2966                        if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
     2967                        if ( $1 == ast::TypeDecl::Ttype ) { SemanticError( yylloc, "ttype keyword is deprecated, use T ..." ); }
    29532968                }
    29542969          type_initializer_opt assertion_list_opt
     
    29612976                {
    29622977                        typedefTable.addToScope( *$2, TYPEDIMname, "9" );
    2963                         $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 );
     2978                        $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );
    29642979                }
    29652980        // | type_specifier identifier_parameter_declarator
    29662981        | assertion_list
    2967                 { $$ = DeclarationNode::newTypeParam( TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
     2982                { $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dtype, new string( DeclarationNode::anonymous.newName() ) )->addAssertions( $1 ); }
    29682983        ;
    29692984
    29702985new_type_class:                                                                                 // CFA
    29712986        // empty
    2972                 { $$ = TypeDecl::Otype; }
     2987                { $$ = ast::TypeDecl::Otype; }
    29732988        | '&'
    2974                 { $$ = TypeDecl::Dtype; }
     2989                { $$ = ast::TypeDecl::Dtype; }
    29752990        | '*'
    2976                 { $$ = TypeDecl::DStype; }                                              // dtype + sized
     2991                { $$ = ast::TypeDecl::DStype; }                                         // dtype + sized
    29772992        // | '(' '*' ')'
    2978         //      { $$ = TypeDecl::Ftype; }
     2993        //      { $$ = ast::TypeDecl::Ftype; }
    29792994        | ELLIPSIS
    2980                 { $$ = TypeDecl::Ttype; }
     2995                { $$ = ast::TypeDecl::Ttype; }
    29812996        ;
    29822997
    29832998type_class:                                                                                             // CFA
    29842999        OTYPE
    2985                 { $$ = TypeDecl::Otype; }
     3000                { $$ = ast::TypeDecl::Otype; }
    29863001        | DTYPE
    2987                 { $$ = TypeDecl::Dtype; }
     3002                { $$ = ast::TypeDecl::Dtype; }
    29883003        | FTYPE
    2989                 { $$ = TypeDecl::Ftype; }
     3004                { $$ = ast::TypeDecl::Ftype; }
    29903005        | TTYPE
    2991                 { $$ = TypeDecl::Ttype; }
     3006                { $$ = ast::TypeDecl::Ttype; }
    29923007        ;
    29933008
     
    30153030type_list:                                                                                              // CFA
    30163031        type
    3017                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3032                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    30183033        | assignment_expression
    30193034        | type_list ',' type
    3020                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3035                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    30213036        | type_list ',' assignment_expression
    30223037                { $$ = (ExpressionNode *)( $1->set_last( $3 )); }
     
    31253140external_definition:
    31263141        DIRECTIVE
    3127                 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }
     3142                { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc, $1 ) ) ); }
    31283143        | declaration
    31293144                {
     
    31313146                        // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is
    31323147                        // disallowed at the moment.
    3133                         if ( $1->linkage == LinkageSpec::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {
     3148                        if ( $1->linkage == ast::Linkage::Cforall && ! $1->storageClasses.is_static && $1->type && $1->type->kind == TypeData::AggregateInst ) {
    31343149                                if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) {
    31353150                                        SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr;
     
    31583173                }
    31593174        | ASM '(' string_literal ')' ';'                                        // GCC, global assembler statement
    3160                 { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( false, $3, nullptr ) ) ); }
     3175                { $$ = DeclarationNode::newAsmStmt( new StatementNode( build_asm( yylloc, false, $3, nullptr ) ) ); }
    31613176        | EXTERN STRINGliteral
    31623177                {
    31633178                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3164                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
     3179                        linkage = ast::Linkage::update( yylloc, linkage, $2 );
    31653180                }
    31663181          up external_definition down
     
    31733188                {
    31743189                        linkageStack.push( linkage );                           // handle nested extern "C"/"Cforall"
    3175                         linkage = LinkageSpec::update( yylloc, linkage, $2 );
     3190                        linkage = ast::Linkage::update( yylloc, linkage, $2 );
    31763191                }
    31773192          '{' up external_definition_list_opt down '}'
     
    32973312subrange:
    32983313        constant_expression '~' constant_expression                     // CFA, integer subrange
    3299                 { $$ = new ExpressionNode( new RangeExpr( maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
     3314                { $$ = new ExpressionNode( new ast::RangeExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }
    33003315        ;
    33013316
     
    38263841array_type_list:
    38273842        basic_type_name
    3828                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3843                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    38293844        | type_name
    3830                 { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( $1 ) ) ); }
     3845                { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); }
    38313846        | assignment_expression upupeq assignment_expression
    38323847        | array_type_list ',' basic_type_name
    3833                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
    3834         | array_type_list ',' type_name 
    3835                 { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ) )); }
     3848                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
     3849        | array_type_list ',' type_name
     3850                { $$ = (ExpressionNode *)($1->set_last( new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $3 ) ) ) )); }
    38363851        | array_type_list ',' assignment_expression upupeq assignment_expression
    38373852        ;
  • src/Parser/parserutility.cc

    rff71057 re02e13f  
    1010// Created On       : Sat May 16 15:30:39 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tus Jul 18 10:12:00 2017
    13 // Update Count     : 8
     12// Last Modified On : Wed Mar  1 10:42:00 2023
     13// Update Count     : 9
    1414//
    1515
     
    1919#include <string>                // for string
    2020
    21 #include "SynTree/Constant.h"    // for Constant
    22 #include "SynTree/Expression.h"  // for UntypedExpr, CastExpr, ConstantExpr
    23 #include "SynTree/Type.h"        // for BasicType, ZeroType, BasicType::Kind...
     21#include "AST/Expr.hpp"          // for UntypedExpr, CastExpr, ConstantExpr
     22#include "AST/Type.hpp"          // for BasicType, ZeroType, BasicType::Kind...
    2423
    2524// rewrite
     
    2827//    if ( (int)(x != 0) ) ...
    2928
    30 Expression *notZeroExpr( Expression *orig ) {
    31         if( !orig ) return nullptr;
    32         UntypedExpr *comparison = new UntypedExpr( new NameExpr( "?!=?" ) );
    33         comparison->get_args().push_back( orig );
    34         comparison->get_args().push_back( new ConstantExpr( Constant( new ZeroType( noQualifiers ), "0", (unsigned long long int)0 ) ) );
    35         return new CastExpr( comparison, new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     29ast::Expr * notZeroExpr( ast::Expr * orig ) {
     30        return ( !orig ) ? nullptr : new ast::CastExpr( orig->location,
     31                ast::UntypedExpr::createCall( orig->location,
     32                        "?!=?",
     33                        {
     34                                orig,
     35                                new ast::ConstantExpr( orig->location,
     36                                        new ast::ZeroType(),
     37                                        "0",
     38                                        std::optional<unsigned long long>( 0 )
     39                                ),
     40                        }
     41                ),
     42                new ast::BasicType( ast::BasicType::SignedInt )
     43        );
    3644}
    3745
  • src/Parser/parserutility.h

    rff71057 re02e13f  
    1010// Created On       : Sat May 16 15:31:46 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Thr Mar  9 12:16:00 2023
    13 // Update Count     : 6
     12// Last Modified On : Tue Apr  4 14:03:00 2023
     13// Update Count     : 7
    1414//
    1515
    1616#pragma once
    1717
    18 class Expression;
     18#include "AST/Copy.hpp"            // for shallowCopy
     19namespace ast {
     20        class Expr;
     21}
    1922
    20 Expression *notZeroExpr( Expression *orig );
     23ast::Expr * notZeroExpr( ast::Expr *orig );
    2124
    2225template< typename T >
     
    3235}
    3336
     37template<typename node_t>
     38node_t * maybeCopy( node_t const * node ) {
     39        return node ? ast::shallowCopy( node ) : nullptr;
     40}
     41
    3442// Local Variables: //
    3543// tab-width: 4 //
  • tests/.expect/attributes.arm64.txt

    rff71057 re02e13f  
    13511351signed int _X4apd5Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object12)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object13)(signed int __param_0));
    13521352signed int _X4apd6Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object14)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object15)());
    1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(signed int __param_0));
     1353signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(__attribute__ ((unused)) signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(__attribute__ ((unused)) signed int __param_0));
    13541354struct Vad {
    13551355    __attribute__ ((unused)) signed int :4;
  • tests/.expect/attributes.x64.txt

    rff71057 re02e13f  
    13511351signed int _X4apd5Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object12)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object13)(signed int __param_0));
    13521352signed int _X4apd6Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object14)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object15)());
    1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(signed int __param_0));
     1353signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(__attribute__ ((unused)) signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(__attribute__ ((unused)) signed int __param_0));
    13541354struct Vad {
    13551355    __attribute__ ((unused)) signed int :4;
  • tests/.expect/attributes.x86.txt

    rff71057 re02e13f  
    13511351signed int _X4apd5Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object12)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object13)(signed int __param_0));
    13521352signed int _X4apd6Fi_Fi__Fi____1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object14)(), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object15)());
    1353 signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(signed int __param_0));
     1353signed int _X4apd7Fi_Fi_i_Fi_i___1(__attribute__ ((unused,unused,unused)) signed int (*__anonymous_object16)(__attribute__ ((unused)) signed int __param_0), __attribute__ ((unused,unused,unused)) signed int (*__anonymous_object17)(__attribute__ ((unused)) signed int __param_0));
    13541354struct Vad {
    13551355    __attribute__ ((unused)) signed int :4;
  • tests/errors/.expect/declaration.txt

    rff71057 re02e13f  
    1 errors/declaration.cfa:16:1 error: duplicate static in declaration of x1: static const volatile short int
     1errors/declaration.cfa:16:1 error: duplicate static storage class(es) in declaration of x1: static const volatile short int
    22
    3 errors/declaration.cfa:17:1 error: conflicting extern & static in declaration of x2: extern const volatile short int
     3errors/declaration.cfa:17:1 error: conflicting extern & static storage classes in declaration of x2: extern const volatile short int
    44
    5 errors/declaration.cfa:18:1 error: conflicting extern & auto, conflicting extern & static, conflicting extern & static, duplicate extern in declaration of x3: extern const volatile short int
     5errors/declaration.cfa:18:1 error: conflicting extern & auto storage classes, conflicting extern & static storage classes, conflicting extern & static storage classes, duplicate extern storage class(es) in declaration of x3: extern const volatile short int
    66
    7 errors/declaration.cfa:19:1 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous0
     7errors/declaration.cfa:19:1 error: duplicate static storage class(es) in declaration of x4: static const volatile instance of const volatile struct __anonymous0
    88  with members
    99    i: int
     
    1111
    1212
    13 errors/declaration.cfa:20:1 error: duplicate const, duplicate static, duplicate volatile in declaration of x5: static const volatile instance of const volatile struct __anonymous1
     13errors/declaration.cfa:20:1 error: duplicate const qualifier(s), duplicate static storage class(es), duplicate volatile qualifier(s) in declaration of x5: static const volatile instance of const volatile struct __anonymous1
    1414  with members
    1515    i: int
     
    1717
    1818
    19 errors/declaration.cfa:22:1 error: duplicate static in declaration of x6: static const volatile Int
     19errors/declaration.cfa:22:1 error: duplicate static storage class(es) in declaration of x6: static const volatile Int
    2020
    21 errors/declaration.cfa:24:1 error: duplicate const in declaration of f01: static inline function
     21errors/declaration.cfa:24:1 error: duplicate const qualifier(s) in declaration of f01: static inline function
    2222  with no parameters
    2323  returning const volatile int
    2424
    2525
    26 errors/declaration.cfa:25:1 error: duplicate volatile in declaration of f02: static inline function
     26errors/declaration.cfa:25:1 error: duplicate volatile qualifier(s) in declaration of f02: static inline function
    2727  with no parameters
    2828  returning const volatile int
    2929
    3030
    31 errors/declaration.cfa:26:1 error: duplicate const in declaration of f03: static inline function
     31errors/declaration.cfa:26:1 error: duplicate const qualifier(s) in declaration of f03: static inline function
    3232  with no parameters
    3333  returning const volatile int
    3434
    3535
    36 errors/declaration.cfa:27:1 error: duplicate volatile in declaration of f04: static inline function
     36errors/declaration.cfa:27:1 error: duplicate volatile qualifier(s) in declaration of f04: static inline function
    3737  with no parameters
    3838  returning const volatile int
    3939
    4040
    41 errors/declaration.cfa:28:1 error: duplicate const in declaration of f05: static inline function
     41errors/declaration.cfa:28:1 error: duplicate const qualifier(s) in declaration of f05: static inline function
    4242  with no parameters
    4343  returning const volatile int
    4444
    4545
    46 errors/declaration.cfa:29:1 error: duplicate volatile in declaration of f06: static inline function
     46errors/declaration.cfa:29:1 error: duplicate volatile qualifier(s) in declaration of f06: static inline function
    4747  with no parameters
    4848  returning const volatile int
    4949
    5050
    51 errors/declaration.cfa:30:1 error: duplicate const in declaration of f07: static inline function
     51errors/declaration.cfa:30:1 error: duplicate const qualifier(s) in declaration of f07: static inline function
    5252  with no parameters
    5353  returning const volatile int
    5454
    5555
    56 errors/declaration.cfa:31:1 error: duplicate const, duplicate volatile in declaration of f08: static inline function
     56errors/declaration.cfa:31:1 error: duplicate const volatile qualifier(s) in declaration of f08: static inline function
    5757  with no parameters
    5858  returning const volatile int
    5959
    6060
    61 errors/declaration.cfa:33:1 error: duplicate const, duplicate volatile in declaration of f09: static inline function
     61errors/declaration.cfa:33:1 error: duplicate const volatile qualifier(s) in declaration of f09: static inline function
    6262  with no parameters
    6363  returning const volatile int
    6464
    6565
    66 errors/declaration.cfa:34:1 error: duplicate const, duplicate _Atomic, duplicate _Atomic, duplicate const, duplicate restrict, duplicate volatile in declaration of f09: static inline function
     66errors/declaration.cfa:34:1 error: duplicate const qualifier(s), duplicate _Atomic qualifier(s), duplicate _Atomic qualifier(s), duplicate const restrict volatile qualifier(s) in declaration of f09: static inline function
    6767  with no parameters
    6868  returning const restrict volatile _Atomic int
Note: See TracChangeset for help on using the changeset viewer.