source: src/Parser/ExpressionNode.cc @ bf4b4cf

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since bf4b4cf was bf4b4cf, checked in by Rob Schluntz <rschlunt@…>, 7 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==
[51b7345]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;
[51b7345]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
[51b7345]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 );
[51b7345]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
[51b7345]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
[51b7345]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
[51b7345]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
[51b7345]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.