| 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 | //
 | 
|---|
| 7 | // ExpressionNode.cc --
 | 
|---|
| 8 | //
 | 
|---|
| 9 | // Author           : Rodolfo G. Esteves
 | 
|---|
| 10 | // Created On       : Sat May 16 13:17:07 2015
 | 
|---|
| 11 | // Last Modified By : Peter A. Buhr
 | 
|---|
| 12 | // Last Modified On : Wed Jun 21 16:44:46 2017
 | 
|---|
| 13 | // Update Count     : 541
 | 
|---|
| 14 | //
 | 
|---|
| 15 | 
 | 
|---|
| 16 | #include <cassert>
 | 
|---|
| 17 | #include <cctype>
 | 
|---|
| 18 | #include <climits>
 | 
|---|
| 19 | #include <cstdio>
 | 
|---|
| 20 | #include <algorithm>
 | 
|---|
| 21 | #include <sstream>
 | 
|---|
| 22 | 
 | 
|---|
| 23 | #include "ParseNode.h"
 | 
|---|
| 24 | #include "TypeData.h"
 | 
|---|
| 25 | #include "SynTree/Constant.h"
 | 
|---|
| 26 | #include "SynTree/Expression.h"
 | 
|---|
| 27 | #include "SynTree/Declaration.h"
 | 
|---|
| 28 | #include "Common/UnimplementedError.h"
 | 
|---|
| 29 | #include "parseutility.h"
 | 
|---|
| 30 | #include "Common/utility.h"
 | 
|---|
| 31 | 
 | 
|---|
| 32 | using namespace std;
 | 
|---|
| 33 | 
 | 
|---|
| 34 | //##############################################################################
 | 
|---|
| 35 | 
 | 
|---|
| 36 | // Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
 | 
|---|
| 37 | //
 | 
|---|
| 38 | //              prefix action constant action suffix
 | 
|---|
| 39 | //
 | 
|---|
| 40 | // Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
 | 
|---|
| 41 | //
 | 
|---|
| 42 | //              constant BEGIN CONT ...
 | 
|---|
| 43 | //              <CONT>(...)? BEGIN 0 ... // possible empty suffix
 | 
|---|
| 44 | //
 | 
|---|
| 45 | // because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
 | 
|---|
| 46 | // type.
 | 
|---|
| 47 | 
 | 
|---|
| 48 | Type::Qualifiers emptyQualifiers;                               // no qualifiers on constants
 | 
|---|
| 49 | 
 | 
|---|
| 50 | static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
 | 
|---|
| 51 | static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
 | 
|---|
| 52 | static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
 | 
|---|
| 53 | static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
 | 
|---|
| 54 | static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
 | 
|---|
| 55 | static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
 | 
|---|
| 56 | 
 | 
