source: src/Parser/ExpressionNode.cc@ 3096ec1

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since 3096ec1 was bf4b4cf, checked in by Rob Schluntz <rschlunt@…>, 8 years ago

Remove argName from Expression.

If named arguments are ever considered again, they should be added in UntypedExpr (and maybe also ApplicationExpr) to avoid unnecessary fields in every Expression. Like designators on initializers, it should be much easier to work with argument names at the call expression level.

  • Property mode set to 100644
File size: 20.7 KB
RevLine 
[b87a5ed]1//
2// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
3//
4// The contents of this file are covered under the licence agreement in the
5// file "LICENCE" distributed with Cforall.
6//
[0caaa6a]7// ExpressionNode.cc --
8//
[f43df73]9// Author : Peter A. Buhr
[b87a5ed]10// Created On : Sat May 16 13:17:07 2015
[76c62b2]11// Last Modified By : Peter A. Buhr
[201aeb9]12// Last Modified On : Tue Sep 26 11:23:36 2017
13// Update Count : 780
[0caaa6a]14//
[b87a5ed]15
[ea6332d]16#include <cassert> // for assert
[d180746]17#include <stdio.h> // for sscanf, size_t
18#include <climits> // for LLONG_MAX, LONG_MAX, INT_MAX, UINT...
19#include <list> // for list
20#include <sstream> // for basic_istream::operator>>, basic_i...
21#include <string> // for string, operator+, operator==
[51b73452]22
[d180746]23#include "Common/SemanticError.h" // for SemanticError
24#include "Common/utility.h" // for maybeMoveBuild, maybeBuild, CodeLo...
25#include "ParseNode.h" // for ExpressionNode, maybeMoveBuildType
26#include "SynTree/Constant.h" // for Constant
27#include "SynTree/Declaration.h" // for EnumDecl, StructDecl, UnionDecl
28#include "SynTree/Expression.h" // for Expression, ConstantExpr, NameExpr
29#include "SynTree/Statement.h" // for CompoundStmt, Statement
30#include "SynTree/Type.h" // for BasicType, Type, Type::Qualifiers
31#include "parserutility.h" // for notZeroExpr
32
33class Initializer;
[51b73452]34
35using namespace std;
36
[cd623a4]37//##############################################################################
38
[7bf7fb9]39// Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
40//
41// prefix action constant action suffix
42//
43// Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
44//
45// constant BEGIN CONT ...
46// <CONT>(...)? BEGIN 0 ... // possible empty suffix
47//
48// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
49// type.
50
[beec62c]51extern const Type::Qualifiers noQualifiers; // no qualifiers on constants
[7bf7fb9]52
[930f69e]53static inline bool checkH( char c ) { return c == 'h' || c == 'H'; }
[7bf7fb9]54static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
[930f69e]55static inline bool checkZ( char c ) { return c == 'z' || c == 'Z'; }
56static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
[7bf7fb9]57static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
58static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
59static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
60static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
61
[201aeb9]62static const char * lnthsInt[2][6] = {
63 { "int8_t", "int16_t", "int32_t", "int64_t", "size_t", },
64 { "uint8_t", "uint16_t", "uint32_t", "uint64_t", "size_t", }
65}; // lnthsInt
66
67static inline void checkLNInt( string & str, int & lnth, int & size ) {
68 string::size_type posn = str.find_first_of( "lL" ), start = posn;
69 if ( posn == string::npos ) return;
70 size = 4; // assume largest size
71 posn += 1; // advance to size
72 if ( str[posn] == '8' ) { // 8
73 lnth = 0;
74 } else if ( str[posn] == '1' ) {
75 posn += 1;
76 if ( str[posn] == '6' ) { // 16
77 lnth = 1;
78 } else { // 128
79 posn += 1;
80 lnth = 5;
81 } // if
82 } else {
83 if ( str[posn] == '3' ) { // 32
84 lnth = 2;
85 } else if ( str[posn] == '6' ) { // 64
86 lnth = 3;
87 } else {
88 assertf( false, "internal error, bad integral length %s", str.c_str() );
[bf4b4cf]89 } // if
[201aeb9]90 posn += 1;
91 } // if
92 str.erase( start, posn - start + 1 ); // remove length suffix
93} // checkLNInt
94
[76c62b2]95static void sepNumeric( string & str, string & units ) {
96 string::size_type posn = str.find_first_of( "`" );
97 if ( posn != string::npos ) {
[e8ccca3]98 units = "?" + str.substr( posn ); // extract units
[76c62b2]99 str.erase( posn ); // remove units
100 } // if
101} // sepNumeric
102
[ba2a68b]103Expression * build_constantInteger( string & str ) {
[201aeb9]104 static const BasicType::Kind kind[2][6] = {
[930f69e]105 // short (h) must be before char (hh)
[201aeb9]106 { BasicType::ShortSignedInt, BasicType::SignedChar, BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt, BasicType::SignedInt128, },
107 { BasicType::ShortUnsignedInt, BasicType::UnsignedChar, BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt, BasicType::UnsignedInt128, },
[7bf7fb9]108 };
[76c62b2]109
[201aeb9]110 string units;
[76c62b2]111 sepNumeric( str, units ); // separate constant from units
112
[7bf7fb9]113 bool dec = true, Unsigned = false; // decimal, unsigned constant
[201aeb9]114 int size; // 0 => short, 1 => char, 2 => int, 3 => long int, 4 => long long int, 5 => int128
115 int lnth = -1; // literal length
116
[6165ce7]117 unsigned long long int v; // converted integral value
[7bf7fb9]118 size_t last = str.length() - 1; // last character of constant
[6165ce7]119 Expression * ret;
[7bf7fb9]120
[6165ce7]121 // special constants
122 if ( str == "0" ) {
123 ret = new ConstantExpr( Constant( (Type *)new ZeroType( noQualifiers ), str, (unsigned long long int)0 ) );
124 goto CLEANUP;
125 } // if
126 if ( str == "1" ) {
127 ret = new ConstantExpr( Constant( (Type *)new OneType( noQualifiers ), str, (unsigned long long int)1 ) );
128 goto CLEANUP;
129 } // if
[ea6332d]130
[7bf7fb9]131 if ( str[0] == '0' ) { // octal/hex constant ?
132 dec = false;
133 if ( last != 0 && checkX( str[1] ) ) { // hex constant ?
134 sscanf( (char *)str.c_str(), "%llx", &v );
135 //printf( "%llx %llu\n", v, v );
136 } else { // octal constant
137 sscanf( (char *)str.c_str(), "%llo", &v );
138 //printf( "%llo %llu\n", v, v );
139 } // if
140 } else { // decimal constant ?
141 sscanf( (char *)str.c_str(), "%llu", &v );
142 //printf( "%llu %llu\n", v, v );
143 } // if
144
145 if ( v <= INT_MAX ) { // signed int
[930f69e]146 size = 2;
[7bf7fb9]147 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int
[930f69e]148 size = 2;
[7bf7fb9]149 Unsigned = true; // unsigned
150 } else if ( v <= LONG_MAX ) { // signed long int
[930f69e]151 size = 3;
[7bf7fb9]152 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
[930f69e]153 size = 3;
[7bf7fb9]154 Unsigned = true; // unsigned long int
155 } else if ( v <= LLONG_MAX ) { // signed long long int
[930f69e]156 size = 4;
[7bf7fb9]157 } else { // unsigned long long int
[930f69e]158 size = 4;
[7bf7fb9]159 Unsigned = true; // unsigned long long int
160 } // if
161
[930f69e]162 // At least one digit in integer constant, so safe to backup while looking for suffix.
163
[7bf7fb9]164 if ( checkU( str[last] ) ) { // suffix 'u' ?
165 Unsigned = true;
[930f69e]166 if ( checkL( str[last - 1] ) ) { // suffix 'l' ?
167 size = 3;
168 if ( checkL( str[last - 2] ) ) { // suffix "ll" ?
169 size = 4;
[7bf7fb9]170 } // if
[930f69e]171 } else if ( checkH( str[last - 1] ) ) { // suffix 'h' ?
172 size = 0;
173 if ( checkH( str[last - 2] ) ) { // suffix "hh" ?
174 size = 1;
175 } // if
176 str.erase( last - size - 1, size + 1 ); // remove 'h'/"hh"
[201aeb9]177 } else { // suffix "ln" ?
178 checkLNInt( str, lnth, size );
[7bf7fb9]179 } // if
180 } else if ( checkL( str[ last ] ) ) { // suffix 'l' ?
[930f69e]181 size = 3;
182 if ( checkL( str[last - 1] ) ) { // suffix 'll' ?
183 size = 4;
184 if ( checkU( str[last - 2] ) ) { // suffix 'u' ?
[7bf7fb9]185 Unsigned = true;
186 } // if
[930f69e]187 } else if ( checkU( str[last - 1] ) ) { // suffix 'u' ?
188 Unsigned = true;
189 } // if
190 } else if ( checkH( str[ last ] ) ) { // suffix 'h' ?
191 size = 0;
192 if ( checkH( str[last - 1] ) ) { // suffix "hh" ?
193 size = 1;
194 if ( checkU( str[last - 2] ) ) { // suffix 'u' ?
[7bf7fb9]195 Unsigned = true;
196 } // if
[930f69e]197 } else if ( checkU( str[last - 1] ) ) { // suffix 'u' ?
198 Unsigned = true;
[7bf7fb9]199 } // if
[930f69e]200 str.erase( last - size, size + 1 ); // remove 'h'/"hh"
201 } else if ( checkZ( str[last] ) ) { // suffix 'z' ?
[201aeb9]202 lnth = 4;
[930f69e]203 str.erase( last, 1 ); // remove 'z'
[201aeb9]204 } else { // suffix "ln" ?
205 checkLNInt( str, lnth, size );
[7bf7fb9]206 } // if
207
[201aeb9]208 assert( 0 <= size && size < 6 );
[e8ccca3]209 ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[Unsigned][size] ), str, v ) );
[201aeb9]210 if ( size < 2 ) { // hh or h, less than int ?
211 // int i = -1uh => 65535 not -1, so cast is necessary for unsigned, which unfortunately eliminates warnings for large values.
[7b1d5ec]212 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
[201aeb9]213 } else if ( lnth != -1 ) { // explicit length ?
214 if ( lnth == 5 ) { // int128 ?
215 size = 5;
216 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[Unsigned][size] ) );
217 } else {
218 ret = new CastExpr( ret, new TypeInstType( Type::Qualifiers(), lnthsInt[Unsigned][lnth], false ) );
219 } // if
[7b1d5ec]220 } // if
[6165ce7]221 CLEANUP:
[e8ccca3]222 if ( units.length() != 0 ) {
[ba2a68b]223 ret = new UntypedExpr( new NameExpr( units ), { ret } );
[e8ccca3]224 } // if
225
[ab57786]226 delete &str; // created by lex
227 return ret;
[7bf7fb9]228} // build_constantInteger
[51b73452]229
[201aeb9]230
231static inline void checkLNFloat( string & str, int & lnth, int & size ) {
232 string::size_type posn = str.find_first_of( "lL" ), start = posn;
233 if ( posn == string::npos ) return;
234 size = 2; // assume largest size
235 lnth = 0;
236 posn += 1; // advance to size
237 if ( str[posn] == '3' ) { // 32
238 size = 0;
239 } else if ( str[posn] == '6' ) { // 64
240 size = 1;
241 } else if ( str[posn] == '8' || str[posn] == '1' ) { // 80, 128
242 size = 2;
243 if ( str[posn] == '1' ) posn += 1;
244 } else {
245 assertf( false, "internal error, bad floating point length %s", str.c_str() );
246 } // if
247 posn += 1;
248 str.erase( start, posn - start + 1 ); // remove length suffix
249} // checkLNFloat
250
251
[f43df73]252Expression * build_constantFloat( string & str ) {
[7bf7fb9]253 static const BasicType::Kind kind[2][3] = {
254 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
255 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
256 };
[59c24b6]257
[201aeb9]258 string units;
[76c62b2]259 sepNumeric( str, units ); // separate constant from units
260
[7bf7fb9]261 bool complx = false; // real, complex
[201aeb9]262 int size = 1; // 0 => float, 1 => double, 2 => long double
263 int lnth = -1; // literal length
[7bf7fb9]264 // floating-point constant has minimum of 2 characters: 1. or .1
265 size_t last = str.length() - 1;
[d56e5bc]266 double v;
267
268 sscanf( str.c_str(), "%lg", &v );
[51b73452]269
[7bf7fb9]270 if ( checkI( str[last] ) ) { // imaginary ?
271 complx = true;
272 last -= 1; // backup one character
273 } // if
[0caaa6a]274
[7bf7fb9]275 if ( checkF( str[last] ) ) { // float ?
276 size = 0;
277 } else if ( checkD( str[last] ) ) { // double ?
278 size = 1;
279 } else if ( checkL( str[last] ) ) { // long double ?
280 size = 2;
[201aeb9]281 } else {
282 size = 1; // double (default)
283 checkLNFloat( str, lnth, size );
[7bf7fb9]284 } // if
285 if ( ! complx && checkI( str[last - 1] ) ) { // imaginary ?
286 complx = true;
287 } // if
[51b73452]288
[201aeb9]289 assert( 0 <= size && size < 3 );
[e8ccca3]290 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, kind[complx][size] ), str, v ) );
[201aeb9]291 if ( lnth != -1 ) { // explicit length ?
292 ret = new CastExpr( ret, new BasicType( Type::Qualifiers(), kind[complx][size] ) );
293 } // if
[e8ccca3]294 if ( units.length() != 0 ) {
[ba2a68b]295 ret = new UntypedExpr( new NameExpr( units ), { ret } );
[e8ccca3]296 } // if
[76c62b2]297
[ab57786]298 delete &str; // created by lex
299 return ret;
[7bf7fb9]300} // build_constantFloat
[51b73452]301
[76c62b2]302static void sepString( string & str, string & units, char delimit ) {
303 string::size_type posn = str.find_last_of( delimit ) + 1;
304 if ( posn != str.length() ) {
[e8ccca3]305 units = "?" + str.substr( posn ); // extract units
[76c62b2]306 str.erase( posn ); // remove units
307 } // if
308} // sepString
309
[f43df73]310Expression * build_constantChar( string & str ) {
[76c62b2]311 string units; // units
312 sepString( str, units, '\'' ); // separate constant from units
313
[e8ccca3]314 Expression * ret = new ConstantExpr( Constant( new BasicType( noQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) );
315 if ( units.length() != 0 ) {
[ba2a68b]316 ret = new UntypedExpr( new NameExpr( units ), { ret } );
[e8ccca3]317 } // if
[76c62b2]318
[ab57786]319 delete &str; // created by lex
320 return ret;
[7bf7fb9]321} // build_constantChar
[51b73452]322
[e612146c]323Expression * build_constantStr( string & str ) {
[76c62b2]324 string units; // units
325 sepString( str, units, '"' ); // separate constant from units
326
[513e165]327 Type * strtype;
328 switch ( str[0] ) { // str has >= 2 characters, i.e, null string "" => safe to look at subscripts 0/1
[e612146c]329 case 'u':
[513e165]330 if ( str[1] == '8' ) goto Default; // utf-8 characters => array of char
331 // lookup type of associated typedef
332 strtype = new TypeInstType( Type::Qualifiers( Type::Const ), "char16_t", false );
[e612146c]333 break;
334 case 'U':
[513e165]335 strtype = new TypeInstType( Type::Qualifiers( Type::Const ), "char32_t", false );
[e612146c]336 break;
337 case 'L':
[513e165]338 strtype = new TypeInstType( Type::Qualifiers( Type::Const ), "wchar_t", false );
[e612146c]339 break;
[513e165]340 Default: // char default string type
341 default:
342 strtype = new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char );
[e612146c]343 } // switch
[513e165]344 ArrayType * at = new ArrayType( noQualifiers, strtype,
[e8ccca3]345 new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ), // +1 for '\0' and -2 for '"'
346 false, false );
[e612146c]347 Expression * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) ); // constant 0 is ignored for pure string value
348 if ( units.length() != 0 ) {
349 ret = new UntypedExpr( new NameExpr( units ), { ret } );
350 } // if
[5809461]351
[ab57786]352 delete &str; // created by lex
353 return ret;
[7bf7fb9]354} // build_constantStr
[51b73452]355
[930f69e]356Expression * build_field_name_FLOATING_FRACTIONconstant( const string & str ) {
357 if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
358 Expression * ret = build_constantInteger( *new string( str.substr(1) ) );
359 delete &str;
360 return ret;
361} // build_field_name_FLOATING_FRACTIONconstant
362
363Expression * build_field_name_FLOATING_DECIMALconstant( const string & str ) {
364 if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
365 Expression * ret = build_constantInteger( *new string( str.substr( 0, str.size()-1 ) ) );
366 delete &str;
367 return ret;
368} // build_field_name_FLOATING_DECIMALconstant
369
[f43df73]370Expression * build_field_name_FLOATINGconstant( const string & str ) {
[8780e30]371 // str is of the form A.B -> separate at the . and return member expression
372 int a, b;
373 char dot;
[f43df73]374 stringstream ss( str );
[8780e30]375 ss >> a >> dot >> b;
[d56e5bc]376 UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) );
[8780e30]377 delete &str;
378 return ret;
379} // build_field_name_FLOATINGconstant
380
381Expression * make_field_name_fraction_constants( Expression * fieldName, Expression * fracts ) {
382 if ( fracts ) {
383 if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( fracts ) ) {
384 memberExpr->set_member( make_field_name_fraction_constants( fieldName, memberExpr->get_aggregate() ) );
385 return memberExpr;
386 } else {
387 return new UntypedMemberExpr( fracts, fieldName );
[f43df73]388 } // if
389 } // if
[8780e30]390 return fieldName;
391} // make_field_name_fraction_constants
392
393Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ) {
394 return make_field_name_fraction_constants( fieldName, maybeMoveBuild< Expression >( fracts ) );
395} // build_field_name_fraction_constants
396
[a2e0687]397NameExpr * build_varref( const string * name ) {
[bf4b4cf]398 NameExpr * expr = new NameExpr( *name );
[7ecbb7e]399 delete name;
400 return expr;
[a2e0687]401} // build_varref
[51b1202]402
[5809461]403// TODO: get rid of this and OperKinds and reuse code from OperatorTable
[a2e0687]404static const char * OperName[] = { // must harmonize with OperKinds
[5721a6d]405 // diadic
[e5f2a67]406 "SizeOf", "AlignOf", "OffsetOf", "?+?", "?-?", "?\\?", "?*?", "?/?", "?%?", "||", "&&",
[5721a6d]407 "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
[e5f2a67]408 "?=?", "?@=?", "?\\=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
[d9e2280]409 "?[?]", "...",
[5721a6d]410 // monadic
[5809461]411 "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--",
[a2e0687]412}; // OperName
[5721a6d]413
[a2e0687]414Expression * build_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) {
415 Type * targetType = maybeMoveBuildType( decl_node );
[d1625f8]416 if ( dynamic_cast< VoidType * >( targetType ) ) {
[064e3ff]417 delete targetType;
[7ecbb7e]418 return new CastExpr( maybeMoveBuild< Expression >(expr_node) );
[064e3ff]419 } else {
[7ecbb7e]420 return new CastExpr( maybeMoveBuild< Expression >(expr_node), targetType );
[064e3ff]421 } // if
[a2e0687]422} // build_cast
[a5f0529]423
[a2e0687]424Expression * build_virtual_cast( DeclarationNode * decl_node, ExpressionNode * expr_node ) {
[513e165]425 return new VirtualCastExpr( maybeMoveBuild< Expression >( expr_node ), maybeMoveBuildType( decl_node ) );
[a2e0687]426} // build_virtual_cast
[064e3ff]427
[a2e0687]428Expression * build_fieldSel( ExpressionNode * expr_node, Expression * member ) {
[513e165]429 return new UntypedMemberExpr( member, maybeMoveBuild< Expression >(expr_node) );
[a2e0687]430} // build_fieldSel
[064e3ff]431
[a2e0687]432Expression * build_pfieldSel( ExpressionNode * expr_node, Expression * member ) {
433 UntypedExpr * deref = new UntypedExpr( new NameExpr( "*?" ) );
[64ac636]434 deref->location = expr_node->location;
[7ecbb7e]435 deref->get_args().push_back( maybeMoveBuild< Expression >(expr_node) );
[a2e0687]436 UntypedMemberExpr * ret = new UntypedMemberExpr( member, deref );
[064e3ff]437 return ret;
[a2e0687]438} // build_pfieldSel
[064e3ff]439
[a2e0687]440Expression * build_offsetOf( DeclarationNode * decl_node, NameExpr * member ) {
[a7c90d4]441 Expression * ret = new UntypedOffsetofExpr( maybeMoveBuildType( decl_node ), member->get_name() );
[ac71a86]442 delete member;
443 return ret;
[a2e0687]444} // build_offsetOf
[064e3ff]445
[a2e0687]446Expression * build_and_or( ExpressionNode * expr_node1, ExpressionNode * expr_node2, bool kind ) {
[7ecbb7e]447 return new LogicalExpr( notZeroExpr( maybeMoveBuild< Expression >(expr_node1) ), notZeroExpr( maybeMoveBuild< Expression >(expr_node2) ), kind );
[a2e0687]448} // build_and_or
[51e076e]449
[a2e0687]450Expression * build_unary_val( OperKinds op, ExpressionNode * expr_node ) {
[f43df73]451 list< Expression * > args;
[7ecbb7e]452 args.push_back( maybeMoveBuild< Expression >(expr_node) );
[d9e2280]453 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
[a2e0687]454} // build_unary_val
455
456Expression * build_unary_ptr( OperKinds op, ExpressionNode * expr_node ) {
[f43df73]457 list< Expression * > args;
[cccc534]458 args.push_back( maybeMoveBuild< Expression >(expr_node) ); // xxx -- this is exactly the same as the val case now, refactor this code.
[d9e2280]459 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
[a2e0687]460} // build_unary_ptr
461
462Expression * build_binary_val( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
[f43df73]463 list< Expression * > args;
[7ecbb7e]464 args.push_back( maybeMoveBuild< Expression >(expr_node1) );
465 args.push_back( maybeMoveBuild< Expression >(expr_node2) );
[d9e2280]466 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
[a2e0687]467} // build_binary_val
468
469Expression * build_binary_ptr( OperKinds op, ExpressionNode * expr_node1, ExpressionNode * expr_node2 ) {
[f43df73]470 list< Expression * > args;
[cda7889]471 args.push_back( maybeMoveBuild< Expression >(expr_node1) );
[7ecbb7e]472 args.push_back( maybeMoveBuild< Expression >(expr_node2) );
[d9e2280]473 return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
[a2e0687]474} // build_binary_ptr
[51e076e]475
[a2e0687]476Expression * build_cond( ExpressionNode * expr_node1, ExpressionNode * expr_node2, ExpressionNode * expr_node3 ) {
[7ecbb7e]477 return new ConditionalExpr( notZeroExpr( maybeMoveBuild< Expression >(expr_node1) ), maybeMoveBuild< Expression >(expr_node2), maybeMoveBuild< Expression >(expr_node3) );
[a2e0687]478} // build_cond
[51e076e]479
[a2e0687]480Expression * build_tuple( ExpressionNode * expr_node ) {
[f43df73]481 list< Expression * > exprs;
[907eccb]482 buildMoveList( expr_node, exprs );
483 return new UntypedTupleExpr( exprs );;
[a2e0687]484} // build_tuple
[9706554]485
[a2e0687]486Expression * build_func( ExpressionNode * function, ExpressionNode * expr_node ) {
[f43df73]487 list< Expression * > args;
[7ecbb7e]488 buildMoveList( expr_node, args );
[bf4b4cf]489 return new UntypedExpr( maybeMoveBuild< Expression >(function), args );
[a2e0687]490} // build_func
[9706554]491
[a2e0687]492Expression * build_compoundLiteral( DeclarationNode * decl_node, InitializerNode * kids ) {
[7880579]493 Declaration * newDecl = maybeBuild< Declaration >(decl_node); // compound literal type
[630a82a]494 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
[7ecbb7e]495 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeMoveBuild< Initializer >(kids) );
[630a82a]496 // these types do not have associated type information
497 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) {
[fbcde64]498 if ( newDeclStructDecl->has_body() ) {
499 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl ), maybeMoveBuild< Initializer >(kids) );
500 } else {
501 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeMoveBuild< Initializer >(kids) );
502 } // if
[630a82a]503 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) {
[fbcde64]504 if ( newDeclUnionDecl->has_body() ) {
505 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl ), maybeMoveBuild< Initializer >(kids) );
506 } else {
507 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeMoveBuild< Initializer >(kids) );
508 } // if
[630a82a]509 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) {
[fbcde64]510 if ( newDeclEnumDecl->has_body() ) {
511 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl ), maybeMoveBuild< Initializer >(kids) );
512 } else {
513 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeMoveBuild< Initializer >(kids) );
514 } // if
[630a82a]515 } else {
516 assert( false );
517 } // if
[a2e0687]518} // build_compoundLiteral
[630a82a]519
[b87a5ed]520// Local Variables: //
521// tab-width: 4 //
522// mode: c++ //
523// compile-command: "make install" //
524// End: //
Note: See TracBrowser for help on using the repository browser.