Changeset e02e13f
- Timestamp:
- Apr 4, 2023, 10:12:57 PM (2 years ago)
- 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. - Files:
-
- 28 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/LaTeXmacros/common.sty
rff71057 re02e13f 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Fri Feb 10 12:09:30202314 %% Update Count : 58 113 %% Last Modified On : Tue Apr 4 12:03:19 2023 14 %% Update Count : 585 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 266 266 \newcommand{\LstCommentStyle}[1]{{\lst@basicstyle{\lst@commentstyle{#1}}}} 267 267 \newcommand{\LstStringStyle}[1]{{\lst@basicstyle{\lst@stringstyle{#1}}}} 268 \newcommand{\LstNumberStyle}[1]{{\lst@basicstyle{\lst@numberstyle{#1}}}} 268 269 269 270 \newlength{\gcolumnposn} % temporary hack because lstlisting does not handle tabs correctly … … 286 287 columns=fullflexible, 287 288 basicstyle=\linespread{0.9}\sf, % reduce line spacing and use sanserif font 288 stringstyle=\ tt,% use typewriter font289 stringstyle=\small\tt, % use typewriter font 289 290 tabsize=5, % N space tabbing 290 291 xleftmargin=\parindentlnth, % indent code to paragraph indentation -
doc/LaTeXmacros/common.tex
rff71057 re02e13f 11 11 %% Created On : Sat Apr 9 10:06:17 2016 12 12 %% Last Modified By : Peter A. Buhr 13 %% Last Modified On : Fri Feb 17 08:32:47202314 %% Update Count : 56 513 %% Last Modified On : Tue Apr 4 12:03:18 2023 14 %% Update Count : 567 15 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 16 16 … … 291 291 columns=fullflexible, 292 292 basicstyle=\linespread{0.9}\sf, % reduce line spacing and use sanserif font 293 stringstyle=\ tt,% use typewriter font293 stringstyle=\small\tt, % use typewriter font 294 294 tabsize=5, % N space tabbing 295 295 xleftmargin=\parindentlnth, % indent code to paragraph indentation -
doc/theses/colby_parsons_MMAth/Makefile
rff71057 re02e13f 96 96 97 97 ${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} 99 99 # Must have *.aux file containing citations for bibtex 100 100 if [ ! -r ${basename $@}.aux ] ; then ${LaTeX} ${basename $@}.tex ; fi -
doc/theses/colby_parsons_MMAth/style/style.tex
rff71057 re02e13f 1 1 \input{common} 2 \CFAStyle % CFA code-style 3 \lstset{language=CFA} % default language 2 4 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}} 72 6 \newcommand{\uC}{$\mu$\CC} 73 7 -
doc/theses/colby_parsons_MMAth/text/CFA_concurrency.tex
rff71057 re02e13f 1 1 \chapter{Concurrency in \CFA}\label{s:cfa_concurrency} 2 2 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 variableswhich he also added to \CFA.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 generators, coroutines, monitors, and user-level threading. 5 Not 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. 6 6 7 7 \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. 9 Kernel threads are created by instancing a @processor@ structure. 10 User-thread types are defined by creating a @thread@ aggregate-type, \ie replace @struct@ with @thread@. 11 For each thread type a corresponding @main@ routine must be defined, which is where the thread starts running once it is created. 12 Examples of \CFA user thread and processor creation are shown in \VRef[Listing]{l:cfa_thd_init}. 18 13 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}$ 16 void @main@( my_thread & this ) { $\C{// thread start routine}$ 17 sout | "Hello threading world"; 24 18 } 25 19 26 20 int 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 scope21 @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 33 27 } 28 \end{cfa} 34 29 35 \end{cfacode} 30 When processors are added, they are added alongside the existing processor given to each program. 31 Thus, for $N$ processors, allocate $N-1$ processors. 32 A thread is implicitly joined at deallocated, either implicitly at block exit for stack allocation or explicitly at @delete@ for heap allocation. 33 The thread performing the deallocation must wait for the thread to terminate before the deallocation can occur. 34 A 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 7 7 \section{Overview} 8 8 The following serves as an introduction to \CFA. 9 \CFA is a layer over C, is transpiled to Cand is largely considered to be an extension of C.10 Beyond C, it adds productivity features, libraries, a type system, and many other languageconstructions.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 limitedinheritance.13 \CFA is rich with interesting features, but a subset that is pertinent to this work will bediscussed.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. 10 Beyond C, it adds productivity features, extended libraries, an advanced type system, and many control-flow/concurrency constructions. 11 However, \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. 13 While \CFA is rich with interesting features, only the subset pertinent to this work is discussed. 14 14 15 15 \section{References} 16 References in \CFA are similar to references in \CC , however in\CFA references are rebindable, and support multi-level referencing.16 References in \CFA are similar to references in \CC; however \CFA references are rebindable, and support multi-level referencing. 17 17 References 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{cfa code}[caption={Example of \CFA references},label={l:cfa_ref}]18 Another difference is the use of @0p@ instead of C's @NULL@ or \CC's @nullptr@. 19 Examples of references are shown in \VRef[Listing]{l:cfa_ref}. 20 21 \begin{cfa}[caption={Example of \CFA references},label={l:cfa_ref}] 22 22 int i = 2; 23 int & ref_i = i; // declare ref to i24 int * ptr_i = &i; // ptr to i23 int & ref_i = i; $\C{// declare ref to i}$ 24 int * ptr_i = &i; $\C{// ptr to i}$ 25 25 26 26 // address of ref_i is the same as address of i 27 27 assert( &ref_i == ptr_i ); 28 28 29 int && ref_ref_i = ref_i; // can have a ref to a ref30 ref_i = 3; // set i to 329 int && ref_ref_i = ref_i; $\C{// can have a ref to a ref}$ 30 ref_i = 3; $\C{// set i to 3}$ 31 31 int new_i = 4; 32 32 33 33 // syntax to rebind ref_i (must cancel implicit deref) 34 &ref_i = &new_i; // (&*)ref_i = &new_i; (sets underlying ptr)35 \end{cfa code}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}. 40 40 Variables 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{cfa code}[caption={Example of \CFA functionoverloading},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{cfa code}41 A routine or variable is disambiguated at each usage site via its type and surrounding expression context. 42 A cast is used to disambiguate any conflicting usage. 43 Examples of overloading are shown in \VRef[Listing]{l:cfa_overload}. 44 45 \begin{cfa}[caption={Example of \CFA overloading},label={l:cfa_overload}] 46 int foo() { sout | "A"; return 0;} 47 int foo( int bar ) { sout | "B"; return 1; } 48 int foo( double bar ) { sout | "C"; return 2; } 49 double foo( double bar ) { sout | "D"; return 3; } 50 void foo( double bar ) { sout | bar; } 51 52 int 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} 60 60 61 61 62 62 \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: 63 The \CFA @with@ statement is for exposing fields of an aggregate type within a scope, allowing field names without qualification. 64 This feature is also implemented in Pascal~\cite{Pascal}. 65 It can exist as a stand-alone statement or wrap a routine body to expose aggregate fields. 66 Examples 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}] 69 struct pair { double x, y; }; 70 struct triple { int a, b, c; }; 79 71 pair 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 } 77 void 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} 103 82 104 83 105 84 \section{Operators} 106 85 Operators 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}] 86 Operators in \CFA are named using an operator symbol and '@?@' to represent operands. 87 Examples of \CFA operators are shown in \VRef[Listing]{l:cfa_operate}. 88 89 \begin{cfa}[caption={Example of \CFA operators},label={l:cfa_operate}] 112 90 struct 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 }; 93 coord ++@?@( coord & c ) with( c ) { $\C{// post increment}$ 94 x++; y++; z++; 95 return c; 96 } 97 coord @?@<=@?@( 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} 128 101 129 102 130 103 \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}] 104 Constructors and destructors in \CFA are special operator routines used for creation and destruction of objects. 105 The default constructor and destructor for a type are called implicitly upon creation and deletion, respectively. 106 Examples 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}] 137 109 struct 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 }; 112 void ?{}( discrete_point & this ) with(this) { $\C{// default constructor}$ 113 [x, y] = 0; 114 } 115 void ?{}( discrete_point & this, int x, int y ) { $\C{// explicit constructor}$ 116 this.[x, y] = [x, y]; 117 } 118 void ^?{}( discrete_point & this ) with(this) { $\C{// destructor}$ 119 ?{}( this ); $\C{// reset by calling default constructor}$ 120 } 121 int 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} 160 126 161 127 162 128 \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.129 C 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. 165 131 166 132 \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. 134 A @forall@ takes in a set of types and a list of constraints. 135 The declarations that follow the @forall@ are parameterized over the types listed that satisfy the constraints. 136 A list of @forall@ constraints can be refactored into a named @trait@ and reused in @forall@s. 137 Examples 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}] 175 140 // sized() is a trait that means the type has a size 176 forall( V & | sized(V) ) // type params for trait141 forall( V & | sized(V) ) $\C{// type params for trait}$ 177 142 trait 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 150 forall( 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 } 193 157 } 194 158 struct Vec1 { int x; }; … … 196 160 void ?{}( Vec1 & this, int x ) { this.x = x; } 197 161 void ^?{}( 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; }162 Vec1 ?+?( Vec1 v1, Vec1 v2 ) { v1.x += v2.x; return v1; } 163 Vec1 ?*?( int c, Vec1 v1 ) { v1.x = v1.x * c; return v1; } 200 164 201 165 struct Vec2 { int x; int y; }; … … 203 167 void ?{}( Vec2 & this, int x ) { this.x = x; this.y = x; } 204 168 void ^?{}( 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} 169 Vec2 ?+?( Vec2 v1, Vec2 v2 ) { v1.x += v2.x; v1.y += v2.y; return v1; } 170 Vec2 ?*?( int c, Vec2 v1 ) { v1.x = v1.x * c; v1.y = v1.y * c; return v1; } 171 172 int 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} 218 180 219 181 \subsection{Inheritance} 220 Inheritance in \CFA copies its style from Plan-9 C nominalinheritance.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 inlinedtype.222 An example of \CFA inheritance is shown in Listing~\ref{l:cfa_inherit}. 223 224 \begin{cfa code}[tabsize=3,caption={Example of \CFAinheritance},label={l:cfa_inherit}]182 Inheritance in \CFA is taken from Plan-9 C's containment inheritance. 183 In \CFA, @struct@s can @inline@ another struct type to gain its fields and masquerade as that type. 184 Examples 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}] 225 187 struct one_d { double x; }; 226 188 struct two_d { 227 inlineone_d;228 189 @inline@ one_d; 190 double y; 229 191 }; 230 192 struct three_d { 231 inlinetwo_d;232 193 @inline@ two_d; 194 double z; 233 195 }; 234 196 double get_x( one_d & d ){ return d.x; } … … 236 198 struct dog {}; 237 199 struct dog_food { 238 200 int count; 239 201 }; 240 202 struct 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 }; 206 void pet_dog( dog & d ) { sout | "woof"; } 207 void print_food( dog_food & f ) { sout | f.count; } 208 209 int 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 88 88 Similarly to create a message type a user must define a struct which \code{inline}'s the base \code{message} struct. 89 89 90 \begin{cfa code}90 \begin{cfa} 91 91 struct derived_actor { 92 92 inline actor; // Plan-9 C inheritance … … 118 118 return 0; 119 119 } 120 \end{cfa code}120 \end{cfa} 121 121 122 122 The above code is a simple actor program in \CFA. … … 125 125 Key things to highlight include the \code{receive} signature, and calls to \code{start_actor_system}, and \code{stop_actor_system}. 126 126 To define a behaviour for some derived actor and derived message type, one must declare a routine with the signature: 127 \begin{cfa code}127 \begin{cfa} 128 128 Allocation receive( derived_actor & receiver, derived_msg & msg ) 129 \end{cfa code}129 \end{cfa} 130 130 Where \code{derived_actor} and \code{derived_msg} can be any derived actor and derived message types respectively. 131 131 The return value of \code{receive} must be a value from the \code{Allocation} enum: 132 \begin{cfa code}132 \begin{cfa} 133 133 enum Allocation { Nodelete, Delete, Destroy, Finished }; 134 \end{cfa code}134 \end{cfa} 135 135 The \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. 136 136 In 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. 137 137 For messages, they either default to \code{Nodelete}, or they can be passed an \code{Allocation} via the \code{message} constructor. 138 138 Message state can be updated via a call to: 139 \begin{cfa code}139 \begin{cfa} 140 140 void set_allocation( message & this, Allocation state ) 141 \end{cfa code}141 \end{cfa} 142 142 143 143 The following describes the use of each of the \code{Allocation} values: … … 186 186 All message sends are done using the left shift operater, \ie <<, similar to the syntax of \CC's output. 187 187 The signature of the left shift operator is: 188 \begin{cfa code}188 \begin{cfa} 189 189 Allocation ?<<?( derived_actor & receiver, derived_msg & msg ) 190 \end{cfa code}190 \end{cfa} 191 191 192 192 An astute eye will notice that this is the same signature as the \code{receive} routine which is no coincidence. … … 368 368 To first verify sequential correctness, consider the equivalent sequential swap below: 369 369 370 \begin{cfa code}370 \begin{cfa} 371 371 void swap( uint victim_idx, uint my_idx ) { 372 372 // Step 0: … … 380 380 request_queues[my_idx] = vic_queue; 381 381 } 382 \end{cfa code}382 \end{cfa} 383 383 384 384 Step 1 is missing in the sequential example since in only matter in the concurrent context presented later. … … 386 386 Temporary 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. 387 387 388 \begin{cfa code}388 \begin{cfa} 389 389 // This routine is atomic 390 390 bool CAS( work_queue ** ptr, work_queue ** old, work_queue * new ) { … … 427 427 return true; 428 428 } 429 \end{cfa code}\label{c:swap}429 \end{cfa}\label{c:swap} 430 430 431 431 Now consider the concurrent implementation of the swap. -
doc/theses/colby_parsons_MMAth/text/channels.tex
rff71057 re02e13f 118 118 Also 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. 119 119 120 \begin{cfa code}[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}] 121 121 struct barrier { 122 122 channel( int ) barWait; … … 171 171 return 0; 172 172 } 173 \end{cfa code}174 175 \begin{cfa code}[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}] 176 176 177 177 struct barrier { … … 237 237 return 0; 238 238 } 239 \end{cfa code}239 \end{cfa} 240 240 241 241 In Listing~\ref{l:cfa_resume} an example of channel closing with resumption is used. … … 244 244 If 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. 245 245 246 \begin{cfa code}[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}] 247 247 channel( int ) chan{ 128 }; 248 248 … … 280 280 return 0; 281 281 } 282 \end{cfa code}282 \end{cfa} 283 283 284 284 \section{Performance} -
doc/theses/colby_parsons_MMAth/text/mutex_stmt.tex
rff71057 re02e13f 12 12 Additionally, 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}. 13 13 14 \begin{cfa code}[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}] 15 15 owner_lock lock1, lock2, lock3; 16 16 int count = 0; … … 20 20 } 21 21 mutex( lock2, lock3 ) count++; // or inline statement 22 \end{cfa code}22 \end{cfa} 23 23 24 24 \section{Other Languages} … … 32 32 An example of \CC scoped\_lock usage is shown in Listing~\ref{l:cc_scoped_lock}. 33 33 34 \begin{c ppcode}[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}] 35 35 std::mutex lock1, lock2, lock3; 36 36 { … … 38 38 // locks are released via raii at end of scope 39 39 } 40 \end{c ppcode}40 \end{cfa} 41 41 42 42 \section{\CFA implementation} … … 58 58 This use case is shown in Listing~\ref{l:sout}. 59 59 60 \begin{cfa code}[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}] 61 61 mutex( sout ) 62 62 sout | "This output is protected by mutual exclusion!"; 63 \end{cfa code}63 \end{cfa} 64 64 65 65 \section{Deadlock Avoidance} … … 70 70 The algorithm presented is taken directly from the source code of the \code{<mutex>} header, with some renaming and comments for clarity. 71 71 72 \begin{c ppcode}[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}] 73 73 int first = 0; // first lock to attempt to lock 74 74 do { … … 86 86 // if first lock is still held then all have been acquired 87 87 } while (!locks[first].owns_lock()); // is first lock held? 88 \end{c ppcode}88 \end{cfa} 89 89 90 90 The 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 98 98 \hypersetup{ 99 99 plainpages=false, % needed if Roman numbers in frontpages 100 unicode=false, % non-Latin characters in Acrobat ’s bookmarks101 pdftoolbar=true, % show Acrobat ’s toolbar?102 pdfmenubar=true, % show Acrobat ’s 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? 103 103 pdffitwindow=false, % window fit to page when opened 104 104 pdfstartview={FitH}, % fits the width of the page to the window … … 110 110 colorlinks=true, % false: boxed links; true: colored links 111 111 linkcolor=blue, % color of internal links 112 citecolor= green, % color of links to bibliography112 citecolor=blue, % color of links to bibliography 113 113 filecolor=magenta, % color of file links 114 114 urlcolor=cyan % color of external links -
src/AST/SymbolTable.cpp
rff71057 re02e13f 70 70 if ( baseExpr ) { 71 71 if (baseExpr->env) { 72 Expr * base = shallowCopy(baseExpr);72 Expr * base = deepCopy(baseExpr); 73 73 const TypeSubstitution * subs = baseExpr->env; 74 74 base->env = nullptr; -
src/Parser/DeclarationNode.cc
rff71057 re02e13f 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Mar 14 11:56:00 202313 // Update Count : 1 40612 // Last Modified On : Tue Apr 4 10:28:00 2023 13 // Update Count : 1392 14 14 // 15 15 … … 21 21 #include <string> // for string, operator+, allocator, char... 22 22 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 23 33 #include "Common/SemanticError.h" // for SemanticError 24 34 #include "Common/UniqueName.h" // for UniqueName 25 #include "Common/utility.h" // for maybeClone , maybeBuild, CodeLocation35 #include "Common/utility.h" // for maybeClone 26 36 #include "Parser/ParseNode.h" // for DeclarationNode, ExpressionNode 27 #include "SynTree/LinkageSpec.h" // for Spec, linkageName, Cforall28 #include "SynTree/Attribute.h" // for Attribute29 #include "SynTree/Declaration.h" // for TypeDecl, ObjectDecl, InlineMemberDecl, Declaration30 #include "SynTree/Expression.h" // for Expression, ConstantExpr31 #include "SynTree/Statement.h" // for AsmStmt32 #include "SynTree/Type.h" // for Type, Type::StorageClasses, Type::...33 37 #include "TypeData.h" // for TypeData, TypeData::Aggregate_t 34 38 #include "TypedefTable.h" // for TypedefTable … … 61 65 UniqueName DeclarationNode::anonymous( "__anonymous" ); 62 66 63 extern LinkageSpec::Spec linkage; // defined in parser.yy67 extern ast::Linkage::Spec linkage; // defined in parser.yy 64 68 65 69 DeclarationNode::DeclarationNode() : … … 67 71 68 72 // variable.name = nullptr; 69 variable.tyClass = TypeDecl::NUMBER_OF_KINDS;73 variable.tyClass = ast::TypeDecl::NUMBER_OF_KINDS; 70 74 variable.assertions = nullptr; 71 75 variable.initializer = nullptr; … … 105 109 newnode->hasEllipsis = hasEllipsis; 106 110 newnode->linkage = linkage; 107 newnode->asmName = maybeC lone( asmName );108 cloneAll( attributes, newnode->attributes );111 newnode->asmName = maybeCopy( asmName ); 112 newnode->attributes = attributes; 109 113 newnode->initializer = maybeClone( initializer ); 110 114 newnode->extension = extension; … … 118 122 119 123 newnode->assert.condition = maybeClone( assert.condition ); 120 newnode->assert.message = maybeC lone( assert.message );124 newnode->assert.message = maybeCopy( assert.message ); 121 125 return newnode; 122 126 } // DeclarationNode::clone … … 128 132 } // if 129 133 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 ); 136 140 137 141 if ( type ) { … … 154 158 if ( ! attributes.empty() ) { 155 159 os << string( indent + 2, ' ' ) << "with attributes " << endl; 156 for ( Attribute * attr: reverseIterate( attributes ) ) {160 for ( ast::ptr<ast::Attribute> const & attr : reverseIterate( attributes ) ) { 157 161 os << string( indent + 4, ' ' ) << attr->name.c_str() << endl; 158 162 } // for … … 169 173 } 170 174 171 DeclarationNode * DeclarationNode::newStorageClass( Type::StorageClasses sc ) {175 DeclarationNode * DeclarationNode::newStorageClass( ast::Storage::Classes sc ) { 172 176 DeclarationNode * newnode = new DeclarationNode; 173 177 newnode->storageClasses = sc; … … 175 179 } // DeclarationNode::newStorageClass 176 180 177 DeclarationNode * DeclarationNode::newFuncSpecifier( Type::FuncSpecifiers fs ) {181 DeclarationNode * DeclarationNode::newFuncSpecifier( ast::Function::Specs fs ) { 178 182 DeclarationNode * newnode = new DeclarationNode; 179 183 newnode->funcSpecs = fs; … … 181 185 } // DeclarationNode::newFuncSpecifier 182 186 183 DeclarationNode * DeclarationNode::newTypeQualifier( Type::Qualifiers tq ) {187 DeclarationNode * DeclarationNode::newTypeQualifier( ast::CV::Qualifiers tq ) { 184 188 DeclarationNode * newnode = new DeclarationNode; 185 189 newnode->type = new TypeData(); … … 241 245 } 242 246 243 DeclarationNode * DeclarationNode::newAggregate( AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {247 DeclarationNode * DeclarationNode::newAggregate( ast::AggregateDecl::Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) { 244 248 DeclarationNode * newnode = new DeclarationNode; 245 249 newnode->type = new TypeData( TypeData::Aggregate ); … … 271 275 } // DeclarationNode::newEnum 272 276 273 274 275 277 DeclarationNode * DeclarationNode::newName( const string * name ) { 276 278 DeclarationNode * newnode = new DeclarationNode; … … 324 326 } // DeclarationNode::newFromTypeGen 325 327 326 DeclarationNode * DeclarationNode::newTypeParam( TypeDecl::Kind tc, const string * name ) {328 DeclarationNode * DeclarationNode::newTypeParam( ast::TypeDecl::Kind tc, const string * name ) { 327 329 DeclarationNode * newnode = newName( name ); 328 330 newnode->type = nullptr; … … 336 338 newnode->type = new TypeData( TypeData::Aggregate ); 337 339 newnode->type->aggregate.name = name; 338 newnode->type->aggregate.kind = AggregateDecl::Trait;340 newnode->type->aggregate.kind = ast::AggregateDecl::Trait; 339 341 newnode->type->aggregate.params = params; 340 342 newnode->type->aggregate.fields = asserts; … … 346 348 newnode->type = new TypeData( TypeData::AggregateInst ); 347 349 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; 349 351 newnode->type->aggInst.aggregate->aggregate.name = name; 350 352 newnode->type->aggInst.params = params; … … 381 383 newnode->type->array.dimension = size; 382 384 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 *>() ) { 384 386 newnode->type->array.isVarLen = false; 385 387 } else { … … 451 453 DeclarationNode * newnode = new DeclarationNode; 452 454 newnode->type = nullptr; 453 std:: list< Expression *> exprs;455 std::vector<ast::ptr<ast::Expr>> exprs; 454 456 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 ) ) ); 456 459 delete name; 457 460 return newnode; … … 470 473 } 471 474 472 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, Expression* message ) {475 DeclarationNode * DeclarationNode::newStaticAssert( ExpressionNode * condition, ast::Expr * message ) { 473 476 DeclarationNode * newnode = new DeclarationNode; 474 477 newnode->assert.condition = condition; … … 477 480 } 478 481 479 480 void appendError( string & dst, const string & src ) { 482 static void appendError( string & dst, const string & src ) { 481 483 if ( src.empty() ) return; 482 484 if ( dst.empty() ) { dst = src; return; } … … 485 487 486 488 void 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() ); 495 498 } // for 496 499 } // DeclarationNode::checkQualifiers 497 500 498 501 void 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 } 521 533 } // if 522 534 … … 528 540 storageClasses |= q->storageClasses; 529 541 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 533 549 return this; 534 550 } // DeclarationNode::copySpecifiers … … 716 732 717 733 DeclarationNode * DeclarationNode::addAssertions( DeclarationNode * assertions ) { 718 if ( variable.tyClass != TypeDecl::NUMBER_OF_KINDS ) {734 if ( variable.tyClass != ast::TypeDecl::NUMBER_OF_KINDS ) { 719 735 if ( variable.assertions ) { 720 736 variable.assertions->appendList( assertions ); … … 798 814 DeclarationNode * DeclarationNode::copyAttribute( DeclarationNode * a ) { 799 815 if ( a ) { 800 for ( Attribute *attr: reverseIterate( a->attributes ) ) { 801 attributes.push_front( attr ); 802 } // for 816 spliceBegin( attributes, a->attributes ); 803 817 a->attributes.clear(); 804 818 } // if … … 921 935 922 936 DeclarationNode * 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." ); 924 938 variable.initializer = init; 925 939 return this; … … 985 999 } 986 1000 987 void buildList( const DeclarationNode * firstNode, std::list< Declaration * > & outputList ) { 1001 void buildList( const DeclarationNode * firstNode, 1002 std::vector<ast::ptr<ast::Decl>> & outputList ) { 988 1003 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 ); 990 1005 991 1006 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 992 1007 try { 993 1008 bool extracted = false, anon = false; 994 AggregateDecl * unionDecl = nullptr;1009 ast::AggregateDecl * unionDecl = nullptr; 995 1010 996 1011 if ( DeclarationNode * extr = cur->extractAggregate() ) { … … 1029 1044 } // if 1030 1045 1031 Declaration* decl = extr->build();1046 ast::Decl * decl = extr->build(); 1032 1047 if ( decl ) { 1033 1048 // Remember the declaration if it is a union aggregate ? 1034 unionDecl = dynamic_cast< UnionDecl *>( decl );1049 unionDecl = dynamic_cast<ast::UnionDecl *>( decl ); 1035 1050 1036 1051 decl->location = cur->location; … … 1051 1066 } // if 1052 1067 1053 Declaration* decl = cur->build();1068 ast::Decl * decl = cur->build(); 1054 1069 if ( decl ) { 1055 if ( TypedefDecl * typedefDecl = dynamic_cast<TypedefDecl *>( decl ) ) {1070 if ( auto typedefDecl = dynamic_cast<ast::TypedefDecl *>( decl ) ) { 1056 1071 if ( unionDecl ) { // is the typedef alias a union aggregate ? 1057 1072 // This code handles a special issue with the attribute transparent_union. … … 1065 1080 1066 1081 // 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 ); 1068 1084 // 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 order1085 for ( auto attr = instType->attributes.begin() ; attr != instType->attributes.end() ; ) { // forward order 1086 assert( *attr ); 1071 1087 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 ); 1076 1090 } else { 1077 attr++; // advance iterator1091 attr++; 1078 1092 } // if 1079 1093 } // for 1094 typedefDecl->base = instType; 1080 1095 } // if 1081 1096 } // if … … 1090 1105 if ( ! (extracted && decl->name == "" && ! anon && ! cur->get_inLine()) ) { 1091 1106 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() ) ) { 1094 1109 if ( aggr->name.find("anonymous") == std::string::npos ) { 1095 1110 if ( ! cur->get_inLine() ) { … … 1117 1132 1118 1133 // currently only builds assertions, function parameters, and return values 1119 void buildList( const DeclarationNode * firstNode, std:: list< DeclarationWithType *> & outputList ) {1134 void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ) { 1120 1135 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 ); 1122 1137 1123 1138 for ( const DeclarationNode * cur = firstNode; cur; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ) ) { 1124 1139 try { 1125 Declaration* decl = cur->build();1140 ast::Decl * decl = cur->build(); 1126 1141 assert( decl ); 1127 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType *>( decl ) ) {1142 if ( ast::DeclWithType * dwt = dynamic_cast<ast::DeclWithType *>( decl ) ) { 1128 1143 dwt->location = cur->location; 1129 1144 *out++ = dwt; 1130 } else if ( StructDecl * agg = dynamic_cast< StructDecl *>( decl ) ) {1145 } else if ( ast::StructDecl * agg = dynamic_cast<ast::StructDecl *>( decl ) ) { 1131 1146 // 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->l ocation = cur->location;1147 auto inst = new ast::StructInstType( agg->name ); 1148 auto obj = new ast::ObjectDecl( cur->location, "", inst ); 1149 obj->linkage = linkage; 1135 1150 *out++ = obj; 1136 1151 delete agg; 1137 } else if ( UnionDecl * agg = dynamic_cast< UnionDecl *>( decl ) ) {1152 } else if ( ast::UnionDecl * agg = dynamic_cast<ast::UnionDecl *>( decl ) ) { 1138 1153 // 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 ); 1142 1158 *out++ = obj; 1143 } else if ( EnumDecl * agg = dynamic_cast< EnumDecl *>( decl ) ) {1159 } else if ( ast::EnumDecl * agg = dynamic_cast<ast::EnumDecl *>( decl ) ) { 1144 1160 // 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 ); 1148 1169 *out++ = obj; 1149 1170 } // if … … 1158 1179 } // buildList 1159 1180 1160 void buildTypeList( const DeclarationNode * firstNode, std::list< Type * > & outputList ) { 1181 void buildTypeList( const DeclarationNode * firstNode, 1182 std::vector<ast::ptr<ast::Type>> & outputList ) { 1161 1183 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 ); 1163 1185 const DeclarationNode * cur = firstNode; 1164 1186 … … 1177 1199 } // buildTypeList 1178 1200 1179 Declaration* DeclarationNode::build() const {1201 ast::Decl * DeclarationNode::build() const { 1180 1202 if ( ! error.empty() ) SemanticError( this, error + " in declaration of " ); 1181 1203 1182 1204 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 ); 1184 1207 } // if 1185 1208 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 ) { 1190 1214 // 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." ); 1193 1217 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 ); 1196 1227 return ret; 1197 1228 } // if … … 1215 1246 } // if 1216 1247 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 ); 1218 1259 if ( isDelete ) { 1219 DeclarationWithType * dwt = strict_dynamic_cast<DeclarationWithType *>( decl );1260 auto dwt = strict_dynamic_cast<ast::DeclWithType *>( decl ); 1220 1261 dwt->isDeleted = true; 1221 1262 } … … 1224 1265 1225 1266 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 ); 1227 1270 } 1228 1271 … … 1235 1278 } // if 1236 1279 if ( enumInLine ) { 1237 return new InlineMemberDecl( *name, storageClasses, linkage, nullptr ); 1280 return new ast::InlineMemberDecl( location, 1281 *name, (ast::Type*)nullptr, storageClasses, linkage ); 1238 1282 } // if 1239 1283 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 1297 ast::Type * DeclarationNode::buildType() const { 1244 1298 assert( type ); 1245 1299 … … 1247 1301 case TypeData::Enum: 1248 1302 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 ); 1251 1306 return ret; 1252 1307 } 1253 1308 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 ); 1256 1316 return ret; 1257 1317 } 1258 1318 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; 1261 1322 return simpletypes; 1262 1323 } // switch -
src/Parser/ExpressionNode.cc
rff71057 re02e13f 10 10 // Created On : Sat May 16 13:17:07 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Mar 14 12:00:00 202313 // Update Count : 108 212 // Last Modified On : Tue Apr 4 11:07:00 2023 13 // Update Count : 1083 14 14 // 15 15 … … 21 21 #include <string> // for string, operator+, operator== 22 22 23 #include "AST/Expr.hpp" // for NameExpr 24 #include "AST/Type.hpp" // for BaseType, SueInstType 23 25 #include "Common/SemanticError.h" // for SemanticError 24 26 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild, CodeLo... 25 27 #include "ParseNode.h" // for ExpressionNode, maybeMoveBuildType 26 #include "SynTree/Constant.h" // for Constant27 #include "SynTree/Declaration.h" // for EnumDecl, StructDecl, UnionDecl28 #include "SynTree/Expression.h" // for Expression, ConstantExpr, NameExpr29 #include "SynTree/Statement.h" // for CompoundStmt, Statement30 #include "SynTree/Type.h" // for BasicType, Type, Type::Qualifiers31 28 #include "parserutility.h" // for notZeroExpr 32 33 class Initializer;34 29 35 30 using namespace std; … … 48 43 // because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their 49 44 // type. 50 51 extern const Type::Qualifiers noQualifiers; // no qualifiers on constants52 45 53 46 // static inline bool checkH( char c ) { return c == 'h' || c == 'H'; } … … 127 120 } // scanbin 128 121 129 Expression * build_constantInteger( string & str ) { 130 static const BasicType::Kind kind[2][6] = { 122 ast::Expr * build_constantInteger( 123 const CodeLocation & location, string & str ) { 124 static const ast::BasicType::Kind kind[2][6] = { 131 125 // 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, }, 134 128 }; 135 129 … … 141 135 string str2( "0x0" ); 142 136 unsigned long long int v, v2 = 0; // converted integral value 143 Expression* ret, * ret2;137 ast::Expr * ret, * ret2; 144 138 145 139 int type = -1; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128 … … 149 143 // special constants 150 144 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 ); 152 146 goto CLEANUP; 153 147 } // if 154 148 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 ); 156 150 goto CLEANUP; 157 151 } // if … … 304 298 305 299 // 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 ); 307 302 if ( Unsigned && type < 2 ) { // hh or h, less than int ? 308 303 // 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 ); 310 308 } else if ( ltype != -1 ) { // explicit length ? 311 309 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 ); 317 322 } 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 ); 319 327 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 ) ); 321 332 } // if 322 333 } // if … … 362 373 363 374 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 }, 375 ast::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 }, 368 380 }; 369 381 … … 402 414 403 415 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 ); 407 426 } // if 408 427 … … 419 438 } // sepString 420 439 421 Expression * build_constantChar(string & str ) {440 ast::Expr * build_constantChar( const CodeLocation & location, string & str ) { 422 441 string units; // units 423 442 sepString( str, units, '\'' ); // separate constant from units 424 443 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] ); 426 448 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 } ); 428 452 } // if 429 453 … … 432 456 } // build_constantChar 433 457 434 Expression * build_constantStr( string & str ) { 458 ast::Expr * build_constantStr( 459 const CodeLocation & location, 460 string & str ) { 435 461 assert( str.length() > 0 ); 436 462 string units; // units 437 463 sepString( str, units, '"' ); // separate constant from units 438 464 439 Type * strtype;465 ast::Type * strtype; 440 466 switch ( str[0] ) { // str has >= 2 characters, i.e, null string "" => safe to look at subscripts 0/1 441 467 case 'u': 442 468 if ( str[1] == '8' ) goto Default; // utf-8 characters => array of char 443 469 // lookup type of associated typedef 444 strtype = new TypeInstType( Type::Qualifiers( ), "char16_t", false );470 strtype = new ast::TypeInstType( "char16_t", ast::TypeDecl::Dtype ); 445 471 break; 446 472 case 'U': 447 strtype = new TypeInstType( Type::Qualifiers( ), "char32_t", false );473 strtype = new ast::TypeInstType( "char32_t", ast::TypeDecl::Dtype ); 448 474 break; 449 475 case 'L': 450 strtype = new TypeInstType( Type::Qualifiers( ), "wchar_t", false );476 strtype = new ast::TypeInstType( "wchar_t", ast::TypeDecl::Dtype ); 451 477 break; 452 478 Default: // char default string type 453 479 default: 454 strtype = new BasicType( Type::Qualifiers( ),BasicType::Char );480 strtype = new ast::BasicType( ast::BasicType::Char ); 455 481 } // 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 ); 460 489 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 } ); 462 493 } // if 463 494 … … 466 497 } // build_constantStr 467 498 468 Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) { 499 ast::Expr * build_field_name_FLOATING_FRACTIONconstant( 500 const CodeLocation & location, const string & str ) { 469 501 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) ) ); 471 504 delete &str; 472 505 return ret; 473 506 } // build_field_name_FLOATING_FRACTIONconstant 474 507 475 Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) { 508 ast::Expr * build_field_name_FLOATING_DECIMALconstant( 509 const CodeLocation & location, const string & str ) { 476 510 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 ) ) ); 478 513 delete &str; 479 514 return ret; 480 515 } // build_field_name_FLOATING_DECIMALconstant 481 516 482 Expression * build_field_name_FLOATINGconstant( const string & str ) { 517 ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation & location, 518 const string & str ) { 483 519 // str is of the form A.B -> separate at the . and return member expression 484 520 int a, b; … … 486 522 stringstream ss( str ); 487 523 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 ); 489 528 delete &str; 490 529 return ret; 491 530 } // build_field_name_FLOATINGconstant 492 531 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; 532 ast::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 503 545 } // make_field_name_fraction_constants 504 546 505 Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ) { 506 return make_field_name_fraction_constants( fieldName, maybeMoveBuild( fracts ) ); 547 ast::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 ) ); 507 551 } // build_field_name_fraction_constants 508 552 509 NameExpr * build_varref( const string * name ) { 510 NameExpr * expr = new NameExpr( *name ); 553 ast::NameExpr * build_varref( const CodeLocation & location, 554 const string * name ) { 555 ast::NameExpr * expr = new ast::NameExpr( location, *name ); 511 556 delete name; 512 557 return expr; 513 558 } // build_varref 514 559 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 ); 560 ast::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 ); 522 568 } 523 569 } 524 570 } 525 return new QualifiedNameExpr(newDecl, name->name );571 return new ast::QualifiedNameExpr( location, newDecl, name->name ); 526 572 } 527 573 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 ); 574 ast::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 ); 531 578 } 532 579 533 DimensionExpr * build_dimensionref( const string * name ) { 534 DimensionExpr * expr = new DimensionExpr( *name ); 580 ast::DimensionExpr * build_dimensionref( const CodeLocation & location, 581 const string * name ) { 582 ast::DimensionExpr * expr = new ast::DimensionExpr( location, *name ); 535 583 delete name; 536 584 return expr; … … 548 596 }; // OperName 549 597 550 Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) { 551 Type * targetType = maybeMoveBuildType( decl_node ); 552 if ( dynamic_cast< VoidType * >( targetType ) ) { 598 ast::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 ) ) { 553 603 delete targetType; 554 return new CastExpr( maybeMoveBuild( expr_node ), false ); 604 return new ast::CastExpr( location, 605 maybeMoveBuild( expr_node ), 606 ast::ExplicitCast ); 555 607 } 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 ); 557 612 } // if 558 613 } // build_cast 559 614 560 Expression * build_keyword_cast( AggregateDecl::Aggregate target, ExpressionNode * expr_node ) { 561 return new KeywordCastExpr( maybeMoveBuild( expr_node ), target ); 615 ast::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 ); 562 622 } 563 623 564 Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) { 565 return new VirtualCastExpr( maybeMoveBuild( expr_node ), maybeMoveBuildType( decl_node ) ); 624 ast::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 ); 566 631 } // build_virtual_cast 567 632 568 Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member ) { 569 return new UntypedMemberExpr( member, maybeMoveBuild( expr_node ) ); 633 ast::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 ); 570 640 } // build_fieldSel 571 641 572 Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member ) { 573 UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) ); 642 ast::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 ); 574 648 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 ); 577 651 return ret; 578 652 } // build_pfieldSel 579 653 580 Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member ) { 581 Expression * ret = new UntypedOffsetofExpr( maybeMoveBuildType( decl_node ), member->get_name() ); 654 ast::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 ); 582 662 delete member; 583 663 return ret; 584 664 } // build_offsetOf 585 665 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 ); 666 ast::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 ); 588 675 } // build_and_or 589 676 590 Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ) { 591 list< Expression * > args; 677 ast::Expr * build_unary_val( const CodeLocation & location, 678 OperKinds op, 679 ExpressionNode * expr_node ) { 680 std::vector<ast::ptr<ast::Expr>> args; 592 681 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 ); 594 686 } // build_unary_val 595 687 596 Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) { 597 list< Expression * > args; 688 ast::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; 598 693 args.push_back( maybeMoveBuild( expr_node1 ) ); 599 694 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 ); 601 699 } // build_binary_val 602 700 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);701 ast::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 ); 608 706 } // build_binary_ptr 609 707 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 ) ); 708 ast::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 ); 612 717 } // build_cond 613 718 614 Expression * build_tuple( ExpressionNode * expr_node ) { 615 list< Expression * > exprs; 719 ast::Expr * build_tuple( const CodeLocation & location, 720 ExpressionNode * expr_node ) { 721 std::vector<ast::ptr<ast::Expr>> exprs; 616 722 buildMoveList( expr_node, exprs ); 617 return new UntypedTupleExpr( exprs );;723 return new ast::UntypedTupleExpr( location, std::move( exprs ) ); 618 724 } // build_tuple 619 725 620 Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ) { 621 list< Expression * > args; 726 ast::Expr * build_func( const CodeLocation & location, 727 ExpressionNode * function, 728 ExpressionNode * expr_node ) { 729 std::vector<ast::ptr<ast::Expr>> args; 622 730 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 ); 624 735 } // build_func 625 736 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 ) ); 737 ast::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 ) ); 630 747 // 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 ) ); 634 753 } 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 ) ); 640 763 } 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 ) ); 646 773 } 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 ) ); 648 777 } // if 649 778 } else { -
src/Parser/InitializerNode.cc
rff71057 re02e13f 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:20:24 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Jul 28 23:27:20 201713 // Update Count : 2 611 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Apr 4 11:18:00 2023 13 // Update Count : 27 14 14 // 15 15 … … 20 20 using namespace std; 21 21 22 #include "AST/Expr.hpp" // for Expr 23 #include "AST/Init.hpp" // for Designator, Init, ListInit, Sing... 22 24 #include "Common/SemanticError.h" // for SemanticError 23 25 #include "Common/utility.h" // for maybeBuild 24 26 #include "ParseNode.h" // for InitializerNode, ExpressionNode 25 #include "SynTree/Expression.h" // for Expression 26 #include "SynTree/Initializer.h" // for Initializer, ListInit, SingleInit 27 28 static ast::ConstructFlag toConstructFlag( bool maybeConstructed ) { 29 return maybeConstructed ? ast::MaybeConstruct : ast::NoConstruct; 30 } 27 31 28 32 InitializerNode::InitializerNode( ExpressionNode * _expr, bool aggrp, ExpressionNode * des ) … … 33 37 if ( kids ) 34 38 set_last( nullptr ); 35 } // InitializerNode::InitializerNode 39 } // InitializerNode::InitializerNode 36 40 37 41 InitializerNode::InitializerNode( InitializerNode * init, bool aggrp, ExpressionNode * des ) … … 85 89 } // InitializerNode::printOneLine 86 90 87 Initializer* InitializerNode::build() const {91 ast::Init * InitializerNode::build() const { 88 92 assertf( ! isDelete, "Should not build delete stmt InitializerNode" ); 89 93 if ( aggregate ) { 90 94 // steal designators from children 91 std:: list< Designation *> designlist;95 std::vector<ast::ptr<ast::Designation>> designlist; 92 96 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 ) ) ); 97 102 } // 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 ); 106 116 } // if 107 117 return nullptr; -
src/Parser/ParseNode.h
rff71057 re02e13f 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:28:16 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Wed Mar 29 08:40:27202313 // Update Count : 94 811 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Apr 3 17:55:00 2023 13 // Update Count : 942 14 14 // 15 15 … … 24 24 #include <string> // for string 25 25 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 26 29 #include "Common/CodeLocation.h" // for CodeLocation 27 30 #include "Common/SemanticError.h" // for SemanticError 28 31 #include "Common/UniqueName.h" // for UniqueName 29 32 #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 37 34 38 35 class Attribute; … … 108 105 void printOneLine( std::ostream & ) const; 109 106 110 virtual Initializer* build() const;107 virtual ast::Init * build() const; 111 108 private: 112 109 ExpressionNode * expr; … … 122 119 class ExpressionNode final : public ParseNode { 123 120 public: 124 ExpressionNode( Expression* expr = nullptr ) : expr( expr ) {}121 ExpressionNode( ast::Expr * expr = nullptr ) : expr( expr ) {} 125 122 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 } 127 128 128 129 bool get_extension() const { return extension; } … … 137 138 bool isExpressionType() const { return nullptr != dynamic_cast<T>(expr.get()); } 138 139 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(); 141 142 node->set_extension( this->get_extension() ); 142 143 node->location = this->location; … … 144 145 } 145 146 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; 147 149 private: 148 150 bool extension = false; … … 164 166 165 167 struct LabelNode { 166 std:: list< Label> labels;168 std::vector<ast::Label> labels; 167 169 }; 168 170 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: 172 ast::Expr * build_constantInteger( const CodeLocation &, std::string & ); 173 ast::Expr * build_constantFloat( const CodeLocation &, std::string & ); 174 ast::Expr * build_constantChar( const CodeLocation &, std::string & ); 175 ast::Expr * build_constantStr( const CodeLocation &, std::string & ); 176 ast::Expr * build_field_name_FLOATING_FRACTIONconstant( const CodeLocation &, const std::string & str ); 177 ast::Expr * build_field_name_FLOATING_DECIMALconstant( const CodeLocation &, const std::string & str ); 178 ast::Expr * build_field_name_FLOATINGconstant( const CodeLocation &, const std::string & str ); 179 ast::Expr * build_field_name_fraction_constants( const CodeLocation &, ast::Expr * fieldName, ExpressionNode * fracts ); 180 181 ast::NameExpr * build_varref( const CodeLocation &, const std::string * name ); 182 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const DeclarationNode * decl_node, const ast::NameExpr * name ); 183 ast::QualifiedNameExpr * build_qualified_expr( const CodeLocation &, const ast::EnumDecl * decl, const ast::NameExpr * name ); 184 ast::DimensionExpr * build_dimensionref( const CodeLocation &, const std::string * name ); 185 186 ast::Expr * build_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node ); 187 ast::Expr * build_keyword_cast( const CodeLocation &, ast::AggregateDecl::Aggregate target, ExpressionNode * expr_node ); 188 ast::Expr * build_virtual_cast( const CodeLocation &, DeclarationNode * decl_node, ExpressionNode * expr_node ); 189 ast::Expr * build_fieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member ); 190 ast::Expr * build_pfieldSel( const CodeLocation &, ExpressionNode * expr_node, ast::Expr * member ); 191 ast::Expr * build_offsetOf( const CodeLocation &, DeclarationNode * decl_node, ast::NameExpr * member ); 192 ast::Expr * build_and( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ); 193 ast::Expr * build_and_or( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ast::LogicalFlag flag ); 194 ast::Expr * build_unary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node ); 195 ast::Expr * build_binary_val( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ); 196 ast::Expr * build_binary_ptr( const CodeLocation &, OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ); 197 ast::Expr * build_cond( const CodeLocation &, ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 ); 198 ast::Expr * build_tuple( const CodeLocation &, ExpressionNode * expr_node = nullptr ); 199 ast::Expr * build_func( const CodeLocation &, ExpressionNode * function, ExpressionNode * expr_node ); 200 ast::Expr * build_compoundLiteral( const CodeLocation &, DeclarationNode * decl_node, InitializerNode * kids ); 198 201 199 202 //############################################################################## … … 219 222 static const char * builtinTypeNames[]; 220 223 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 ); 224 227 static DeclarationNode * newBasicType( BasicType ); 225 228 static DeclarationNode * newComplexType( ComplexType ); … … 232 235 static DeclarationNode * newQualifiedType( DeclarationNode *, DeclarationNode * ); 233 236 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 ); 235 238 static DeclarationNode * newEnum( const std::string * name, DeclarationNode * constants, bool body, bool typed, DeclarationNode * base = nullptr, EnumHiding hiding = EnumHiding::Visible ); 236 239 static DeclarationNode * newEnumConstant( const std::string * name, ExpressionNode * constant ); … … 239 242 static DeclarationNode * newName( const std::string * ); 240 243 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 * ); 242 245 static DeclarationNode * newTrait( const std::string * name, DeclarationNode * params, DeclarationNode * asserts ); 243 246 static DeclarationNode * newTraitUse( const std::string * name, ExpressionNode * params ); … … 253 256 static DeclarationNode * newDirectiveStmt( StatementNode * stmt ); // gcc external directive statement 254 257 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 ); 256 259 257 260 DeclarationNode(); … … 294 297 virtual void printList( __attribute__((unused)) std::ostream & os, __attribute__((unused)) int indent = 0 ) const override; 295 298 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; } 300 303 DeclarationNode * extractAggregate() const; 301 304 bool has_enumeratorValue() const { return (bool)enumeratorValue; } … … 312 315 struct Variable_t { 313 316 // const std::string * name; 314 TypeDecl::Kind tyClass;317 ast::TypeDecl::Kind tyClass; 315 318 DeclarationNode * assertions; 316 319 DeclarationNode * initializer; … … 320 323 struct StaticAssert_t { 321 324 ExpressionNode * condition; 322 Expression* message;325 ast::Expr * message; 323 326 }; 324 327 StaticAssert_t assert; … … 330 333 bool inLine = false; 331 334 bool enumInLine = false; 332 Type::FuncSpecifiers funcSpecs;333 Type::StorageClasses storageClasses;335 ast::Function::Specs funcSpecs; 336 ast::Storage::Classes storageClasses; 334 337 335 338 ExpressionNode * bitfieldWidth = nullptr; 336 339 std::unique_ptr<ExpressionNode> enumeratorValue; 337 340 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; 341 344 InitializerNode * initializer = nullptr; 342 345 bool extension = false; … … 348 351 }; // DeclarationNode 349 352 350 Type * buildType( TypeData * type );351 352 static inline Type * maybeMoveBuildType( const DeclarationNode * orig ) {353 Type * ret = orig ? orig->buildType() : nullptr;353 ast::Type * buildType( TypeData * type ); 354 355 static inline ast::Type * maybeMoveBuildType( const DeclarationNode * orig ) { 356 ast::Type * ret = orig ? orig->buildType() : nullptr; 354 357 delete orig; 355 358 return ret; … … 359 362 360 363 struct 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 ) {} 363 370 StatementNode( DeclarationNode * decl ); 364 371 virtual ~StatementNode() {} 365 372 366 373 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>>{} ); 371 384 delete attr; 372 385 delete name; … … 380 393 } 381 394 382 std::unique_ptr<Statement> stmt; 395 std::unique_ptr<ast::Stmt> stmt; 396 std::unique_ptr<ast::StmtClause> clause; 383 397 }; // StatementNode 384 398 385 Statement * build_expr(ExpressionNode * ctl );399 ast::Stmt * build_expr( CodeLocation const &, ExpressionNode * ctl ); 386 400 387 401 struct CondCtl { … … 402 416 }; 403 417 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 ) { 418 ast::Stmt * build_if( const CodeLocation &, CondCtl * ctl, StatementNode * then, StatementNode * else_ ); 419 ast::Stmt * build_switch( const CodeLocation &, bool isSwitch, ExpressionNode * ctl, StatementNode * stmt ); 420 ast::CaseClause * build_case( ExpressionNode * ctl ); 421 ast::CaseClause * build_default( const CodeLocation & ); 422 ast::Stmt * build_while( const CodeLocation &, CondCtl * ctl, StatementNode * stmt, StatementNode * else_ = nullptr ); 423 ast::Stmt * build_do_while( const CodeLocation &, ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ = nullptr ); 424 ast::Stmt * build_for( const CodeLocation &, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ = nullptr ); 425 ast::Stmt * build_branch( const CodeLocation &, ast::BranchStmt::Kind kind ); 426 ast::Stmt * build_branch( const CodeLocation &, std::string * identifier, ast::BranchStmt::Kind kind ); 427 ast::Stmt * build_computedgoto( ExpressionNode * ctl ); 428 ast::Stmt * build_return( const CodeLocation &, ExpressionNode * ctl ); 429 ast::Stmt * build_throw( const CodeLocation &, ExpressionNode * ctl ); 430 ast::Stmt * build_resume( const CodeLocation &, ExpressionNode * ctl ); 431 ast::Stmt * build_resume_at( ExpressionNode * ctl , ExpressionNode * target ); 432 ast::Stmt * build_try( const CodeLocation &, StatementNode * try_, StatementNode * catch_, StatementNode * finally_ ); 433 ast::CatchClause * build_catch( const CodeLocation &, ast::ExceptionKind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ); 434 ast::FinallyClause * build_finally( const CodeLocation &, StatementNode * stmt ); 435 ast::Stmt * build_compound( const CodeLocation &, StatementNode * first ); 436 StatementNode * maybe_build_compound( const CodeLocation &, StatementNode * first ); 437 ast::Stmt * build_asm( const CodeLocation &, bool voltile, ast::Expr * instruction, ExpressionNode * output = nullptr, ExpressionNode * input = nullptr, ExpressionNode * clobber = nullptr, LabelNode * gotolabels = nullptr ); 438 ast::Stmt * build_directive( const CodeLocation &, std::string * directive ); 439 ast::SuspendStmt * build_suspend( const CodeLocation &, StatementNode *, ast::SuspendStmt::Type ); 440 ast::WaitForStmt * build_waitfor( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ); 441 ast::WaitForStmt * build_waitfor_else( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, StatementNode * stmt ); 442 ast::WaitForStmt * build_waitfor_timeout( const CodeLocation &, ast::WaitForStmt * existing, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ); 443 ast::Stmt * build_with( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt ); 444 ast::Stmt * build_mutex( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt ); 445 446 //############################################################################## 447 448 template<typename AstType, typename NodeType, 449 template<typename, typename...> class Container, typename... Args> 450 void buildList( const NodeType * firstNode, 451 Container<ast::ptr<AstType>, Args...> & output ) { 437 452 SemanticErrorException errors; 438 std::back_insert_iterator< Container< SynTreeType *, Args... > > out( outputList );453 std::back_insert_iterator<Container<ast::ptr<AstType>, Args...>> out( output ); 439 454 const NodeType * cur = firstNode; 440 455 441 456 while ( cur ) { 442 457 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; 447 460 } else { 461 assertf(false, __PRETTY_FUNCTION__ ); 448 462 SemanticError( cur->location, "type specifier declaration in forall clause is currently unimplemented." ); 449 463 } // if … … 451 465 errors.append( e ); 452 466 } // 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 ) { 456 471 SemanticError( temp->location, "internal error, non-homogeneous nodes founds in buildList processing." ); 457 472 } // if … … 463 478 464 479 // 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 ); 480 void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Decl>> & outputList ); 481 void buildList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::DeclWithType>> & outputList ); 482 void buildTypeList( const DeclarationNode * firstNode, std::vector<ast::ptr<ast::Type>> & outputList ); 483 484 template<typename AstType, typename NodeType, 485 template<typename, typename...> class Container, typename... Args> 486 void buildMoveList( const NodeType * firstNode, 487 Container<ast::ptr<AstType>, Args...> & output ) { 488 buildList<AstType, NodeType, Container, Args...>( firstNode, output ); 472 489 delete firstNode; 473 490 } -
src/Parser/ParserTypes.h
rff71057 re02e13f 4 4 // The contents of this file are covered under the licence agreement in the 5 5 // file "LICENCE" distributed with Cforall. 6 // 7 // parser.hh -- 8 // 6 // 7 // parser.hh -- 8 // 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 22 08:58:10 2001 -
src/Parser/RunParser.cpp
rff71057 re02e13f 10 10 // Created On : Mon Dec 19 11:00:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Feb 16 10:08:00 202313 // Update Count : 212 // Last Modified On : Mon Mar 6 9:42:00 2023 13 // Update Count : 3 14 14 // 15 15 … … 46 46 47 47 ast::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 ); 51 50 delete parseTree; 52 51 parseTree = nullptr; 53 52 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 } 60 57 return transUnit; 61 58 } -
src/Parser/StatementNode.cc
rff71057 re02e13f 10 10 // Author : Rodolfo G. Esteves 11 11 // Created On : Sat May 16 14:59:41 2015 12 // Last Modified By : Peter A. Buhr13 // Last Modified On : Wed Mar 29 08:51:23202314 // Update Count : 4 5412 // Last Modified By : Andrew Beach 13 // Last Modified On : Tue Apr 4 11:40:00 2023 14 // Update Count : 427 15 15 // 16 16 17 17 #include <cassert> // for assert, strict_dynamic_cast, assertf 18 #include <list> // for list19 18 #include <memory> // for unique_ptr 20 19 #include <string> // for string 21 20 21 #include "AST/Label.hpp" // for Label 22 #include "AST/Stmt.hpp" // for Stmt, AsmStmt, BranchStmt, CaseCla... 22 23 #include "Common/SemanticError.h" // for SemanticError 23 24 #include "Common/utility.h" // for maybeMoveBuild, maybeBuild 24 25 #include "ParseNode.h" // for StatementNode, ExpressionNode, bui... 25 #include "SynTree/Expression.h" // for Expression, ConstantExpr26 #include "SynTree/Label.h" // for Label, noLabels27 #include "SynTree/Declaration.h"28 #include "SynTree/Statement.h" // for Statement, BranchStmt, CaseStmt29 26 #include "parserutility.h" // for notZeroExpr 30 27 … … 32 29 33 30 using namespace std; 34 35 31 36 32 StatementNode::StatementNode( DeclarationNode * decl ) { … … 38 34 DeclarationNode * agg = decl->extractAggregate(); 39 35 if ( agg ) { 40 StatementNode * nextStmt = new StatementNode( new DeclStmt( maybeBuild( decl ) ) ); 36 StatementNode * nextStmt = new StatementNode( 37 new ast::DeclStmt( decl->location, maybeBuild( decl ) ) ); 41 38 set_next( nextStmt ); 42 39 if ( decl->get_next() ) { … … 51 48 agg = decl; 52 49 } // 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 ) ) ); 54 53 } // StatementNode::StatementNode 55 54 … … 59 58 for ( StatementNode * curr = prev; curr != nullptr; curr = (StatementNode *)curr->get_next() ) { 60 59 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() ) ); 62 62 prev = curr; 63 63 } // for 64 64 // convert from StatementNode list to Statement list 65 65 StatementNode * node = dynamic_cast< StatementNode * >(prev); 66 list< Statement *> stmts;66 std::vector<ast::ptr<ast::Stmt>> stmts; 67 67 buildMoveList( stmt, stmts ); 68 68 // 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(); 71 74 return this; 72 75 } // StatementNode::append_last_case 73 76 74 Statement * build_expr( ExpressionNode * ctl ) { 75 Expression * e = maybeMoveBuild( ctl ); 76 77 if ( e ) return new ExprStmt( e ); 78 else return new NullStmt(); 77 ast::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 } 79 83 } // build_expr 80 84 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; 85 static 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; 87 93 if ( ctl->condition ) { 88 94 // compare the provided condition against 0 89 95 cond = notZeroExpr( maybeMoveBuild( ctl->condition ) ); 90 96 } else { 91 for ( Statement * stmt : init) {97 for ( ast::ptr<ast::Stmt> & stmt : inits ) { 92 98 // 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; 97 105 } 98 106 } … … 101 109 } // build_if_control 102 110 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 ); 111 ast::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 ); 110 117 assert( aststmt.size() == 1 ); 111 astthen = aststmt.front(); 112 118 ast::Stmt const * astthen = aststmt.front().release(); 119 120 ast::Stmt const * astelse = nullptr; 113 121 if ( else_ ) { 114 list< Statement *> aststmt;115 buildMoveList < Statement, StatementNode >( else_, aststmt );122 std::vector<ast::ptr<ast::Stmt>> aststmt; 123 buildMoveList( else_, aststmt ); 116 124 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 ); 121 131 } // build_if 122 132 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. 134 template<typename clause_t> 135 static 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 168 ast::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; 132 184 } // if 133 185 } // for 134 186 } // if 135 187 // 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 ) ); 137 190 } // build_switch 138 191 139 Statement * build_case( ExpressionNode * ctl ) { 140 return new CaseStmt( maybeMoveBuild( ctl ), {} ); // stmt starts empty and then added to 192 ast::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, {} ); 141 196 } // build_case 142 197 143 Statement * build_default() { 144 return new CaseStmt( nullptr, {}, true ); // stmt starts empty and then added to 198 ast::CaseClause * build_default( const CodeLocation & location ) { 199 // stmt starts empty and then added to 200 return new ast::CaseClause( location, nullptr, {} ); 145 201 } // build_default 146 202 147 Statement * build_while(CondCtl * ctl, StatementNode * stmt, StatementNode * else_ ) {148 list< Statement *> astinit; // maybe empty149 Expression* astcond = build_if_control( ctl, astinit ); // ctl deleted, cond/init set150 151 list< Statement *> aststmt; // loop body, compound created if empty152 buildMoveList < Statement, StatementNode >( stmt, aststmt );203 ast::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 ); 153 209 assert( aststmt.size() == 1 ); 154 210 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 ); 159 222 } // build_while 160 223 161 Statement * build_do_while(ExpressionNode * ctl, StatementNode * stmt, StatementNode * else_ ) {162 list< Statement *> aststmt; // loop body, compound created if empty163 buildMoveList < Statement, StatementNode >( stmt, aststmt );224 ast::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 ); 164 227 assert( aststmt.size() == 1 ); // compound created if empty 165 228 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 ); 168 232 169 233 // 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 ); 171 241 } // build_do_while 172 242 173 Statement * build_for(ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) {174 list< Statement *> astinit; // maybe empty243 ast::Stmt * build_for( const CodeLocation & location, ForCtrl * forctl, StatementNode * stmt, StatementNode * else_ ) { 244 std::vector<ast::ptr<ast::Stmt>> astinit; // maybe empty 175 245 buildMoveList( forctl->init, astinit ); 176 246 177 Expression* astcond = nullptr; // maybe empty247 ast::Expr * astcond = nullptr; // maybe empty 178 248 astcond = notZeroExpr( maybeMoveBuild( forctl->condition ) ); 179 249 180 Expression* astincr = nullptr; // maybe empty250 ast::Expr * astincr = nullptr; // maybe empty 181 251 astincr = maybeMoveBuild( forctl->change ); 182 252 delete forctl; 183 253 184 list< Statement *> aststmt; // loop body, compound created if empty185 buildMoveList < Statement, StatementNode >( stmt, aststmt );254 std::vector<ast::ptr<ast::Stmt>> aststmt; // loop body, compound created if empty 255 buildMoveList( stmt, aststmt ); 186 256 assert( aststmt.size() == 1 ); 187 257 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 ); 192 269 } // build_for 193 270 194 Statement * build_branch( BranchStmt::Type kind ) { 195 Statement * ret = new BranchStmt( "", kind ); 271 ast::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 278 ast::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 196 284 return ret; 197 285 } // build_branch 198 286 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 ); 287 ast::Stmt * build_computedgoto( ExpressionNode * ctl ) { 288 ast::Expr * expr = maybeMoveBuild( ctl ); 289 return new ast::BranchStmt( expr->location, expr ); 207 290 } // build_computedgoto 208 291 209 Statement * build_return(ExpressionNode * ctl ) {210 list< Expression *> exps;292 ast::Stmt * build_return( const CodeLocation & location, ExpressionNode * ctl ) { 293 std::vector<ast::ptr<ast::Expr>> exps; 211 294 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 ); 213 298 } // build_return 214 299 215 Statement * build_throw( ExpressionNode * ctl ) { 216 list< Expression * > exps; 300 static ast::Stmt * build_throw_stmt( 301 const CodeLocation & location, 302 ExpressionNode * ctl, 303 ast::ExceptionKind kind ) { 304 std::vector<ast::ptr<ast::Expr>> exps; 217 305 buildMoveList( ctl, exps ); 218 306 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 314 ast::Stmt * build_throw( const CodeLocation & loc, ExpressionNode * ctl ) { 315 return build_throw_stmt( loc, ctl, ast::Terminate ); 220 316 } // build_throw 221 317 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 ); 318 ast::Stmt * build_resume( const CodeLocation & loc, ExpressionNode * ctl ) { 319 return build_throw_stmt( loc, ctl, ast::Resume ); 227 320 } // build_resume 228 321 229 Statement * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) {322 ast::Stmt * build_resume_at( ExpressionNode * ctl, ExpressionNode * target ) { 230 323 (void)ctl; 231 324 (void)target; … … 233 326 } // build_resume_at 234 327 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 ); 328 ast::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 ); 241 341 } // build_try 242 342 243 Statement * build_catch( CatchStmt::Kind kind, DeclarationNode * decl, ExpressionNode * cond, StatementNode * body ) {244 list< Statement *> aststmt;245 buildMoveList < Statement, StatementNode >( body, aststmt );343 ast::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 ); 246 346 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 ); 248 353 } // build_catch 249 354 250 Statement * build_finally(StatementNode * stmt ) {251 list< Statement *> aststmt;252 buildMoveList < Statement, StatementNode >( stmt, aststmt );355 ast::FinallyClause * build_finally( const CodeLocation & location, StatementNode * stmt ) { 356 std::vector<ast::ptr<ast::Stmt>> aststmt; 357 buildMoveList( stmt, aststmt ); 253 358 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 ); 255 362 } // build_finally 256 363 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 ); 364 ast::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; 264 368 if(!stmts.empty()) { 265 369 assert( stmts.size() == 1 ); 266 node->then = dynamic_cast< CompoundStmt * >( stmts.front());370 then2 = stmts.front().strict_as<ast::CompoundStmt>(); 267 371 } 268 372 auto node = new ast::SuspendStmt( location, then2, ast::SuspendStmt::None ); 373 node->type = type; 269 374 return node; 270 375 } // build_suspend 271 376 272 WaitForStmt * build_waitfor( WaitForStmt * existing, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) { 273 WaitForStmt::Target target; 274 target.function = maybeBuild( targetExpr ); 377 ast::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 ) ); 275 382 276 383 ExpressionNode * next = dynamic_cast<ExpressionNode *>( targetExpr->get_next() ); 277 384 targetExpr->set_next( nullptr ); 278 buildMoveList < Expression >( next, target.arguments );385 buildMoveList( next, clause->target_args ); 279 386 280 387 delete targetExpr; 281 388 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 ); 287 390 288 391 return existing; 289 392 } // build_waitfor 290 393 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 394 ast::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; 295 399 return existing; 296 400 } // build_waitfor_else 297 401 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 402 ast::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; 303 408 return existing; 304 409 } // build_waitfor_timeout 305 410 306 Statement * build_with(ExpressionNode * exprs, StatementNode * stmt ) {307 list< Expression *> e;411 ast::Stmt * build_with( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) { 412 std::vector<ast::ptr<ast::Expr>> e; 308 413 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 ) ); 311 416 } // build_with 312 417 313 Statement * build_compound(StatementNode * first ) {314 CompoundStmt * cs = new CompoundStmt();315 buildMoveList( first, cs-> get_kids());418 ast::Stmt * build_compound( const CodeLocation & location, StatementNode * first ) { 419 auto cs = new ast::CompoundStmt( location ); 420 buildMoveList( first, cs->kids ); 316 421 return cs; 317 422 } // build_compound … … 321 426 // statement and wrap it into a compound statement to insert additional code. Hence, all control structures have a 322 427 // conical form for code generation. 323 StatementNode * maybe_build_compound( StatementNode * first ) {428 StatementNode * maybe_build_compound( const CodeLocation & location, StatementNode * first ) { 324 429 // Optimization: if the control-structure statement is a compound statement, do not wrap it. 325 430 // 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 ) ); 330 433 } // if 331 434 return first; … … 333 436 334 437 // 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;438 ast::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; 338 441 339 442 buildMoveList( output, out ); 340 443 buildMoveList( input, in ); 341 444 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 ); 343 453 } // build_asm 344 454 345 Statement * build_directive( string * directive ) { 346 return new DirectiveStmt( *directive ); 455 ast::Stmt * build_directive( const CodeLocation & location, string * directive ) { 456 auto stmt = new ast::DirectiveStmt( location, *directive ); 457 delete directive; 458 return stmt; 347 459 } // build_directive 348 460 349 Statement * build_mutex(ExpressionNode * exprs, StatementNode * stmt ) {350 list< Expression *> expList;461 ast::Stmt * build_mutex( const CodeLocation & location, ExpressionNode * exprs, StatementNode * stmt ) { 462 std::vector<ast::ptr<ast::Expr>> expList; 351 463 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 ) ); 354 466 } // build_mutex 355 467 -
src/Parser/TypeData.cc
rff71057 re02e13f 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 15:12:51 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sun Feb 19 11:00:46202313 // Update Count : 6 7911 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Apr 4 13:39:00 2023 13 // Update Count : 680 14 14 // 15 16 #include "TypeData.h" 15 17 16 18 #include <cassert> // for assert 17 19 #include <ostream> // for operator<<, ostream, basic_ostream 18 20 21 #include "AST/Decl.hpp" // for AggregateDecl, ObjectDecl, TypeDe... 22 #include "AST/Init.hpp" // for SingleInit, ListInit 23 #include "AST/Print.hpp" // for print 19 24 #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... 21 27 #include "Parser/ParseNode.h" // for DeclarationNode, ExpressionNode 22 #include "SynTree/Declaration.h" // for TypeDecl, ObjectDecl, FunctionDecl23 #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, Statement26 #include "SynTree/Type.h" // for BasicType, Type, Type::ForallList27 #include "TypeData.h"28 28 29 29 class Attribute; … … 60 60 break; 61 61 case Aggregate: 62 aggregate.kind = AggregateDecl::NoAggregate;62 aggregate.kind = ast::AggregateDecl::NoAggregate; 63 63 aggregate.name = nullptr; 64 64 aggregate.params = nullptr; … … 89 89 typeexpr = nullptr; 90 90 break; 91 case Vtable: 91 92 case Builtin: 92 case Vtable:93 93 // No unique data to initialize. 94 94 break; … … 111 111 case EnumConstant: 112 112 case GlobalScope: 113 case Basic: 113 114 // No unique data to deconstruct. 114 break;115 case Basic:116 115 break; 117 116 case Array: … … 250 249 251 250 void 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 ); 255 252 256 253 if ( forall ) { … … 325 322 break; 326 323 case Aggregate: 327 os << AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl;324 os << ast::AggregateDecl::aggrString( aggregate.kind ) << ' ' << *aggregate.name << endl; 328 325 if ( aggregate.params ) { 329 326 os << string( indent + 2, ' ' ) << "with type parameters" << endl; … … 472 469 473 470 474 template< typename ForallList > 475 void buildForall( const DeclarationNode * firstNode, ForallList &outputList ) { 476 buildList( firstNode, outputList ); 471 void 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 } 477 483 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 624 void 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 ); 505 769 } // for 506 770 } // buildForall 507 771 508 772 509 Type * typebuild( const TypeData * td ) {773 ast::Type * typebuild( const TypeData * td ) { 510 774 assert( td ); 511 775 switch ( td->kind ) { 512 776 case TypeData::Unknown: 513 777 // 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 ); 515 782 case TypeData::Basic: 516 783 return buildBasicType( td ); … … 522 789 return buildReference( td ); 523 790 case TypeData::Function: 524 return buildFunction ( td );791 return buildFunctionType( td ); 525 792 case TypeData::AggregateInst: 526 793 return buildAggInst( td ); 527 794 case TypeData::EnumConstant: 528 return new EnumInstType( buildQualifiers( td ), "");795 return new ast::EnumInstType( "", buildQualifiers( td ) ); 529 796 case TypeData::SymbolicInst: 530 797 return buildSymbolicInst( td ); … … 539 806 switch ( td->builtintype ) { 540 807 case DeclarationNode::Zero: 541 return new ZeroType( noQualifiers);808 return new ast::ZeroType(); 542 809 case DeclarationNode::One: 543 return new OneType( noQualifiers);810 return new ast::OneType(); 544 811 default: 545 return new VarArgsType( buildQualifiers( td ) );812 return new ast::VarArgsType( buildQualifiers( td ) ); 546 813 } // switch 547 814 case TypeData::GlobalScope: 548 return new GlobalScopeType();815 return new ast::GlobalScopeType(); 549 816 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 ); 551 822 case TypeData::Symbolic: 552 823 case TypeData::Enum: … … 587 858 588 859 589 Type::Qualifiers buildQualifiers( const TypeData * td ) {860 ast::CV::Qualifiers buildQualifiers( const TypeData * td ) { 590 861 return td->qualifiers; 591 862 } // buildQualifiers … … 596 867 } // genTSError 597 868 598 Type * buildBasicType( const TypeData * td ) {599 BasicType::Kind ret;869 ast::Type * buildBasicType( const TypeData * td ) { 870 ast::BasicType::Kind ret; 600 871 601 872 switch ( td->basictype ) { … … 607 878 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); 608 879 } // if 609 return new VoidType( buildQualifiers( td ) );880 return new ast::VoidType( buildQualifiers( td ) ); 610 881 break; 611 882 … … 618 889 } // if 619 890 620 ret = BasicType::Bool;891 ret = ast::BasicType::Bool; 621 892 break; 622 893 … … 625 896 // character types. The implementation shall define char to have the same range, representation, and behavior as 626 897 // 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 }; 628 899 629 900 if ( td->length != DeclarationNode::NoLength ) { … … 635 906 636 907 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 }, 640 911 }; 641 912 … … 648 919 649 920 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; 651 922 if ( td->length != DeclarationNode::NoLength ) { 652 923 genTSError( DeclarationNode::lengthNames[ td->length ], td->basictype ); … … 666 937 case DeclarationNode::uFloat128: 667 938 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, }, 671 942 }; 672 943 … … 709 980 } // switch 710 981 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 ) ); 713 983 return bt; 714 984 } // buildBasicType 715 985 716 986 717 PointerType * buildPointer( const TypeData * td ) {718 PointerType * pt;987 ast::PointerType * buildPointer( const TypeData * td ) { 988 ast::PointerType * pt; 719 989 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 ); 721 994 } 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 ); 723 999 } // if 724 buildForall( td->forall, pt->get_forall() );725 1000 return pt; 726 1001 } // buildPointer 727 1002 728 1003 729 ArrayType * buildArray( const TypeData * td ) {730 ArrayType * at;1004 ast::ArrayType * buildArray( const TypeData * td ) { 1005 ast::ArrayType * at; 731 1006 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 ); 734 1014 } 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 ); 737 1022 } // if 738 buildForall( td->forall, at->get_forall() );739 1023 return at; 740 1024 } // buildArray 741 1025 742 1026 743 ReferenceType * buildReference( const TypeData * td ) {744 ReferenceType * rt;1027 ast::ReferenceType * buildReference( const TypeData * td ) { 1028 ast::ReferenceType * rt; 745 1029 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 ); 747 1034 } 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 ); 749 1039 } // if 750 buildForall( td->forall, rt->get_forall() );751 1040 return rt; 752 1041 } // buildReference 753 1042 754 1043 755 AggregateDecl * buildAggregate( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) {1044 ast::AggregateDecl * buildAggregate( const TypeData * td, std::vector<ast::ptr<ast::Attribute>> attributes, ast::Linkage::Spec linkage ) { 756 1045 assert( td->kind == TypeData::Aggregate ); 757 AggregateDecl * at;1046 ast::AggregateDecl * at; 758 1047 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 ); 775 1077 break; 776 1078 default: … … 778 1080 } // switch 779 1081 780 buildList( td->aggregate.fields, at-> get_members());1082 buildList( td->aggregate.fields, at->members ); 781 1083 at->set_body( td->aggregate.body ); 782 1084 … … 785 1087 786 1088 787 ReferenceToType * buildComAggInst( const TypeData * type, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { 1089 ast::BaseInstType * buildComAggInst( 1090 const TypeData * type, 1091 std::vector<ast::ptr<ast::Attribute>> && attributes, 1092 ast::Linkage::Spec linkage ) { 788 1093 switch ( type->kind ) { 789 1094 case TypeData::Enum: 790 1095 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 ); 793 1102 } 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; 796 1109 case TypeData::Aggregate: 797 1110 if ( type->aggregate.body ) { 798 AggregateDecl * typedecl = buildAggregate( type, attributes, linkage ); 1111 ast::AggregateDecl * typedecl = 1112 buildAggregate( type, std::move( attributes ), linkage ); 799 1113 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: 808 1128 assert( false ); 809 //return new TraitInstType( buildQualifiers( type ), (TraitDecl *)typedecl );810 1129 break; 811 1130 default: … … 814 1133 } else { 815 1134 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 ); 825 1153 default: 826 1154 assert( false ); 827 1155 } // switch 828 } // if 829 return nullptr; 1156 break; 1157 } // if 1158 break; 830 1159 default: 831 1160 assert( false ); 832 1161 } // switch 1162 assert( false ); 833 1163 } // buildAggInst 834 1164 835 1165 836 ReferenceToType * buildAggInst( const TypeData * td ) {1166 ast::BaseInstType * buildAggInst( const TypeData * td ) { 837 1167 assert( td->kind == TypeData::AggregateInst ); 838 1168 839 // ReferenceToType * ret = buildComAggInst( td->aggInst.aggregate, std::list< Attribute * >() ); 840 ReferenceToType * ret = nullptr; 1169 ast::BaseInstType * ret = nullptr; 841 1170 TypeData * type = td->aggInst.aggregate; 842 1171 switch ( type->kind ) { 843 1172 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 ); 845 1177 case TypeData::Aggregate: 846 1178 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 ); 852 1187 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 ); 855 1193 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 ); 858 1199 break; 859 1200 default: … … 865 1206 } // switch 866 1207 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 ); 870 1210 return ret; 871 1211 } // buildAggInst 872 1212 873 1213 874 NamedTypeDecl * buildSymbolic( const TypeData * td, std::list< Attribute * > attributes, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) { 1214 ast::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 ) { 875 1220 assert( td->kind == TypeData::Symbolic ); 876 NamedTypeDecl * ret;1221 ast::NamedTypeDecl * ret; 877 1222 assert( td->base ); 878 1223 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 ); 880 1231 } 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 ); 882 1240 } // 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 ); 885 1243 return ret; 886 1244 } // buildSymbolic 887 1245 888 1246 889 EnumDecl * buildEnum( const TypeData * td, std::list< Attribute * > attributes, LinkageSpec::Spec linkage ) { 1247 ast::EnumDecl * buildEnum( 1248 const TypeData * td, 1249 std::vector<ast::ptr<ast::Attribute>> && attributes, 1250 ast::Linkage::Spec linkage ) { 890 1251 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; 896 1264 for ( const DeclarationNode * cur = td->enumeration.constants; cur != nullptr; cur = dynamic_cast< DeclarationNode * >( cur->get_next() ), ++members ) { 897 1265 if ( cur->enumInLine ) { … … 900 1268 SemanticError( td->location, "Enumerator of enum(void) cannot have an explicit initializer value." ); 901 1269 } 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 ); 904 1277 } 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())) { 906 1279 SemanticError( td->location, "Enumerators of an non-integer typed enum must be explicitly initialized." ); 907 1280 } … … 910 1283 // if 911 1284 } // for 912 ret-> set_body( td->enumeration.body );1285 ret->body = td->enumeration.body; 913 1286 return ret; 914 1287 } // buildEnum 915 1288 916 1289 917 TypeInstType * buildSymbolicInst( const TypeData * td ) {1290 ast::TypeInstType * buildSymbolicInst( const TypeData * td ) { 918 1291 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 ); 922 1298 return ret; 923 1299 } // buildSymbolicInst 924 1300 925 1301 926 TupleType * buildTuple( const TypeData * td ) {1302 ast::TupleType * buildTuple( const TypeData * td ) { 927 1303 assert( td->kind == TypeData::Tuple ); 928 std:: list< Type *> types;1304 std::vector<ast::ptr<ast::Type>> types; 929 1305 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 ); 932 1310 return ret; 933 1311 } // buildTuple 934 1312 935 1313 936 TypeofType * buildTypeof( const TypeData * td ) {1314 ast::TypeofType * buildTypeof( const TypeData * td ) { 937 1315 assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof ); 938 1316 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 ); 941 1323 } // buildTypeof 942 1324 943 1325 944 VTableType * buildVtable( const TypeData * td ) {1326 ast::VTableType * buildVtable( const TypeData * td ) { 945 1327 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 ); 947 1332 } // buildVtable 948 1333 949 1334 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 ) { 1335 ast::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 1409 ast::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 ) { 951 1419 if ( td->kind == TypeData::Function ) { 952 1420 if ( td->function.idList ) { // KR function ? … … 954 1422 } // if 955 1423 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 ) ); 962 1427 } else if ( td->kind == TypeData::Aggregate ) { 963 return buildAggregate( td, attributes, linkage );1428 return buildAggregate( td, std::move( attributes ), linkage ); 964 1429 } else if ( td->kind == TypeData::Enum ) { 965 return buildEnum( td, attributes, linkage );1430 return buildEnum( td, std::move( attributes ), linkage ); 966 1431 } else if ( td->kind == TypeData::Symbolic ) { 967 return buildSymbolic( td, attributes, name, scs, linkage );1432 return buildSymbolic( td, std::move( attributes ), name, scs, linkage ); 968 1433 } 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; 970 1445 } // if 971 1446 return nullptr; … … 973 1448 974 1449 975 FunctionType * buildFunction( const TypeData * td ) {1450 ast::FunctionType * buildFunctionType( const TypeData * td ) { 976 1451 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 ); 979 1458 buildForall( td->forall, ft->forall ); 980 1459 if ( td->base ) { 981 1460 switch ( td->base->kind ) { 982 1461 case TypeData::Tuple: 983 build List( td->base->tuple, ft->returnVals );1462 buildTypeList( td->base->tuple, ft->returns ); 984 1463 break; 985 1464 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; 987 1467 } // switch 988 1468 } 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 ) ); 990 1471 } // if 991 1472 return ft; 992 } // buildFunction 1473 } // buildFunctionType 993 1474 994 1475 … … 1021 1502 param->type = decl->type; // set copy declaration type to parameter type 1022 1503 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 ); 1024 1506 } // if 1025 1507 } // for -
src/Parser/TypeData.h
rff71057 re02e13f 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat May 16 15:18:36 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Fri Feb 24 14:25:02202313 // Update Count : 20 511 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Mar 1 10:44:00 2023 13 // Update Count : 206 14 14 // 15 15 … … 20 20 #include <string> // for string 21 21 22 #include "AST/Type.hpp" // for Type 22 23 #include "ParseNode.h" // for DeclarationNode, DeclarationNode::Ag... 23 #include "SynTree/LinkageSpec.h" // for Spec24 #include "SynTree/Type.h" // for Type, ReferenceToType (ptr only)25 #include "SynTree/SynTree.h" // for Visitor Nodes26 24 27 25 struct TypeData { … … 30 28 31 29 struct Aggregate_t { 32 AggregateDecl::Aggregate kind;30 ast::AggregateDecl::Aggregate kind; 33 31 const std::string * name = nullptr; 34 32 DeclarationNode * params = nullptr; … … 41 39 }; 42 40 43 struct AggInst_t { // handles SUE41 struct AggInst_t { 44 42 TypeData * aggregate = nullptr; 45 43 ExpressionNode * params = nullptr; … … 93 91 DeclarationNode::BuiltinType builtintype = DeclarationNode::NoBuiltinType; 94 92 95 Type::Qualifiers qualifiers;93 ast::CV::Qualifiers qualifiers; 96 94 DeclarationNode * forall = nullptr; 97 95 … … 114 112 }; 115 113 116 Type * typebuild( const TypeData * );114 ast::Type * typebuild( const TypeData * ); 117 115 TypeData * 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 * );116 ast::CV::Qualifiers buildQualifiers( const TypeData * td ); 117 ast::Type * buildBasicType( const TypeData * ); 118 ast::PointerType * buildPointer( const TypeData * ); 119 ast::ArrayType * buildArray( const TypeData * ); 120 ast::ReferenceType * buildReference( const TypeData * ); 121 ast::AggregateDecl * buildAggregate( const TypeData *, std::vector<ast::ptr<ast::Attribute>> ); 122 ast::BaseInstType * buildComAggInst( const TypeData *, std::vector<ast::ptr<ast::Attribute>> && attributes, ast::Linkage::Spec linkage ); 123 ast::BaseInstType * buildAggInst( const TypeData * ); 124 ast::TypeDecl * buildVariable( const TypeData * ); 125 ast::EnumDecl * buildEnum( const TypeData *, std::vector<ast::ptr<ast::Attribute>> &&, ast::Linkage::Spec ); 126 ast::TypeInstType * buildSymbolicInst( const TypeData * ); 127 ast::TupleType * buildTuple( const TypeData * ); 128 ast::TypeofType * buildTypeof( const TypeData * ); 129 ast::VTableType * buildVtable( const TypeData * ); 130 ast::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>>() ); 134 ast::FunctionType * buildFunctionType( const TypeData * ); 135 ast::Decl * addEnumBase( Declaration *, const TypeData * ); 138 136 void buildKRFunction( const TypeData::Function_t & function ); 139 137 -
src/Parser/lex.ll
rff71057 re02e13f 23 23 // line-number directives) and C/C++ style comments, which are ignored. 24 24 25 // **************************** Includes and Defines ****************************25 // *************************** Includes and Defines **************************** 26 26 27 27 #ifdef __clang__ -
src/Parser/parser.yy
rff71057 re02e13f 9 9 // Author : Peter A. Buhr 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T hu Mar 30 21:28:25202313 // Update Count : 632 811 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Apr 4 14:02:00 2023 13 // Update Count : 6329 14 14 // 15 15 … … 64 64 65 65 extern DeclarationNode * parseTree; 66 extern LinkageSpec::Spec linkage;66 extern ast::Linkage::Spec linkage; 67 67 extern TypedefTable typedefTable; 68 68 69 stack< LinkageSpec::Spec> linkageStack;69 stack<ast::Linkage::Spec> linkageStack; 70 70 71 71 bool appendStr( string & to, string & from ) { … … 200 200 } // fieldDecl 201 201 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" ) ) ) 204 204 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right) 205 205 #define MISSING_ANON_FIELD "Missing loop fields with an anonymous loop index is meaningless as loop index is unavailable in loop body." … … 208 208 209 209 static ForCtrl * makeForCtrl( 210 const CodeLocation & location, 210 211 DeclarationNode * init, 211 212 enum OperKinds compop, … … 213 214 ExpressionNode * inc ) { 214 215 // 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, 216 217 compop, 217 new ExpressionNode( build_varref( new string( *init->name ) ) ),218 new ExpressionNode( build_varref( location, new string( *init->name ) ) ), 218 219 comp ) ); 219 if ( inc ) inc = new ExpressionNode( build_binary_val( 220 if ( inc ) inc = new ExpressionNode( build_binary_val( location, 220 221 // choose += or -= for upto/downto 221 222 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 ) ) ), 223 224 inc ) ); 224 225 // The StatementNode call frees init->name, it must happen later. … … 226 227 } 227 228 228 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {229 ForCtrl * forCtrl( const CodeLocation & location, DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 229 230 if ( index->initializer ) { 230 231 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." ); … … 234 235 } // if 235 236 DeclarationNode * initDecl = index->addInitializer( new InitializerNode( start ) ); 236 return makeForCtrl( initDecl, compop, comp, inc );237 return makeForCtrl( location, initDecl, compop, comp, inc ); 237 238 } // forCtrl 238 239 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 ) ) );240 ForCtrl * 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 ) ) ); 243 244 } // if 244 245 DeclarationNode * initDecl = distAttr( … … 246 247 DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) 247 248 ); 248 return makeForCtrl( initDecl, compop, comp, inc );249 return makeForCtrl( location, initDecl, compop, comp, inc ); 249 250 } // forCtrl 250 251 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 );252 ForCtrl * 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 ); 257 258 } else { 258 259 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed." ); return nullptr; … … 299 300 ExpressionNode * en; 300 301 DeclarationNode * decl; 301 AggregateDecl::Aggregate aggKey;302 TypeDecl::Kind tclass;302 ast::AggregateDecl::Aggregate aggKey; 303 ast::TypeDecl::Kind tclass; 303 304 StatementNode * sn; 304 WaitForStmt * wfs;305 Expression* constant;305 ast::WaitForStmt * wfs; 306 ast::Expr * constant; 306 307 CondCtl * ifctl; 307 308 ForCtrl * fctl; … … 313 314 bool flag; 314 315 EnumHiding hide; 315 CatchStmt::Kind catch_kind;316 GenericExpr * genexpr;316 ast::ExceptionKind catch_kind; 317 ast::GenericExpr * genexpr; 317 318 } 318 319 319 // ************************* TERMINAL TOKENS ********************************320 // ************************ TERMINAL TOKENS ******************************** 320 321 321 322 // keywords … … 611 612 constant: 612 613 // 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 ) ); } 618 619 ; 619 620 … … 641 642 642 643 string_literal: 643 string_literal_list { $$ = build_constantStr( *$1 ); }644 string_literal_list { $$ = build_constantStr( yylloc, *$1 ); } 644 645 ; 645 646 … … 658 659 primary_expression: 659 660 IDENTIFIER // typedef name cannot be used as a variable name 660 { $$ = new ExpressionNode( build_varref( $1 ) ); }661 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); } 661 662 | quasi_keyword 662 { $$ = new ExpressionNode( build_varref( $1 ) ); }663 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); } 663 664 | TYPEDIMname // CFA, generic length argument 664 665 // { $$ = new ExpressionNode( new TypeExpr( maybeMoveBuildType( DeclarationNode::newFromTypedef( $1 ) ) ) ); } 665 666 // { $$ = new ExpressionNode( build_varref( $1 ) ); } 666 { $$ = new ExpressionNode( build_dimensionref( $1 ) ); }667 { $$ = new ExpressionNode( build_dimensionref( yylloc, $1 ) ); } 667 668 | tuple 668 669 | '(' comma_expression ')' 669 670 { $$ = $2; } 670 671 | '(' 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 ) ) ) ); } 672 673 | 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 ) ) ); } 674 675 | type_name '.' '[' field_name_list ']' // CFA, nested type / tuple field selector 675 676 { SemanticError( yylloc, "Qualified name is currently unimplemented." ); $$ = nullptr; } … … 703 704 { 704 705 // 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() ); 706 708 delete $3; 707 709 $$ = $1; … … 713 715 { 714 716 // 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 ) } } ); 716 718 } 717 719 | DEFAULT ':' assignment_expression 718 { $$ = new GenericExpr(nullptr, { { maybeMoveBuild( $3 ) } } ); }720 { $$ = new ast::GenericExpr( yylloc, nullptr, { { maybeMoveBuild( $3 ) } } ); } 719 721 ; 720 722 … … 725 727 // Switching to this behaviour may help check if a C compatibilty case uses comma-exprs in subscripts. 726 728 // 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 ) ) )) ) ); } 728 730 | postfix_expression '[' assignment_expression ']' 729 731 // CFA, comma_expression disallowed in this context because it results in a common user error: subscripting a … … 731 733 // little advantage to this feature and many disadvantages. It is possible to write x[(i,j)] in CFA, which is 732 734 // 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 ) ); } 734 736 | 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 ) ); } 736 738 | 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 ) ); } 738 740 | postfix_expression '{' argument_expression_list_opt '}' // CFA, constructor call 739 741 { 740 742 Token fn; 741 743 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 ) ) ) ); 743 745 } 744 746 | postfix_expression '(' argument_expression_list_opt ')' 745 { $$ = new ExpressionNode( build_func( $1, $3 ) ); }747 { $$ = new ExpressionNode( build_func( yylloc, $1, $3 ) ); } 746 748 | VA_ARG '(' primary_expression ',' declaration_specifier_nobody abstract_parameter_declarator_opt ')' 747 749 // { 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") ) ), 749 751 (ExpressionNode *)($3->set_last( (ExpressionNode *)($6 ? $6->addType( $5 ) : $5) )) ) ); } 750 752 | 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 ) ); } 752 754 | 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 ) ); } 754 756 | 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 ) ) ); } 756 758 | postfix_expression '.' identifier 757 { $$ = new ExpressionNode( build_fieldSel( $1, build_varref($3 ) ) ); }759 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); } 758 760 | 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 ) ) ); } 760 762 | 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 ) ) ); } 762 764 | 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 ) ) ); } 764 766 | postfix_expression '.' aggregate_control 765 { $$ = new ExpressionNode( build_keyword_cast( $3, $1 ) ); }767 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $3, $1 ) ); } 766 768 | postfix_expression ARROW identifier 767 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref($3 ) ) ); }769 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, build_varref( yylloc, $3 ) ) ); } 768 770 | 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 ) ) ); } 770 772 | 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 ) ) ); } 772 774 | postfix_expression ICR 773 { $$ = new ExpressionNode( build_unary_val( OperKinds::IncrPost, $1 ) ); }775 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::IncrPost, $1 ) ); } 774 776 | postfix_expression DECR 775 { $$ = new ExpressionNode( build_unary_val( OperKinds::DecrPost, $1 ) ); }777 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::DecrPost, $1 ) ); } 776 778 | '(' 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 ) ) ); } 778 780 | '(' 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 ) ) ); } 780 782 | '^' primary_expression '{' argument_expression_list_opt '}' // CFA, destructor call 781 783 { 782 784 Token fn; 783 785 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 ) ) ); 785 787 } 786 788 ; … … 813 815 field_name 814 816 | 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 ) ) ); } 816 818 | 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 ) ) ); } 818 820 | field_name '.' field 819 { $$ = new ExpressionNode( build_fieldSel( $1, maybeMoveBuild( $3 ) ) ); }821 { $$ = new ExpressionNode( build_fieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); } 820 822 | 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 ) ) ); } 822 824 | field_name ARROW field 823 { $$ = new ExpressionNode( build_pfieldSel( $1, maybeMoveBuild( $3 ) ) ); }825 { $$ = new ExpressionNode( build_pfieldSel( yylloc, $1, maybeMoveBuild( $3 ) ) ); } 824 826 | 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 ) ) ); } 826 828 ; 827 829 828 830 field_name: 829 831 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 ) ); } 831 833 | 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 ) ); } 833 835 | identifier_at fraction_constants_opt // CFA, allow anonymous fields 834 836 { 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 ) ); 836 838 } 837 839 ; … … 842 844 | fraction_constants_opt FLOATING_FRACTIONconstant 843 845 { 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 ); 846 848 } 847 849 ; … … 862 864 { 863 865 switch ( $1 ) { 864 865 $$ = new ExpressionNode( new AddressExpr( maybeMoveBuild( $2 ) ) );866 case OperKinds::AddressOf: 867 $$ = new ExpressionNode( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ); 866 868 break; 867 868 $$ = new ExpressionNode( build_unary_val( $1, $2 ) );869 case OperKinds::PointTo: 870 $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); 869 871 break; 870 871 $$ = new ExpressionNode( new AddressExpr( newAddressExpr( maybeMoveBuild( $2 ) ) ) );872 case OperKinds::And: 873 $$ = new ExpressionNode( new ast::AddressExpr( new ast::AddressExpr( maybeMoveBuild( $2 ) ) ) ); 872 874 break; 873 875 default: 874 876 assert( false ); 875 877 } 876 878 } 877 879 | unary_operator cast_expression 878 { $$ = new ExpressionNode( build_unary_val( $1, $2 ) ); }880 { $$ = new ExpressionNode( build_unary_val( yylloc, $1, $2 ) ); } 879 881 | ICR unary_expression 880 { $$ = new ExpressionNode( build_unary_val( OperKinds::Incr, $2 ) ); }882 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Incr, $2 ) ); } 881 883 | DECR unary_expression 882 { $$ = new ExpressionNode( build_unary_val( OperKinds::Decr, $2 ) ); }884 { $$ = new ExpressionNode( build_unary_val( yylloc, OperKinds::Decr, $2 ) ); } 883 885 | SIZEOF unary_expression 884 { $$ = new ExpressionNode( new SizeofExpr(maybeMoveBuild( $2 ) ) ); }886 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuild( $2 ) ) ); } 885 887 | SIZEOF '(' type_no_function ')' 886 { $$ = new ExpressionNode( new SizeofExpr(maybeMoveBuildType( $3 ) ) ); }888 { $$ = new ExpressionNode( new ast::SizeofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); } 887 889 | ALIGNOF unary_expression // GCC, variable alignment 888 { $$ = new ExpressionNode( new AlignofExpr(maybeMoveBuild( $2 ) ) ); }890 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuild( $2 ) ) ); } 889 891 | ALIGNOF '(' type_no_function ')' // GCC, type alignment 890 { $$ = new ExpressionNode( new AlignofExpr(maybeMoveBuildType( $3 ) ) ); }892 { $$ = new ExpressionNode( new ast::AlignofExpr( yylloc, maybeMoveBuildType( $3 ) ) ); } 891 893 | 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 ) ) ); } 893 895 | TYPEID '(' type_no_function ')' 894 896 { … … 915 917 unary_expression 916 918 | '(' type_no_function ')' cast_expression 917 { $$ = new ExpressionNode( build_cast( $2, $4 ) ); }919 { $$ = new ExpressionNode( build_cast( yylloc, $2, $4 ) ); } 918 920 | '(' aggregate_control '&' ')' cast_expression // CFA 919 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }921 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); } 920 922 | '(' aggregate_control '*' ')' cast_expression // CFA 921 { $$ = new ExpressionNode( build_keyword_cast( $2, $5 ) ); }923 { $$ = new ExpressionNode( build_keyword_cast( yylloc, $2, $5 ) ); } 922 924 | '(' VIRTUAL ')' cast_expression // CFA 923 { $$ = new ExpressionNode( new VirtualCastExpr(maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); }925 { $$ = new ExpressionNode( new ast::VirtualCastExpr( yylloc, maybeMoveBuild( $4 ), maybeMoveBuildType( nullptr ) ) ); } 924 926 | '(' 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 ) ) ); } 926 928 | '(' RETURN type_no_function ')' cast_expression // CFA 927 929 { SemanticError( yylloc, "Return cast is currently unimplemented." ); $$ = nullptr; } … … 931 933 { SemanticError( yylloc, "Qualifier cast is currently unimplemented." ); $$ = nullptr; } 932 934 // | '(' type_no_function ')' tuple 933 // { $$ = new ExpressionNode( build_cast($2, $4 ) ); }935 // { $$ = new ast::ExpressionNode( build_cast( yylloc, $2, $4 ) ); } 934 936 ; 935 937 … … 949 951 cast_expression 950 952 | 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 ) ); } 952 954 ; 953 955 … … 955 957 exponential_expression 956 958 | 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 ) ); } 958 960 | 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 ) ); } 960 962 | 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 ) ); } 962 964 ; 963 965 … … 965 967 multiplicative_expression 966 968 | 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 ) ); } 968 970 | 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 ) ); } 970 972 ; 971 973 … … 973 975 additive_expression 974 976 | 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 ) ); } 976 978 | 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 ) ); } 978 980 ; 979 981 … … 981 983 shift_expression 982 984 | 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 ) ); } 984 986 | 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 ) ); } 986 988 | 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 ) ); } 988 990 | 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 ) ); } 990 992 ; 991 993 … … 993 995 relational_expression 994 996 | 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 ) ); } 996 998 | 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 ) ); } 998 1000 ; 999 1001 … … 1001 1003 equality_expression 1002 1004 | 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 ) ); } 1004 1006 ; 1005 1007 … … 1007 1009 AND_expression 1008 1010 | 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 ) ); } 1010 1012 ; 1011 1013 … … 1013 1015 exclusive_OR_expression 1014 1016 | 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 ) ); } 1016 1018 ; 1017 1019 … … 1019 1021 inclusive_OR_expression 1020 1022 | 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 ) ); } 1022 1024 ; 1023 1025 … … 1025 1027 logical_AND_expression 1026 1028 | 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 ) ); } 1028 1030 ; 1029 1031 … … 1031 1033 logical_OR_expression 1032 1034 | logical_OR_expression '?' comma_expression ':' conditional_expression 1033 { $$ = new ExpressionNode( build_cond( $1, $3, $5 ) ); }1035 { $$ = new ExpressionNode( build_cond( yylloc, $1, $3, $5 ) ); } 1034 1036 // FIX ME: computes $1 twice 1035 1037 | 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 ) ); } 1037 1039 ; 1038 1040 … … 1049 1051 // SemanticError( yylloc, "C @= assignment is currently unimplemented." ); $$ = nullptr; 1050 1052 // } else { 1051 $$ = new ExpressionNode( build_binary_val( $2, $1, $3 ) );1053 $$ = new ExpressionNode( build_binary_val( yylloc, $2, $1, $3 ) ); 1052 1054 // } // if 1053 1055 } … … 1094 1096 // { $$ = new ExpressionNode( build_tuple( $3 ) ); } 1095 1097 '[' ',' 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 ) ) ); } 1097 1099 | '[' 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 ) ) )); } 1099 1101 ; 1100 1102 … … 1112 1114 assignment_expression 1113 1115 | comma_expression ',' assignment_expression 1114 { $$ = new ExpressionNode( new CommaExpr(maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); }1116 { $$ = new ExpressionNode( new ast::CommaExpr( yylloc, maybeMoveBuild( $1 ), maybeMoveBuild( $3 ) ) ); } 1115 1117 ; 1116 1118 … … 1139 1141 | asm_statement 1140 1142 | DIRECTIVE 1141 { $$ = new StatementNode( build_directive( $1 ) ); }1143 { $$ = new StatementNode( build_directive( yylloc, $1 ) ); } 1142 1144 ; 1143 1145 … … 1145 1147 // labels cannot be identifiers 0 or 1 1146 1148 identifier_or_type_name ':' attribute_list_opt statement 1147 { $$ = $4->add_label( $1, $3 ); }1149 { $$ = $4->add_label( yylloc, $1, $3 ); } 1148 1150 | identifier_or_type_name ':' attribute_list_opt error // syntax error 1149 1151 { … … 1157 1159 compound_statement: 1158 1160 '{' '}' 1159 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); }1161 { $$ = new StatementNode( build_compound( yylloc, (StatementNode *)0 ) ); } 1160 1162 | '{' push 1161 1163 local_label_declaration_opt // GCC, local labels appear at start of block 1162 1164 statement_decl_list // C99, intermix declarations and statements 1163 1165 pop '}' 1164 { $$ = new StatementNode( build_compound( $4 ) ); }1166 { $$ = new StatementNode( build_compound( yylloc, $4 ) ); } 1165 1167 ; 1166 1168 … … 1193 1195 expression_statement: 1194 1196 comma_expression_opt ';' 1195 { $$ = new StatementNode( build_expr( $1 ) ); }1197 { $$ = new StatementNode( build_expr( yylloc, $1 ) ); } 1196 1198 ; 1197 1199 … … 1202 1204 { $$ = $2; } 1203 1205 | SWITCH '(' comma_expression ')' case_clause 1204 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }1206 { $$ = new StatementNode( build_switch( yylloc, true, $3, $5 ) ); } 1205 1207 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1206 1208 { 1207 StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) );1209 StatementNode *sw = new StatementNode( build_switch( yylloc, true, $3, $8 ) ); 1208 1210 // The semantics of the declaration list is changed to include associated initialization, which is performed 1209 1211 // *before* the transfer to the appropriate case clause by hoisting the declarations into a compound … … 1211 1213 // therefore, are removed from the grammar even though C allows it. The change also applies to choose 1212 1214 // 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; 1214 1216 } 1215 1217 | SWITCH '(' comma_expression ')' '{' error '}' // CFA, syntax error 1216 1218 { SemanticError( yylloc, "Only declarations can appear before the list of case clauses." ); $$ = nullptr; } 1217 1219 | CHOOSE '(' comma_expression ')' case_clause // CFA 1218 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); }1220 { $$ = new StatementNode( build_switch( yylloc, false, $3, $5 ) ); } 1219 1221 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop '}' // CFA 1220 1222 { 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; 1223 1225 } 1224 1226 | CHOOSE '(' comma_expression ')' '{' error '}' // CFA, syntax error … … 1229 1231 IF '(' conditional_declaration ')' statement %prec THEN 1230 1232 // 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 ) ); } 1232 1234 | 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 ) ) ); } 1234 1236 ; 1235 1237 … … 1251 1253 constant_expression { $$ = $1; } 1252 1254 | 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 ) ) ); } 1254 1256 | subrange // CFA, subrange 1255 1257 ; … … 1267 1269 | CASE case_value_list error // syntax error 1268 1270 { SemanticError( yylloc, "Missing colon after case list." ); $$ = nullptr; } 1269 | DEFAULT ':' { $$ = new StatementNode( build_default( ) ); }1271 | DEFAULT ':' { $$ = new StatementNode( build_default( yylloc ) ); } 1270 1272 // A semantic check is required to ensure only one default clause per switch/choose statement. 1271 1273 | DEFAULT error // syntax error … … 1279 1281 1280 1282 case_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 ) ); } 1282 1284 ; 1283 1285 … … 1290 1292 switch_clause_list: // CFA 1291 1293 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 ) ) ); } 1293 1295 | 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 ) ) ) ) ); } 1295 1297 ; 1296 1298 1297 1299 iteration_statement: 1298 1300 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 ) ) ); } 1300 1302 | WHILE '(' ')' statement ELSE statement // CFA 1301 1303 { 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 ) ) ); 1303 1305 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1304 1306 } 1305 1307 | 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 ) ) ); } 1307 1309 | 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 ) ); } 1309 1311 | 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 ) ) ); } 1311 1313 | DO statement WHILE '(' ')' ELSE statement // CFA 1312 1314 { 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 ) ) ); 1314 1316 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1315 1317 } 1316 1318 | 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 ) ) ); } 1318 1320 | 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 ) ); } 1320 1322 | 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 ) ) ); } 1322 1324 | FOR '(' ')' statement ELSE statement // CFA 1323 1325 { 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 ) ) ); 1325 1327 SemanticWarning( yylloc, Warning::SuperfluousElse ); 1326 1328 } 1327 1329 | 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 ) ) ); } 1329 1331 | 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 ) ); } 1331 1333 ; 1332 1334 … … 1342 1344 if ( $1->condition ) { 1343 1345 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 ) ); 1345 1347 } // if 1346 1348 } else $1->condition = $3->condition; 1347 1349 if ( $1->change ) { 1348 1350 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() ) ); 1350 1352 } // if 1351 1353 } else $1->change = $3->change; … … 1359 1361 | comma_expression ';' comma_expression_opt ';' comma_expression_opt 1360 1362 { 1361 StatementNode * init = $1 ? new StatementNode( new ExprStmt(maybeMoveBuild( $1 ) ) ) : nullptr;1363 StatementNode * init = $1 ? new StatementNode( new ast::ExprStmt( yylloc, maybeMoveBuild( $1 ) ) ) : nullptr; 1362 1364 $$ = new ForCtrl( init, $3, $5 ); 1363 1365 } … … 1371 1373 1372 1374 | 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 ); } 1374 1376 | 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 ); } 1376 1378 1377 1379 | 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 ); } 1379 1381 | '@' updowneq comma_expression // CFA, anonymous loop-index 1380 1382 { 1381 1383 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 ); 1383 1385 } 1384 1386 | comma_expression updowneq '@' // CFA, anonymous loop-index … … 1388 1390 } 1389 1391 | 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 ); } 1391 1393 | '@' updowneq comma_expression '~' comma_expression // CFA, anonymous loop-index 1392 1394 { 1393 1395 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 ); 1395 1397 } 1396 1398 | comma_expression updowneq '@' '~' comma_expression // CFA, anonymous loop-index … … 1411 1413 1412 1414 | 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 ); } 1414 1416 | 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 ); } 1416 1418 1417 1419 | 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 ); } 1419 1421 | comma_expression ';' '@' updowneq comma_expression // CFA 1420 1422 { 1421 1423 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 ); 1423 1425 } 1424 1426 | comma_expression ';' comma_expression updowneq '@' // CFA … … 1426 1428 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1427 1429 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 ); 1429 1431 } 1430 1432 | comma_expression ';' '@' updowneq '@' // CFA, error … … 1432 1434 1433 1435 | 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 ); } 1435 1437 | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error 1436 1438 { 1437 1439 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 ); 1439 1441 } 1440 1442 | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA … … 1442 1444 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1443 1445 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 ); 1445 1447 } 1446 1448 | 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 ); } 1448 1450 | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error 1449 1451 { 1450 1452 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 ); 1452 1454 } 1453 1455 | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA … … 1455 1457 if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1456 1458 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 ); 1458 1460 } 1459 1461 | comma_expression ';' '@' updowneq '@' '~' '@' // CFA … … 1461 1463 1462 1464 | 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 ); } 1464 1466 | 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 ); } 1466 1468 1467 1469 | 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 ); } 1469 1471 | declaration '@' updowneq comma_expression // CFA 1470 1472 { 1471 1473 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 ); 1473 1475 } 1474 1476 | declaration comma_expression updowneq '@' // CFA … … 1476 1478 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1477 1479 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 ); 1479 1481 } 1480 1482 1481 1483 | 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 ); } 1483 1485 | declaration '@' updowneq comma_expression '~' comma_expression // CFA 1484 1486 { 1485 1487 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 ); 1487 1489 } 1488 1490 | declaration comma_expression updowneq '@' '~' comma_expression // CFA … … 1490 1492 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1491 1493 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 ); 1493 1495 } 1494 1496 | 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 ); } 1496 1498 | declaration '@' updowneq comma_expression '~' '@' // CFA 1497 1499 { 1498 1500 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 ); 1500 1502 } 1501 1503 | declaration comma_expression updowneq '@' '~' '@' // CFA … … 1503 1505 if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; } 1504 1506 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 ); 1506 1508 } 1507 1509 | declaration '@' updowneq '@' '~' '@' // CFA, error … … 1546 1548 jump_statement: 1547 1549 GOTO identifier_or_type_name ';' 1548 { $$ = new StatementNode( build_branch( $2,BranchStmt::Goto ) ); }1550 { $$ = new StatementNode( build_branch( yylloc, $2, ast::BranchStmt::Goto ) ); } 1549 1551 | GOTO '*' comma_expression ';' // GCC, computed goto 1550 1552 // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3); … … 1553 1555 // A semantic check is required to ensure fallthru appears only in the body of a choose statement. 1554 1556 | fall_through_name ';' // CFA 1555 { $$ = new StatementNode( build_branch( BranchStmt::FallThrough ) ); }1557 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThrough ) ); } 1556 1558 | 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 ) ); } 1558 1560 | fall_through_name DEFAULT ';' // CFA 1559 { $$ = new StatementNode( build_branch( BranchStmt::FallThroughDefault ) ); }1561 { $$ = new StatementNode( build_branch( yylloc, ast::BranchStmt::FallThroughDefault ) ); } 1560 1562 | CONTINUE ';' 1561 1563 // 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 ) ); } 1563 1565 | CONTINUE identifier_or_type_name ';' // CFA, multi-level continue 1564 1566 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1565 1567 // 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 ) ); } 1567 1569 | BREAK ';' 1568 1570 // 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 ) ); } 1570 1572 | BREAK identifier_or_type_name ';' // CFA, multi-level exit 1571 1573 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 1572 1574 // 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 ) ); } 1574 1576 | RETURN comma_expression_opt ';' 1575 { $$ = new StatementNode( build_return( $2 ) ); }1577 { $$ = new StatementNode( build_return( yylloc, $2 ) ); } 1576 1578 | RETURN '{' initializer_list_opt comma_opt '}' ';' 1577 1579 { SemanticError( yylloc, "Initializer return is currently unimplemented." ); $$ = nullptr; } 1578 1580 | SUSPEND ';' 1579 { $$ = new StatementNode( build_suspend( nullptr) ); }1581 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::None ) ); } 1580 1582 | SUSPEND compound_statement 1581 { $$ = new StatementNode( build_suspend( $2) ); }1583 { $$ = new StatementNode( build_suspend( yylloc, $2, ast::SuspendStmt::None ) ); } 1582 1584 | SUSPEND COROUTINE ';' 1583 { $$ = new StatementNode( build_suspend( nullptr,SuspendStmt::Coroutine ) ); }1585 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Coroutine ) ); } 1584 1586 | SUSPEND COROUTINE compound_statement 1585 { $$ = new StatementNode( build_suspend( $3,SuspendStmt::Coroutine ) ); }1587 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Coroutine ) ); } 1586 1588 | SUSPEND GENERATOR ';' 1587 { $$ = new StatementNode( build_suspend( nullptr,SuspendStmt::Generator ) ); }1589 { $$ = new StatementNode( build_suspend( yylloc, nullptr, ast::SuspendStmt::Generator ) ); } 1588 1590 | SUSPEND GENERATOR compound_statement 1589 { $$ = new StatementNode( build_suspend( $3,SuspendStmt::Generator ) ); }1591 { $$ = new StatementNode( build_suspend( yylloc, $3, ast::SuspendStmt::Generator ) ); } 1590 1592 | THROW assignment_expression_opt ';' // handles rethrow 1591 { $$ = new StatementNode( build_throw( $2 ) ); }1593 { $$ = new StatementNode( build_throw( yylloc, $2 ) ); } 1592 1594 | THROWRESUME assignment_expression_opt ';' // handles reresume 1593 { $$ = new StatementNode( build_resume( $2 ) ); }1595 { $$ = new StatementNode( build_resume( yylloc, $2 ) ); } 1594 1596 | THROWRESUME assignment_expression_opt AT assignment_expression ';' // handles reresume 1595 1597 { $$ = new StatementNode( build_resume_at( $2, $4 ) ); } … … 1603 1605 with_statement: 1604 1606 WITH '(' tuple_expression_list ')' statement 1605 { $$ = new StatementNode( build_with( $3, $5 ) ); }1607 { $$ = new StatementNode( build_with( yylloc, $3, $5 ) ); } 1606 1608 ; 1607 1609 … … 1611 1613 { 1612 1614 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 ) ); 1614 1616 } 1615 1617 ; … … 1650 1652 when_clause_opt waitfor statement %prec THEN 1651 1653 // 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 ) ); } 1653 1655 | 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 ) ); } 1655 1657 | 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 ) ); } 1657 1659 | 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 ) ); } 1659 1661 // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless) 1660 1662 | wor_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // syntax error 1661 1663 { SemanticError( yylloc, "else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; } 1662 1664 | 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 ; 1664 1667 1665 1668 waitfor_statement: … … 1711 1714 wor_waituntil_clause %prec THEN 1712 1715 // 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 ) ); } 1714 1717 ; 1715 1718 1716 1719 exception_statement: 1717 TRY compound_statement handler_clause %prec THEN1718 { $$ = new StatementNode( build_try( $2, $3, nullptr ) ); }1720 TRY compound_statement handler_clause %prec THEN 1721 { $$ = new StatementNode( build_try( yylloc, $2, $3, nullptr ) ); } 1719 1722 | TRY compound_statement finally_clause 1720 { $$ = new StatementNode( build_try( $2, nullptr, $3 ) ); }1723 { $$ = new StatementNode( build_try( yylloc, $2, nullptr, $3 ) ); } 1721 1724 | TRY compound_statement handler_clause finally_clause 1722 { $$ = new StatementNode( build_try( $2, $3, $4 ) ); }1725 { $$ = new StatementNode( build_try( yylloc, $2, $3, $4 ) ); } 1723 1726 ; 1724 1727 1725 1728 handler_clause: 1726 1729 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 ) ); } 1728 1731 | 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 ) ) ); } 1730 1733 ; 1731 1734 … … 1737 1740 1738 1741 handler_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; } 1743 1746 ; 1744 1747 1745 1748 finally_clause: 1746 FINALLY compound_statement { $$ = new StatementNode( build_finally( $2 ) ); }1749 FINALLY compound_statement { $$ = new StatementNode( build_finally( yylloc, $2 ) ); } 1747 1750 ; 1748 1751 … … 1770 1773 asm_statement: 1771 1774 ASM asm_volatile_opt '(' string_literal ')' ';' 1772 { $$ = new StatementNode( build_asm( $2, $4, nullptr ) ); }1775 { $$ = new StatementNode( build_asm( yylloc, $2, $4, nullptr ) ); } 1773 1776 | 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 ) ); } 1775 1778 | 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 ) ); } 1777 1780 | 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 ) ); } 1779 1782 | 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 ) ); } 1781 1784 ; 1782 1785 … … 1802 1805 asm_operand: // GCC 1803 1806 string_literal '(' constant_expression ')' 1804 { $$ = new ExpressionNode( new AsmExpr( nullptr, $1, maybeMoveBuild( $3 ) ) ); }1807 { $$ = new ExpressionNode( new ast::AsmExpr( yylloc, "", $1, maybeMoveBuild( $3 ) ) ); } 1805 1808 | '[' 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 } 1807 1813 ; 1808 1814 … … 1819 1825 identifier 1820 1826 { 1821 $$ = new LabelNode(); $$->labels. push_back(*$1 );1827 $$ = new LabelNode(); $$->labels.emplace_back( yylloc, *$1 ); 1822 1828 delete $1; // allocated by lexer 1823 1829 } 1824 1830 | label_list ',' identifier 1825 1831 { 1826 $$ = $1; $1->labels. push_back(*$3 );1832 $$ = $1; $1->labels.emplace_back( yylloc, *$3 ); 1827 1833 delete $3; // allocated by lexer 1828 1834 } … … 1887 1893 { $$ = DeclarationNode::newStaticAssert( $3, $5 ); } 1888 1894 | STATICASSERT '(' constant_expression ')' ';' // CFA 1889 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( *new string( "\"\"" ) ) ); }1895 { $$ = DeclarationNode::newStaticAssert( $3, build_constantStr( yylloc, *new string( "\"\"" ) ) ); } 1890 1896 1891 1897 // C declaration syntax is notoriously confusing and error prone. Cforall provides its own type, variable and function … … 2087 2093 { 2088 2094 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 ), 2090 2096 " declaration" ) ); 2091 2097 $$ = nullptr; … … 2321 2327 { $$ = DeclarationNode::newTypeof( $3 ); } 2322 2328 | 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 ); } 2324 2330 | BASETYPEOF '(' comma_expression ')' // CFA: basetypeof( a+b ) y; 2325 2331 { $$ = DeclarationNode::newTypeof( $3, true ); } … … 2515 2521 aggregate_data: 2516 2522 STRUCT vtable_opt 2517 { $$ = AggregateDecl::Struct; }2523 { $$ = ast::AggregateDecl::Struct; } 2518 2524 | UNION 2519 { $$ = AggregateDecl::Union; }2525 { $$ = ast::AggregateDecl::Union; } 2520 2526 | 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; } 2523 2529 ; 2524 2530 2525 2531 aggregate_control: // CFA 2526 2532 MONITOR 2527 { $$ = AggregateDecl::Monitor; }2533 { $$ = ast::AggregateDecl::Monitor; } 2528 2534 | MUTEX STRUCT 2529 { $$ = AggregateDecl::Monitor; }2535 { $$ = ast::AggregateDecl::Monitor; } 2530 2536 | GENERATOR 2531 { $$ = AggregateDecl::Generator; }2537 { $$ = ast::AggregateDecl::Generator; } 2532 2538 | 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 } 2534 2543 | COROUTINE 2535 { $$ = AggregateDecl::Coroutine; }2544 { $$ = ast::AggregateDecl::Coroutine; } 2536 2545 | 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 } 2538 2550 | THREAD 2539 { $$ = AggregateDecl::Thread; }2551 { $$ = ast::AggregateDecl::Thread; } 2540 2552 | 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 } 2542 2557 ; 2543 2558 … … 2889 2904 designator_list ':' // C99, CFA uses ":" instead of "=" 2890 2905 | identifier_at ':' // GCC, field name 2891 { $$ = new ExpressionNode( build_varref( $1 ) ); }2906 { $$ = new ExpressionNode( build_varref( yylloc, $1 ) ); } 2892 2907 ; 2893 2908 … … 2901 2916 designator: 2902 2917 '.' identifier_at // C99, field name 2903 { $$ = new ExpressionNode( build_varref( $2 ) ); }2918 { $$ = new ExpressionNode( build_varref( yylloc, $2 ) ); } 2904 2919 | '[' push assignment_expression pop ']' // C99, single array element 2905 2920 // assignment_expression used instead of constant_expression because of shift/reduce conflicts with tuple. … … 2908 2923 { $$ = $3; } 2909 2924 | '[' 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 ) ) ); } 2911 2926 | '.' '[' push field_name_list pop ']' // CFA, tuple field selector 2912 2927 { $$ = $4; } … … 2948 2963 { 2949 2964 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 ..." ); } 2953 2968 } 2954 2969 type_initializer_opt assertion_list_opt … … 2961 2976 { 2962 2977 typedefTable.addToScope( *$2, TYPEDIMname, "9" ); 2963 $$ = DeclarationNode::newTypeParam( TypeDecl::Dimension, $2 );2978 $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 ); 2964 2979 } 2965 2980 // | type_specifier identifier_parameter_declarator 2966 2981 | 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 ); } 2968 2983 ; 2969 2984 2970 2985 new_type_class: // CFA 2971 2986 // empty 2972 { $$ = TypeDecl::Otype; }2987 { $$ = ast::TypeDecl::Otype; } 2973 2988 | '&' 2974 { $$ = TypeDecl::Dtype; }2989 { $$ = ast::TypeDecl::Dtype; } 2975 2990 | '*' 2976 { $$ = TypeDecl::DStype; } // dtype + sized2991 { $$ = ast::TypeDecl::DStype; } // dtype + sized 2977 2992 // | '(' '*' ')' 2978 // { $$ = TypeDecl::Ftype; }2993 // { $$ = ast::TypeDecl::Ftype; } 2979 2994 | ELLIPSIS 2980 { $$ = TypeDecl::Ttype; }2995 { $$ = ast::TypeDecl::Ttype; } 2981 2996 ; 2982 2997 2983 2998 type_class: // CFA 2984 2999 OTYPE 2985 { $$ = TypeDecl::Otype; }3000 { $$ = ast::TypeDecl::Otype; } 2986 3001 | DTYPE 2987 { $$ = TypeDecl::Dtype; }3002 { $$ = ast::TypeDecl::Dtype; } 2988 3003 | FTYPE 2989 { $$ = TypeDecl::Ftype; }3004 { $$ = ast::TypeDecl::Ftype; } 2990 3005 | TTYPE 2991 { $$ = TypeDecl::Ttype; }3006 { $$ = ast::TypeDecl::Ttype; } 2992 3007 ; 2993 3008 … … 3015 3030 type_list: // CFA 3016 3031 type 3017 { $$ = new ExpressionNode( new TypeExpr(maybeMoveBuildType( $1 ) ) ); }3032 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); } 3018 3033 | assignment_expression 3019 3034 | 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 ) ) ) )); } 3021 3036 | type_list ',' assignment_expression 3022 3037 { $$ = (ExpressionNode *)( $1->set_last( $3 )); } … … 3125 3140 external_definition: 3126 3141 DIRECTIVE 3127 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( $1 ) ) ); }3142 { $$ = DeclarationNode::newDirectiveStmt( new StatementNode( build_directive( yylloc, $1 ) ) ); } 3128 3143 | declaration 3129 3144 { … … 3131 3146 // unit, which is a dubious task, especially because C uses name rather than structural typing; hence it is 3132 3147 // 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 ) { 3134 3149 if ( $1->type->aggInst.aggregate->kind == TypeData::Enum && $1->type->aggInst.aggregate->enumeration.anon ) { 3135 3150 SemanticError( yylloc, "extern anonymous enumeration is currently unimplemented." ); $$ = nullptr; … … 3158 3173 } 3159 3174 | 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 ) ) ); } 3161 3176 | EXTERN STRINGliteral 3162 3177 { 3163 3178 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3164 linkage = LinkageSpec::update( yylloc, linkage, $2 );3179 linkage = ast::Linkage::update( yylloc, linkage, $2 ); 3165 3180 } 3166 3181 up external_definition down … … 3173 3188 { 3174 3189 linkageStack.push( linkage ); // handle nested extern "C"/"Cforall" 3175 linkage = LinkageSpec::update( yylloc, linkage, $2 );3190 linkage = ast::Linkage::update( yylloc, linkage, $2 ); 3176 3191 } 3177 3192 '{' up external_definition_list_opt down '}' … … 3297 3312 subrange: 3298 3313 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 ) ) ); } 3300 3315 ; 3301 3316 … … 3826 3841 array_type_list: 3827 3842 basic_type_name 3828 { $$ = new ExpressionNode( new TypeExpr(maybeMoveBuildType( $1 ) ) ); }3843 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); } 3829 3844 | type_name 3830 { $$ = new ExpressionNode( new TypeExpr(maybeMoveBuildType( $1 ) ) ); }3845 { $$ = new ExpressionNode( new ast::TypeExpr( yylloc, maybeMoveBuildType( $1 ) ) ); } 3831 3846 | assignment_expression upupeq assignment_expression 3832 3847 | 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 ) ) ) )); } 3836 3851 | array_type_list ',' assignment_expression upupeq assignment_expression 3837 3852 ; -
src/Parser/parserutility.cc
rff71057 re02e13f 10 10 // Created On : Sat May 16 15:30:39 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus Jul 18 10:12:00 201713 // Update Count : 812 // Last Modified On : Wed Mar 1 10:42:00 2023 13 // Update Count : 9 14 14 // 15 15 … … 19 19 #include <string> // for string 20 20 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... 24 23 25 24 // rewrite … … 28 27 // if ( (int)(x != 0) ) ... 29 28 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 ) ); 29 ast::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 ); 36 44 } 37 45 -
src/Parser/parserutility.h
rff71057 re02e13f 10 10 // Created On : Sat May 16 15:31:46 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T hr Mar 9 12:16:00 202313 // Update Count : 612 // Last Modified On : Tue Apr 4 14:03:00 2023 13 // Update Count : 7 14 14 // 15 15 16 16 #pragma once 17 17 18 class Expression; 18 #include "AST/Copy.hpp" // for shallowCopy 19 namespace ast { 20 class Expr; 21 } 19 22 20 Expression *notZeroExpr( Expression*orig );23 ast::Expr * notZeroExpr( ast::Expr *orig ); 21 24 22 25 template< typename T > … … 32 35 } 33 36 37 template<typename node_t> 38 node_t * maybeCopy( node_t const * node ) { 39 return node ? ast::shallowCopy( node ) : nullptr; 40 } 41 34 42 // Local Variables: // 35 43 // tab-width: 4 // -
tests/.expect/attributes.arm64.txt
rff71057 re02e13f 1351 1351 signed 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)); 1352 1352 signed 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));1353 signed 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)); 1354 1354 struct Vad { 1355 1355 __attribute__ ((unused)) signed int :4; -
tests/.expect/attributes.x64.txt
rff71057 re02e13f 1351 1351 signed 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)); 1352 1352 signed 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));1353 signed 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)); 1354 1354 struct Vad { 1355 1355 __attribute__ ((unused)) signed int :4; -
tests/.expect/attributes.x86.txt
rff71057 re02e13f 1351 1351 signed 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)); 1352 1352 signed 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));1353 signed 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)); 1354 1354 struct Vad { 1355 1355 __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 int1 errors/declaration.cfa:16:1 error: duplicate static storage class(es) in declaration of x1: static const volatile short int 2 2 3 errors/declaration.cfa:17:1 error: conflicting extern & static in declaration of x2: extern const volatile short int3 errors/declaration.cfa:17:1 error: conflicting extern & static storage classes in declaration of x2: extern const volatile short int 4 4 5 errors/declaration.cfa:18:1 error: conflicting extern & auto , conflicting extern & static, conflicting extern & static, duplicate externin declaration of x3: extern const volatile short int5 errors/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 6 6 7 errors/declaration.cfa:19:1 error: duplicate static in declaration of x4: static const volatile instance of const volatile struct __anonymous07 errors/declaration.cfa:19:1 error: duplicate static storage class(es) in declaration of x4: static const volatile instance of const volatile struct __anonymous0 8 8 with members 9 9 i: int … … 11 11 12 12 13 errors/declaration.cfa:20:1 error: duplicate const , duplicate static, duplicate volatilein declaration of x5: static const volatile instance of const volatile struct __anonymous113 errors/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 14 14 with members 15 15 i: int … … 17 17 18 18 19 errors/declaration.cfa:22:1 error: duplicate static in declaration of x6: static const volatile Int19 errors/declaration.cfa:22:1 error: duplicate static storage class(es) in declaration of x6: static const volatile Int 20 20 21 errors/declaration.cfa:24:1 error: duplicate const in declaration of f01: static inline function21 errors/declaration.cfa:24:1 error: duplicate const qualifier(s) in declaration of f01: static inline function 22 22 with no parameters 23 23 returning const volatile int 24 24 25 25 26 errors/declaration.cfa:25:1 error: duplicate volatile in declaration of f02: static inline function26 errors/declaration.cfa:25:1 error: duplicate volatile qualifier(s) in declaration of f02: static inline function 27 27 with no parameters 28 28 returning const volatile int 29 29 30 30 31 errors/declaration.cfa:26:1 error: duplicate const in declaration of f03: static inline function31 errors/declaration.cfa:26:1 error: duplicate const qualifier(s) in declaration of f03: static inline function 32 32 with no parameters 33 33 returning const volatile int 34 34 35 35 36 errors/declaration.cfa:27:1 error: duplicate volatile in declaration of f04: static inline function36 errors/declaration.cfa:27:1 error: duplicate volatile qualifier(s) in declaration of f04: static inline function 37 37 with no parameters 38 38 returning const volatile int 39 39 40 40 41 errors/declaration.cfa:28:1 error: duplicate const in declaration of f05: static inline function41 errors/declaration.cfa:28:1 error: duplicate const qualifier(s) in declaration of f05: static inline function 42 42 with no parameters 43 43 returning const volatile int 44 44 45 45 46 errors/declaration.cfa:29:1 error: duplicate volatile in declaration of f06: static inline function46 errors/declaration.cfa:29:1 error: duplicate volatile qualifier(s) in declaration of f06: static inline function 47 47 with no parameters 48 48 returning const volatile int 49 49 50 50 51 errors/declaration.cfa:30:1 error: duplicate const in declaration of f07: static inline function51 errors/declaration.cfa:30:1 error: duplicate const qualifier(s) in declaration of f07: static inline function 52 52 with no parameters 53 53 returning const volatile int 54 54 55 55 56 errors/declaration.cfa:31:1 error: duplicate const , duplicate volatilein declaration of f08: static inline function56 errors/declaration.cfa:31:1 error: duplicate const volatile qualifier(s) in declaration of f08: static inline function 57 57 with no parameters 58 58 returning const volatile int 59 59 60 60 61 errors/declaration.cfa:33:1 error: duplicate const , duplicate volatilein declaration of f09: static inline function61 errors/declaration.cfa:33:1 error: duplicate const volatile qualifier(s) in declaration of f09: static inline function 62 62 with no parameters 63 63 returning const volatile int 64 64 65 65 66 errors/declaration.cfa:34:1 error: duplicate const , duplicate _Atomic, duplicate _Atomic, duplicate const, duplicate restrict, duplicate volatilein declaration of f09: static inline function66 errors/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 67 67 with no parameters 68 68 returning const restrict volatile _Atomic int
Note:
See TracChangeset
for help on using the changeset viewer.