|---|
| 57 | Expression *build_constantInteger( const std::string & str ) {
 | 
|---|
| 58 |         static const BasicType::Kind kind[2][3] = {
 | 
|---|
| 59 |                 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
 | 
|---|
| 60 |                 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
 | 
|---|
| 61 |         };
 | 
|---|
| 62 |         bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
 | 
|---|
| 63 |         int size;                                                                                       // 0 => int, 1 => long, 2 => long long
 | 
|---|
| 64 |         unsigned long long int v;                                                               // converted integral value
 | 
|---|
| 65 |         size_t last = str.length() - 1;                                         // last character of constant
 | 
|---|
| 66 | 
 | 
|---|
| 67 |         if ( str[0] == '0' ) {                                                          // octal/hex constant ?
 | 
|---|
| 68 |                 dec = false;
 | 
|---|
| 69 |                 if ( last != 0 && checkX( str[1] ) ) {                  // hex constant ?
 | 
|---|
| 70 |                         sscanf( (char *)str.c_str(), "%llx", &v );
 | 
|---|
| 71 |                         //printf( "%llx %llu\n", v, v );
 | 
|---|
| 72 |                 } else {                                                                                // octal constant
 | 
|---|
| 73 |                         sscanf( (char *)str.c_str(), "%llo", &v );
 | 
|---|
| 74 |                         //printf( "%llo %llu\n", v, v );
 | 
|---|
| 75 |                 } // if
 | 
|---|
| 76 |         } else {                                                                                        // decimal constant ?
 | 
|---|
| 77 |                 sscanf( (char *)str.c_str(), "%llu", &v );
 | 
|---|
| 78 |                 //printf( "%llu %llu\n", v, v );
 | 
|---|
| 79 |         } // if
 | 
|---|
| 80 | 
 | 
|---|
| 81 |         if ( v <= INT_MAX ) {                                                           // signed int
 | 
|---|
| 82 |                 size = 0;
 | 
|---|
| 83 |         } else if ( v <= UINT_MAX && ! dec ) {                          // unsigned int
 | 
|---|
| 84 |                 size = 0;
 | 
|---|
| 85 |                 Unsigned = true;                                                                // unsigned
 | 
|---|
| 86 |         } else if ( v <= LONG_MAX ) {                                           // signed long int
 | 
|---|
| 87 |                 size = 1;
 | 
|---|
| 88 |         } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
 | 
|---|
| 89 |                 size = 1;
 | 
|---|
| 90 |                 Unsigned = true;                                                                // unsigned long int
 | 
|---|
| 91 |         } else if ( v <= LLONG_MAX ) {                                          // signed long long int
 | 
|---|
| 92 |                 size = 2;
 | 
|---|
| 93 |         } else {                                                                                        // unsigned long long int
 | 
|---|
| 94 |                 size = 2;
 | 
|---|
| 95 |                 Unsigned = true;                                                                // unsigned long long int
 | 
|---|
| 96 |         } // if
 | 
|---|
| 97 | 
 | 
|---|
| 98 |         if ( checkU( str[last] ) ) {                                            // suffix 'u' ?
 | 
|---|
| 99 |                 Unsigned = true;
 | 
|---|
| 100 |                 if ( last > 0 && checkL( str[last - 1] ) ) {    // suffix 'l' ?
 | 
|---|
| 101 |                         size = 1;
 | 
|---|
| 102 |                         if ( last > 1 && checkL( str[last - 2] ) ) { // suffix 'll' ?
 | 
|---|
| 103 |                                 size = 2;
 | 
|---|
| 104 |                         } // if
 | 
|---|
| 105 |                 } // if
 | 
|---|
| 106 |         } else if ( checkL( str[ last ] ) ) {                           // suffix 'l' ?
 | 
|---|
| 107 |                 size = 1;
 | 
|---|
| 108 |                 if ( last > 0 && checkL( str[last - 1] ) ) {    // suffix 'll' ?
 | 
|---|
| 109 |                         size = 2;
 | 
|---|
| 110 |                         if ( last > 1 && checkU( str[last - 2] ) ) { // suffix 'u' ?
 | 
|---|
| 111 |                                 Unsigned = true;
 | 
|---|
| 112 |                         } // if
 | 
|---|
| 113 |                 } else {
 | 
|---|
| 114 |                         if ( last > 0 && checkU( str[last - 1] ) ) { // suffix 'u' ?
 | 
|---|
| 115 |                                 Unsigned = true;
 | 
|---|
| 116 |                         } // if
 | 
|---|
| 117 |                 } // if
 | 
|---|
| 118 |         } // if
 | 
|---|
| 119 | 
 | 
|---|
| 120 |         Expression * ret = new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[Unsigned][size] ), str, v ) );
 | 
|---|
| 121 |         delete &str;                                                                            // created by lex
 | 
|---|
| 122 |         return ret;
 | 
|---|
| 123 | } // build_constantInteger
 | 
|---|
| 124 | 
 | 
|---|
| 125 | Expression *build_constantFloat( const std::string & str ) {
 | 
|---|
| 126 |         static const BasicType::Kind kind[2][3] = {
 | 
|---|
| 127 |                 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
 | 
|---|
| 128 |                 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
 | 
|---|
| 129 |         };
 | 
|---|
| 130 | 
 | 
|---|
| 131 |         bool complx = false;                                                            // real, complex
 | 
|---|
| 132 |         int size = 1;                                                                           // 0 => float, 1 => double (default), 2 => long double
 | 
|---|
| 133 |         // floating-point constant has minimum of 2 characters: 1. or .1
 | 
|---|
| 134 |         size_t last = str.length() - 1;
 | 
|---|
| 135 |         double v;
 | 
|---|
| 136 | 
 | 
|---|
| 137 |         sscanf( str.c_str(), "%lg", &v );
 | 
|---|
| 138 | 
 | 
|---|
| 139 |         if ( checkI( str[last] ) ) {                                            // imaginary ?
 | 
|---|
| 140 |                 complx = true;
 | 
|---|
| 141 |                 last -= 1;                                                                              // backup one character
 | 
|---|
| 142 |         } // if
 | 
|---|
| 143 | 
 | 
|---|
| 144 |         if ( checkF( str[last] ) ) {                                            // float ?
 | 
|---|
| 145 |                 size = 0;
 | 
|---|
| 146 |         } else if ( checkD( str[last] ) ) {                                     // double ?
 | 
|---|
| 147 |                 size = 1;
 | 
|---|
| 148 |         } else if ( checkL( str[last] ) ) {                                     // long double ?
 | 
|---|
| 149 |                 size = 2;
 | 
|---|
| 150 |         } // if
 | 
|---|
| 151 |         if ( ! complx && checkI( str[last - 1] ) ) {            // imaginary ?
 | 
|---|
| 152 |                 complx = true;
 | 
|---|
| 153 |         } // if
 | 
|---|
| 154 | 
 | 
|---|
| 155 |         Expression * ret = new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[complx][size] ), str, v ) );
 | 
|---|
| 156 |         delete &str;                                                                            // created by lex
 | 
|---|
| 157 |         return ret;
 | 
|---|
| 158 | } // build_constantFloat
 | 
|---|
| 159 | 
 | 
|---|
| 160 | Expression *build_constantChar( const std::string & str ) {
 | 
|---|
| 161 |         Expression * ret = new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::Char ), str, (unsigned long long int)(unsigned char)str[1] ) );
 | 
|---|
| 162 |         delete &str;                                                                            // created by lex
 | 
|---|
| 163 |         return ret;
 | 
|---|
| 164 | } // build_constantChar
 | 
|---|
| 165 | 
 | 
|---|
| 166 | ConstantExpr *build_constantStr( const std::string & str ) {
 | 
|---|
| 167 |         // string should probably be a primitive type
 | 
|---|
| 168 |         ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ),
 | 
|---|
| 169 |                                                                    new ConstantExpr( Constant::from_ulong( str.size() + 1 - 2 ) ),  // +1 for '\0' and -2 for '"'
 | 
|---|
| 170 |                                                                    false, false );
 | 
|---|
| 171 |         // constant 0 is ignored for pure string value
 | 
|---|
| 172 |         ConstantExpr * ret = new ConstantExpr( Constant( at, str, (unsigned long long int)0 ) );
 | 
|---|
| 173 |         delete &str;                                                                            // created by lex
 | 
|---|
| 174 |         return ret;
 | 
|---|
| 175 | } // build_constantStr
 | 
|---|
| 176 | 
 | 
|---|
| 177 | Expression *build_constantZeroOne( const std::string & str ) {
 | 
|---|
| 178 |         Expression * ret = new ConstantExpr( Constant( str == "0" ? (Type *)new ZeroType( emptyQualifiers ) : (Type*)new OneType( emptyQualifiers ), str,
 | 
|---|
| 179 |                                                                                                    str == "0" ? (unsigned long long int)0 : (unsigned long long int)1 ) );
 | 
|---|
| 180 |         delete &str;                                                                            // created by lex
 | 
|---|
| 181 |         return ret;
 | 
|---|
| 182 | } // build_constantChar
 | 
|---|
| 183 | 
 | 
|---|
| 184 | Expression * build_field_name_FLOATINGconstant( const std::string & str ) {
 | 
|---|
| 185 |         // str is of the form A.B -> separate at the . and return member expression
 | 
|---|
| 186 |         int a, b;
 | 
|---|
| 187 |         char dot;
 | 
|---|
| 188 |         std::stringstream ss( str );
 | 
|---|
| 189 |         ss >> a >> dot >> b;
 | 
|---|
| 190 |         UntypedMemberExpr * ret = new UntypedMemberExpr( new ConstantExpr( Constant::from_int( b ) ), new ConstantExpr( Constant::from_int( a ) ) );
 | 
|---|
| 191 |         delete &str;
 | 
|---|
| 192 |         return ret;
 | 
|---|
| 193 | } // build_field_name_FLOATINGconstant
 | 
|---|
| 194 | 
 | 
|---|
| 195 | Expression * make_field_name_fraction_constants( Expression * fieldName, Expression * fracts ) {
 | 
|---|
| 196 |         if ( fracts ) {
 | 
|---|
| 197 |                 if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( fracts ) ) {
 | 
|---|
| 198 |                         memberExpr->set_member( make_field_name_fraction_constants( fieldName, memberExpr->get_aggregate() ) );
 | 
|---|
| 199 |                         return memberExpr;
 | 
|---|
| 200 |                 } else {
 | 
|---|
| 201 |                         return new UntypedMemberExpr( fracts, fieldName );
 | 
|---|
| 202 |                 }
 | 
|---|
| 203 |         }
 | 
|---|
| 204 |         return fieldName;
 | 
|---|
| 205 | } // make_field_name_fraction_constants
 | 
|---|
| 206 | 
 | 
|---|
| 207 | Expression * build_field_name_fraction_constants( Expression * fieldName, ExpressionNode * fracts ) {
 | 
|---|
| 208 |         return make_field_name_fraction_constants( fieldName, maybeMoveBuild< Expression >( fracts ) );
 | 
|---|
| 209 | } // build_field_name_fraction_constants
 | 
|---|
| 210 | 
 | 
|---|
| 211 | 
 | 
|---|
| 212 | 
 | 
|---|
| 213 | Expression * build_field_name_REALFRACTIONconstant( const std::string & str ) {
 | 
|---|
| 214 |         if ( str.find_first_not_of( "0123456789", 1 ) != string::npos ) throw SemanticError( "invalid tuple index " + str );
 | 
|---|
| 215 |         Expression * ret = build_constantInteger( *new std::string( str.substr(1) ) );
 | 
|---|
| 216 |         delete &str;
 | 
|---|
| 217 |         return ret;
 | 
|---|
| 218 | } // build_field_name_REALFRACTIONconstant
 | 
|---|
| 219 | 
 | 
|---|
| 220 | Expression * build_field_name_REALDECIMALconstant( const std::string & str ) {
 | 
|---|
| 221 |         if ( str[str.size()-1] != '.' ) throw SemanticError( "invalid tuple index " + str );
 | 
|---|
| 222 |         Expression * ret = build_constantInteger( *new std::string( str.substr( 0, str.size()-1 ) ) );
 | 
|---|
| 223 |         delete &str;
 | 
|---|
| 224 |         return ret;
 | 
|---|
| 225 | } // build_field_name_REALDECIMALconstant
 | 
|---|
| 226 | 
 | 
|---|
| 227 | NameExpr * build_varref( const string *name ) {
 | 
|---|
| 228 |         NameExpr *expr = new NameExpr( *name, nullptr );
 | 
|---|
| 229 |         delete name;
 | 
|---|
| 230 |         return expr;
 | 
|---|
| 231 | }
 | 
|---|
| 232 | 
 | 
|---|
| 233 | static const char *OperName[] = {
 | 
|---|
| 234 |         // diadic
 | 
|---|
| 235 |         "SizeOf", "AlignOf", "OffsetOf", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
 | 
|---|
| 236 |         "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
 | 
|---|
| 237 |         "?=?", "?@=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
 | 
|---|
| 238 |         "?[?]", "...",
 | 
|---|
| 239 |         // monadic
 | 
|---|
| 240 |         "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
 | 
|---|
| 241 | };
 | 
|---|
| 242 | 
 | 
|---|
| 243 | Expression *build_cast( DeclarationNode *decl_node, ExpressionNode *expr_node ) {
 | 
|---|
| 244 |         Type *targetType = maybeMoveBuildType( decl_node );
 | 
|---|
| 245 |         if ( dynamic_cast< VoidType * >( targetType ) ) {
 | 
|---|
| 246 |                 delete targetType;
 | 
|---|
| 247 |                 return new CastExpr( maybeMoveBuild< Expression >(expr_node) );
 | 
|---|
| 248 |         } else {
 | 
|---|
| 249 |                 return new CastExpr( maybeMoveBuild< Expression >(expr_node), targetType );
 | 
|---|
| 250 |         } // if
 | 
|---|
| 251 | }
 | 
|---|
| 252 | 
 | 
|---|
| 253 | Expression *build_fieldSel( ExpressionNode *expr_node, Expression *member ) {
 | 
|---|
| 254 |         UntypedMemberExpr *ret = new UntypedMemberExpr( member, maybeMoveBuild< Expression >(expr_node) );
 | 
|---|
| 255 |         return ret;
 | 
|---|
| 256 | }
 | 
|---|
| 257 | 
 | 
|---|
| 258 | Expression *build_pfieldSel( ExpressionNode *expr_node, Expression *member ) {
 | 
|---|
| 259 |         UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
 | 
|---|
| 260 |         deref->location = expr_node->location;
 | 
|---|
| 261 |         deref->get_args().push_back( maybeMoveBuild< Expression >(expr_node) );
 | 
|---|
| 262 |         UntypedMemberExpr *ret = new UntypedMemberExpr( member, deref );
 | 
|---|
| 263 |         return ret;
 | 
|---|
| 264 | }
 | 
|---|
| 265 | 
 | 
|---|
| 266 | Expression *build_addressOf( ExpressionNode *expr_node ) {
 | 
|---|
| 267 |                 return new AddressExpr( maybeMoveBuild< Expression >(expr_node) );
 | 
|---|
| 268 | }
 | 
|---|
| 269 | Expression *build_sizeOfexpr( ExpressionNode *expr_node ) {
 | 
|---|
| 270 |         return new SizeofExpr( maybeMoveBuild< Expression >(expr_node) );
 | 
|---|
| 271 | }
 | 
|---|
| 272 | Expression *build_sizeOftype( DeclarationNode *decl_node ) {
 | 
|---|
| 273 |         return new SizeofExpr( maybeMoveBuildType( decl_node ) );
 | 
|---|
| 274 | }
 | 
|---|
| 275 | Expression *build_alignOfexpr( ExpressionNode *expr_node ) {
 | 
|---|
| 276 |         return new AlignofExpr( maybeMoveBuild< Expression >(expr_node) );
 | 
|---|
| 277 | }
 | 
|---|
| 278 | Expression *build_alignOftype( DeclarationNode *decl_node ) {
 | 
|---|
| 279 |         return new AlignofExpr( maybeMoveBuildType( decl_node) );
 | 
|---|
| 280 | }
 | 
|---|
| 281 | Expression *build_offsetOf( DeclarationNode *decl_node, NameExpr *member ) {
 | 
|---|
| 282 |         Expression * ret = new UntypedOffsetofExpr( maybeMoveBuildType( decl_node ), member->get_name() );
 | 
|---|
| 283 |         delete member;
 | 
|---|
| 284 |         return ret;
 | 
|---|
| 285 | }
 | 
|---|
| 286 | 
 | 
|---|
| 287 | Expression *build_and_or( ExpressionNode *expr_node1, ExpressionNode *expr_node2, bool kind ) {
 | 
|---|
| 288 |         return new LogicalExpr( notZeroExpr( maybeMoveBuild< Expression >(expr_node1) ), notZeroExpr( maybeMoveBuild< Expression >(expr_node2) ), kind );
 | 
|---|
| 289 | }
 | 
|---|
| 290 | 
 | 
|---|
| 291 | Expression *build_unary_val( OperKinds op, ExpressionNode *expr_node ) {
 | 
|---|
| 292 |         std::list< Expression * > args;
 | 
|---|
| 293 |         args.push_back( maybeMoveBuild< Expression >(expr_node) );
 | 
|---|
| 294 |         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
 | 
|---|
| 295 | }
 | 
|---|
| 296 | Expression *build_unary_ptr( OperKinds op, ExpressionNode *expr_node ) {
 | 
|---|
| 297 |         std::list< Expression * > args;
 | 
|---|
| 298 |         args.push_back( new AddressExpr( maybeMoveBuild< Expression >(expr_node) ) );
 | 
|---|
| 299 |         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
 | 
|---|
| 300 | }
 | 
|---|
| 301 | Expression *build_binary_val( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
 | 
|---|
| 302 |         std::list< Expression * > args;
 | 
|---|
| 303 |         args.push_back( maybeMoveBuild< Expression >(expr_node1) );
 | 
|---|
| 304 |         args.push_back( maybeMoveBuild< Expression >(expr_node2) );
 | 
|---|
| 305 |         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
 | 
|---|
| 306 | }
 | 
|---|
| 307 | Expression *build_binary_ptr( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
 | 
|---|
| 308 |         std::list< Expression * > args;
 | 
|---|
| 309 |         args.push_back( new AddressExpr( maybeMoveBuild< Expression >(expr_node1) ) );
 | 
|---|
| 310 |         args.push_back( maybeMoveBuild< Expression >(expr_node2) );
 | 
|---|
| 311 |         return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
 | 
|---|
| 312 | }
 | 
|---|
| 313 | 
 | 
|---|
| 314 | Expression *build_cond( ExpressionNode *expr_node1, ExpressionNode *expr_node2, ExpressionNode *expr_node3 ) {
 | 
|---|
| 315 |         return new ConditionalExpr( notZeroExpr( maybeMoveBuild< Expression >(expr_node1) ), maybeMoveBuild< Expression >(expr_node2), maybeMoveBuild< Expression >(expr_node3) );
 | 
|---|
| 316 | }
 | 
|---|
| 317 | 
 | 
|---|
| 318 | Expression *build_comma( ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
 | 
|---|
| 319 |         return new CommaExpr( maybeMoveBuild< Expression >(expr_node1), maybeMoveBuild< Expression >(expr_node2) );
 | 
|---|
| 320 | }
 | 
|---|
| 321 | 
 | 
|---|
| 322 | Expression *build_attrexpr( NameExpr *var, ExpressionNode * expr_node ) {
 | 
|---|
| 323 |         return new AttrExpr( var, maybeMoveBuild< Expression >(expr_node) );
 | 
|---|
| 324 | }
 | 
|---|
| 325 | Expression *build_attrtype( NameExpr *var, DeclarationNode * decl_node ) {
 | 
|---|
| 326 |         return new AttrExpr( var, maybeMoveBuildType( decl_node ) );
 | 
|---|
| 327 | }
 | 
|---|
| 328 | 
 | 
|---|
| 329 | Expression *build_tuple( ExpressionNode * expr_node ) {
 | 
|---|
| 330 |         std::list< Expression * > exprs;
 | 
|---|
| 331 |         buildMoveList( expr_node, exprs );
 | 
|---|
| 332 |         return new UntypedTupleExpr( exprs );;
 | 
|---|
| 333 | }
 | 
|---|
| 334 | 
 | 
|---|
| 335 | Expression *build_func( ExpressionNode * function, ExpressionNode * expr_node ) {
 | 
|---|
| 336 |         std::list< Expression * > args;
 | 
|---|
| 337 |         buildMoveList( expr_node, args );
 | 
|---|
| 338 |         return new UntypedExpr( maybeMoveBuild< Expression >(function), args, nullptr );
 | 
|---|
| 339 | }
 | 
|---|
| 340 | 
 | 
|---|
| 341 | Expression *build_range( ExpressionNode * low, ExpressionNode *high ) {
 | 
|---|
| 342 |         return new RangeExpr( maybeMoveBuild< Expression >( low ), maybeMoveBuild< Expression >( high ) );
 | 
|---|
| 343 | }
 | 
|---|
| 344 | 
 | 
|---|
| 345 | Expression *build_asmexpr( ExpressionNode *inout, ConstantExpr *constraint, ExpressionNode *operand ) {
 | 
|---|
| 346 |         return new AsmExpr( maybeMoveBuild< Expression >( inout ), constraint, maybeMoveBuild< Expression >(operand) );
 | 
|---|
| 347 | }
 | 
|---|
| 348 | 
 | 
|---|
| 349 | Expression *build_valexpr( StatementNode *s ) {
 | 
|---|
| 350 |         return new StmtExpr( dynamic_cast< CompoundStmt * >(maybeMoveBuild< Statement >(s) ) );
 | 
|---|
| 351 | }
 | 
|---|
| 352 | Expression *build_typevalue( DeclarationNode *decl ) {
 | 
|---|
| 353 |         return new TypeExpr( maybeMoveBuildType( decl ) );
 | 
|---|
| 354 | }
 | 
|---|
| 355 | 
 | 
|---|
| 356 | Expression *build_compoundLiteral( DeclarationNode *decl_node, InitializerNode *kids ) {
 | 
|---|
| 357 |         Declaration * newDecl = maybeBuild< Declaration >(decl_node); // compound literal type
 | 
|---|
| 358 |         if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
 | 
|---|
| 359 |                 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeMoveBuild< Initializer >(kids) );
 | 
|---|
| 360 |         // these types do not have associated type information
 | 
|---|
| 361 |         } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl )  ) {
 | 
|---|
| 362 |                 if ( newDeclStructDecl->has_body() ) {
 | 
|---|
| 363 |                         return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl ), maybeMoveBuild< Initializer >(kids) );
 | 
|---|
| 364 |                 } else {
 | 
|---|
| 365 |                         return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeMoveBuild< Initializer >(kids) );
 | 
|---|
| 366 |                 } // if
 | 
|---|
| 367 |         } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl )  ) {
 | 
|---|
| 368 |                 if ( newDeclUnionDecl->has_body() ) {
 | 
|---|
| 369 |                         return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl ), maybeMoveBuild< Initializer >(kids) );
 | 
|---|
| 370 |                 } else {
 | 
|---|
| 371 |                         return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeMoveBuild< Initializer >(kids) );
 | 
|---|
| 372 |                 } // if
 | 
|---|
| 373 |         } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl )  ) {
 | 
|---|
| 374 |                 if ( newDeclEnumDecl->has_body() ) {
 | 
|---|
| 375 |                         return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl ), maybeMoveBuild< Initializer >(kids) );
 | 
|---|
| 376 |                 } else {
 | 
|---|
| 377 |                         return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeMoveBuild< Initializer >(kids) );
 | 
|---|
| 378 |                 } // if
 | 
|---|
| 379 |         } else {
 | 
|---|
| 380 |                 assert( false );
 | 
|---|
| 381 |         } // if
 | 
|---|
| 382 | }
 | 
|---|
| 383 | 
 | 
|---|
| 384 | // Local Variables: //
 | 
|---|
| 385 | // tab-width: 4 //
 | 
|---|
| 386 | // mode: c++ //
 | 
|---|
| 387 | // compile-command: "make install" //
 | 
|---|
| 388 | // End: //
 | 
|---|