source: src/Parser/ExpressionNode.cc@ 2edd5502

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors ctor deferred_resn demangler enum forall-pointer-decay gc_noraii jacob/cs343-translation jenkins-sandbox memory 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 2edd5502 was 630a82a, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

C99 compound literals now work, comment rational code, clean up hoisting AddVisit

  • Property mode set to 100644
File size: 28.9 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//
7// ExpressionNode.cc --
8//
9// Author : Rodolfo G. Esteves
10// Created On : Sat May 16 13:17:07 2015
[097e2b0]11// Last Modified By : Peter A. Buhr
[630a82a]12// Last Modified On : Fri Apr 8 15:43:05 2016
13// Update Count : 296
[b87a5ed]14//
15
[51b73452]16#include <cassert>
17#include <cctype>
18#include <algorithm>
[59db689]19#include <sstream>
20#include <cstdio>
21#include <climits>
[51b73452]22
23#include "ParseNode.h"
[630a82a]24#include "TypeData.h"
[51b73452]25#include "SynTree/Constant.h"
26#include "SynTree/Expression.h"
[630a82a]27#include "SynTree/Declaration.h"
[d3b7937]28#include "Common/UnimplementedError.h"
[51b73452]29#include "parseutility.h"
[d3b7937]30#include "Common/utility.h"
[51b73452]31
32using namespace std;
33
[3848e0e]34ExpressionNode::ExpressionNode() : ParseNode(), argName( 0 ) {}
[51b73452]35
[e869d663]36ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ), argName( 0 ) {}
[51b73452]37
[3848e0e]38ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ) {
[b87a5ed]39 if ( other.argName ) {
40 argName = other.argName->clone();
41 } else {
42 argName = 0;
43 } // if
[51b73452]44}
45
[7f5566b]46ExpressionNode * ExpressionNode::set_argName( const std::string *aName ) {
[b87a5ed]47 argName = new VarRefNode( aName );
48 return this;
[51b73452]49}
50
[7f5566b]51ExpressionNode * ExpressionNode::set_argName( ExpressionNode *aDesignator ) {
[b87a5ed]52 argName = aDesignator;
53 return this;
[51b73452]54}
55
56void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
[b87a5ed]57 if ( argName ) {
[59db689]58 os << string( indent, ' ' ) << "(designated by: ";
[b87a5ed]59 argName->printOneLine( os, indent );
60 os << ")" << std::endl;
61 } // if
[51b73452]62}
63
[cd623a4]64//##############################################################################
65
[3848e0e]66NullExprNode::NullExprNode() {}
[51b73452]67
[3848e0e]68NullExprNode *NullExprNode::clone() const {
[b87a5ed]69 return new NullExprNode();
[51b73452]70}
71
[bdd516a]72void NullExprNode::print( std::ostream & os, int indent ) const {
[b87a5ed]73 printDesignation( os );
74 os << "null expression";
[51b73452]75}
76
[bdd516a]77void NullExprNode::printOneLine( std::ostream & os, int indent ) const {
[b87a5ed]78 printDesignation( os );
79 os << "null";
[51b73452]80}
81
[3848e0e]82Expression *NullExprNode::build() const {
[b87a5ed]83 return 0;
[51b73452]84}
85
[a08ba92]86CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
[b87a5ed]87 return new CommaExprNode( this, exp );
[51b73452]88}
89
[cd623a4]90//##############################################################################
91
92static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
93static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
94static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
[5721a6d]95static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
96static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
[cd623a4]97static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
98
[5f2f2d7]99// Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
[cd623a4]100//
101// prefix action constant action suffix
102//
103// Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
104//
105// constant BEGIN CONT ...
106// <CONT>(...)? BEGIN 0 ... // possible empty suffix
107//
108// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
109// type.
[51b73452]110
[59db689]111ConstantNode::ConstantNode( Type t, string *inVal ) : type( t ), value( *inVal ) {
[cd623a4]112 // lexing divides constants into 4 kinds
[a08ba92]113 switch ( type ) {
[59db689]114 case Integer:
[b87a5ed]115 {
[59db689]116 static const BasicType::Kind kind[2][3] = {
117 { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
118 { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
119 };
120 bool dec = true, Unsigned = false; // decimal, unsigned constant
121 int size; // 0 => int, 1 => long, 2 => long long
[5721a6d]122 unsigned long long v; // converted integral value
123 size_t last = value.length() - 1; // last character of constant
[59db689]124
[cd623a4]125 if ( value[0] == '0' ) { // octal constant ?
[59db689]126 dec = false;
[cd623a4]127 if ( last != 0 && checkX( value[1] ) ) { // hex constant ?
[59db689]128 sscanf( (char *)value.c_str(), "%llx", &v );
129 //printf( "%llx %llu\n", v, v );
130 } else {
131 sscanf( (char *)value.c_str(), "%llo", &v );
132 //printf( "%llo %llu\n", v, v );
133 } // if
[cd623a4]134 } else { // decimal constant ?
[5f2f2d7]135 sscanf( (char *)value.c_str(), "%llu", &v );
[59db689]136 //printf( "%llu %llu\n", v, v );
137 } // if
138
139 if ( v <= INT_MAX ) { // signed int
140 size = 0;
[5f2f2d7]141 } else if ( v <= UINT_MAX && ! dec ) { // unsigned int
[59db689]142 size = 0;
[5f2f2d7]143 Unsigned = true; // unsigned
[59db689]144 } else if ( v <= LONG_MAX ) { // signed long int
145 size = 1;
[5f2f2d7]146 } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
[59db689]147 size = 1;
[5f2f2d7]148 Unsigned = true; // unsigned long int
[59db689]149 } else if ( v <= LLONG_MAX ) { // signed long long int
150 size = 2;
[5f2f2d7]151 } else { // unsigned long long int
[59db689]152 size = 2;
[5f2f2d7]153 Unsigned = true; // unsigned long long int
[59db689]154 } // if
[51b73452]155
[cd623a4]156 if ( checkU( value[last] ) ) { // suffix 'u' ?
[59db689]157 Unsigned = true;
[5f2f2d7]158 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'l' ?
[59db689]159 size = 1;
[5f2f2d7]160 if ( last > 1 && checkL( value[ last - 2 ] ) ) { // suffix 'll' ?
[59db689]161 size = 2;
162 } // if
163 } // if
[cd623a4]164 } else if ( checkL( value[ last ] ) ) { // suffix 'l' ?
[59db689]165 size = 1;
[5f2f2d7]166 if ( last > 0 && checkL( value[ last - 1 ] ) ) { // suffix 'll' ?
[59db689]167 size = 2;
[5f2f2d7]168 if ( last > 1 && checkU( value[ last - 2 ] ) ) { // suffix 'u' ?
169 Unsigned = true;
170 } // if
171 } else {
172 if ( last > 0 && checkU( value[ last - 1 ] ) ) { // suffix 'u' ?
173 Unsigned = true;
174 } // if
[59db689]175 } // if
176 } // if
[cd623a4]177 btype = kind[Unsigned][size]; // lookup constant type
178 break;
179 }
180 case Float:
181 {
[5721a6d]182 static const BasicType::Kind kind[2][3] = {
183 { BasicType::Float, BasicType::Double, BasicType::LongDouble },
184 { BasicType::FloatComplex, BasicType::DoubleComplex, BasicType::LongDoubleComplex },
185 };
186 bool complx = false; // real, complex
187 int size = 1; // 0 => float, 1 => double (default), 2 => long double
188 // floating-point constant has minimum of 2 characters: 1. or .1
189 size_t last = value.length() - 1;
190
191 if ( checkI( value[last] ) ) { // imaginary ?
192 complx = true;
193 last -= 1; // backup one character
[cd623a4]194 } // if
[5721a6d]195 if ( checkF( value[last] ) ) { // float ?
196 size = 0;
197 } else if ( checkD( value[last] ) ) { // double ?
198 size = 1;
199 } else if ( checkL( value[last] ) ) { // long double ?
200 size = 2;
[cd623a4]201 } // if
[5721a6d]202 if ( ! complx && checkI( value[last - 1] ) ) { // imaginary ?
203 complx = true;
204 } // if
205 btype = kind[complx][size]; // lookup constant type
[b87a5ed]206 break;
207 }
[59db689]208 case Character:
209 btype = BasicType::Char; // default
210 if ( string( "LUu" ).find( value[0] ) != string::npos ) {
211 // ???
212 } // if
213 break;
214 case String:
215 // array of char
216 if ( string( "LUu" ).find( value[0] ) != string::npos ) {
217 if ( value[0] == 'u' && value[1] == '8' ) {
218 // ???
219 } else {
220 // ???
221 } // if
222 } // if
223 break;
224 } // switch
225} // ConstantNode::ConstantNode
[51b73452]226
[59db689]227ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
228 assert( newValue != 0 );
229 assert( type == String );
[51b73452]230
[7f5566b]231 // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
[59db689]232 value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
233
[cd623a4]234 delete newValue; // allocated by lexer
[b87a5ed]235 return this;
[51b73452]236}
237
[bdd516a]238void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
[59db689]239 os << string( indent, ' ' );
[b87a5ed]240 printDesignation( os );
241
242 switch ( type ) {
243 case Integer:
244 case Float:
245 os << value ;
246 break;
247 case Character:
248 os << "'" << value << "'";
249 break;
250 case String:
251 os << '"' << value << '"';
252 break;
[c7ed6d0]253 } // switch
[51b73452]254
[b87a5ed]255 os << ' ';
[51b73452]256}
257
[bdd516a]258void ConstantNode::print( std::ostream &os, int indent ) const {
[b87a5ed]259 printOneLine( os, indent );
260 os << endl;
[51b73452]261}
262
263Expression *ConstantNode::build() const {
[cd623a4]264 ::Type::Qualifiers q; // no qualifiers on constants
[b87a5ed]265
[59db689]266 switch ( get_type() ) {
[b87a5ed]267 case String:
[59db689]268 {
269 // string should probably be a primitive type
270 ArrayType *at = new ArrayType( q, new BasicType( q, BasicType::Char ),
271 new ConstantExpr(
272 Constant( new BasicType( q, BasicType::UnsignedInt ),
[ea9b9d3]273 toString( value.size()+1-2 ) ) ), // +1 for '\0' and -2 for '"'
[59db689]274 false, false );
275 return new ConstantExpr( Constant( at, value ), maybeBuild< Expression >( get_argName() ) );
276 }
277 default:
[cd623a4]278 return new ConstantExpr( Constant( new BasicType( q, btype ), get_value() ), maybeBuild< Expression >( get_argName() ) );
[b87a5ed]279 }
[51b73452]280}
281
[cd623a4]282//##############################################################################
283
[bdd516a]284VarRefNode::VarRefNode() : isLabel( false ) {}
[51b73452]285
[59db689]286VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {}
[51b73452]287
[3848e0e]288VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
[51b73452]289}
290
291Expression *VarRefNode::build() const {
[b87a5ed]292 return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
[51b73452]293}
294
[bdd516a]295void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]296 printDesignation( os );
297 os << get_name() << ' ';
[51b73452]298}
299
[bdd516a]300void VarRefNode::print( std::ostream &os, int indent ) const {
[b87a5ed]301 printDesignation( os );
[44b5ca0]302 os << string( indent, ' ' ) << "Referencing: ";
[b87a5ed]303 os << "Variable: " << get_name();
304 os << endl;
[51b73452]305}
306
[cd623a4]307//##############################################################################
308
[51b1202]309DesignatorNode::DesignatorNode( ExpressionNode *expr, bool isArrayIndex ) : isArrayIndex( isArrayIndex ) {
310 set_argName( expr );
[e869d663]311 assert( get_argName() );
312
313 if ( ! isArrayIndex ) {
314 if ( VarRefNode * var = dynamic_cast< VarRefNode * >( expr ) ) {
315
316 stringstream ss( var->get_name() );
317 double value;
318 if ( ss >> value ) {
319 // this is a floating point constant. It MUST be
320 // ".0" or ".1", otherwise the program is invalid
321 if ( ! (var->get_name() == ".0" || var->get_name() == ".1") ) {
322 throw SemanticError( "invalid designator name: " + var->get_name() );
323 } // if
324 var->set_name( var->get_name().substr(1) );
325 } // if
326 } // if
327 } // if
[51b1202]328}
329
330DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) {
331}
332
[e869d663]333class DesignatorFixer : public Mutator {
334public:
335 virtual Expression* mutate( NameExpr *nameExpr ) {
336 if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
337 Constant val( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nameExpr->get_name() );
338 delete nameExpr;
339 return new ConstantExpr( val );
340 }
341 return nameExpr;
342 }
343};
344
[51b1202]345Expression *DesignatorNode::build() const {
[e869d663]346 Expression * ret = get_argName()->build();
347
[51b1202]348 if ( isArrayIndex ) {
[e869d663]349 // need to traverse entire structure and change any instances of 0 or 1 to
350 // ConstantExpr
351 DesignatorFixer fixer;
352 ret = ret->acceptMutator( fixer );
[51b1202]353 } // if
[e869d663]354
355 return ret;
[51b1202]356}
357
358void DesignatorNode::printOneLine( std::ostream &os, int indent ) const {
359 if ( get_argName() ) {
360 if ( isArrayIndex ) {
361 os << "[";
362 get_argName()->printOneLine( os, indent );
363 os << "]";
364 } else {
365 os << ".";
366 get_argName()->printOneLine( os, indent );
367 }
368 } // if
369}
370
371void DesignatorNode::print( std::ostream &os, int indent ) const {
372 if ( get_argName() ) {
373 if ( isArrayIndex ) {
374 os << "[";
375 get_argName()->print( os, indent );
376 os << "]";
377 } else {
378 os << ".";
379 get_argName()->print( os, indent );
380 }
381 } // if
382}
383
384//##############################################################################
385
[5721a6d]386static const char *opName[] = {
387 "TupleC", "Comma", "TupleFieldSel", // "TuplePFieldSel", // n-adic
388 // triadic
389 "Cond", "NCond",
390 // diadic
391 "SizeOf", "AlignOf", "OffsetOf", "Attr", "CompLit", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
392 "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
393 "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
394 "?[?]", "FieldSel", "PFieldSel", "Range",
395 // monadic
396 "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
397};
398
[bdd516a]399OperatorNode::OperatorNode( Type t ) : type( t ) {}
[51b73452]400
[3848e0e]401OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
[51b73452]402}
403
404OperatorNode::~OperatorNode() {}
405
[bdd516a]406OperatorNode::Type OperatorNode::get_type( void ) const{
[b87a5ed]407 return type;
[51b73452]408}
409
[3848e0e]410void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]411 printDesignation( os );
[5721a6d]412 os << opName[ type ] << ' ';
[51b73452]413}
414
415void OperatorNode::print( std::ostream &os, int indent ) const{
[b87a5ed]416 printDesignation( os );
[5721a6d]417 os << string( indent, ' ' ) << "Operator: " << opName[type] << endl;
[b87a5ed]418 return;
[51b73452]419}
420
[59db689]421const char *OperatorNode::get_typename( void ) const{
[5721a6d]422 return opName[ type ];
[51b73452]423}
424
[cd623a4]425//##############################################################################
426
[7f5566b]427CompositeExprNode::CompositeExprNode() : ExpressionNode(), function( 0 ), arguments( 0 ) {
[51b73452]428}
429
[59db689]430CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
[51b73452]431}
432
[bdd516a]433CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
[b87a5ed]434 function( f ), arguments( args ) {
[51b73452]435}
436
[bdd516a]437CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
[097e2b0]438 function( f ), arguments( arg1 ) {
439 arguments->set_link( arg2 );
[51b73452]440}
441
[3848e0e]442CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ) {
[b87a5ed]443 ParseNode *cur = other.arguments;
444 while ( cur ) {
445 if ( arguments ) {
446 arguments->set_link( cur->clone() );
447 } else {
448 arguments = ( ExpressionNode*)cur->clone();
449 } // if
450 cur = cur->get_link();
451 }
[51b73452]452}
453
[3848e0e]454CompositeExprNode::~CompositeExprNode() {
[b87a5ed]455 delete function;
456 delete arguments;
[51b73452]457}
458
[d3b7937]459#include "Common/utility.h"
[51b73452]460
[3848e0e]461Expression *CompositeExprNode::build() const {
[b87a5ed]462 OperatorNode *op;
463 std::list<Expression *> args;
[51b73452]464
[b87a5ed]465 buildList( get_args(), args );
466
[cd623a4]467 if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
[b87a5ed]468 return new UntypedExpr( function->build(), args, maybeBuild< Expression >( get_argName() ));
[cd623a4]469 } // if
[b87a5ed]470
[cd623a4]471 switch ( op->get_type()) {
472 case OperatorNode::Incr:
473 case OperatorNode::Decr:
474 case OperatorNode::IncrPost:
475 case OperatorNode::DecrPost:
476 case OperatorNode::Assign:
477 case OperatorNode::MulAssn:
478 case OperatorNode::DivAssn:
479 case OperatorNode::ModAssn:
480 case OperatorNode::PlusAssn:
481 case OperatorNode::MinusAssn:
482 case OperatorNode::LSAssn:
483 case OperatorNode::RSAssn:
484 case OperatorNode::AndAssn:
485 case OperatorNode::ERAssn:
486 case OperatorNode::OrAssn:
487 // the rewrite rules for these expressions specify that the first argument has its address taken
488 assert( ! args.empty() );
489 args.front() = new AddressExpr( args.front() );
490 break;
[984dce6]491 default: // do nothing
[cd623a4]492 ;
[984dce6]493 } // switch
[cd623a4]494
495 switch ( op->get_type() ) {
496 case OperatorNode::Incr:
497 case OperatorNode::Decr:
498 case OperatorNode::IncrPost:
499 case OperatorNode::DecrPost:
500 case OperatorNode::Assign:
501 case OperatorNode::MulAssn:
502 case OperatorNode::DivAssn:
503 case OperatorNode::ModAssn:
504 case OperatorNode::PlusAssn:
505 case OperatorNode::MinusAssn:
506 case OperatorNode::LSAssn:
507 case OperatorNode::RSAssn:
508 case OperatorNode::AndAssn:
509 case OperatorNode::ERAssn:
510 case OperatorNode::OrAssn:
511 case OperatorNode::Plus:
512 case OperatorNode::Minus:
513 case OperatorNode::Mul:
514 case OperatorNode::Div:
515 case OperatorNode::Mod:
516 case OperatorNode::BitOr:
517 case OperatorNode::BitAnd:
518 case OperatorNode::Xor:
519 case OperatorNode::LShift:
520 case OperatorNode::RShift:
521 case OperatorNode::LThan:
522 case OperatorNode::GThan:
523 case OperatorNode::LEThan:
524 case OperatorNode::GEThan:
525 case OperatorNode::Eq:
526 case OperatorNode::Neq:
527 case OperatorNode::Index:
528 case OperatorNode::Range:
529 case OperatorNode::UnPlus:
530 case OperatorNode::UnMinus:
531 case OperatorNode::PointTo:
532 case OperatorNode::Neg:
533 case OperatorNode::BitNeg:
534 case OperatorNode::LabelAddress:
[5721a6d]535 return new UntypedExpr( new NameExpr( opName[ op->get_type() ] ), args );
[cd623a4]536 case OperatorNode::AddressOf:
537 assert( args.size() == 1 );
538 assert( args.front() );
539
540 return new AddressExpr( args.front() );
541 case OperatorNode::Cast:
542 {
543 TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
544 assert( arg );
[b87a5ed]545
[cd623a4]546 DeclarationNode *decl_node = arg->get_decl();
547 ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
[b87a5ed]548
[cd623a4]549 Type *targetType = decl_node->buildType();
550 if ( dynamic_cast< VoidType* >( targetType ) ) {
551 delete targetType;
552 return new CastExpr( expr_node->build(), maybeBuild< Expression >( get_argName() ) );
553 } else {
554 return new CastExpr( expr_node->build(),targetType, maybeBuild< Expression >( get_argName() ) );
555 } // if
556 }
557 case OperatorNode::FieldSel:
558 {
559 assert( args.size() == 2 );
560
561 NameExpr *member = dynamic_cast<NameExpr *>( args.back());
562 // TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
[b87a5ed]563
[cd623a4]564 if ( member != 0 ) {
565 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
[b87a5ed]566 delete member;
567 return ret;
[cd623a4]568 /* else if ( memberTup != 0 )
569 {
570 UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
571 delete member;
572 return ret;
573 } */
574 } else
575 assert( false );
576 }
577 case OperatorNode::PFieldSel:
578 {
579 assert( args.size() == 2 );
580
581 NameExpr *member = dynamic_cast<NameExpr *>( args.back()); // modify for Tuples xxx
582 assert( member != 0 );
583
584 UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
585 deref->get_args().push_back( args.front() );
586
587 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
588 delete member;
589 return ret;
590 }
[5721a6d]591 case OperatorNode::SizeOf:
[47534159]592 {
593 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
[5721a6d]594 return new SizeofExpr( arg->get_decl()->buildType());
[47534159]595 } else {
[5721a6d]596 return new SizeofExpr( args.front());
[47534159]597 } // if
598 }
[5721a6d]599 case OperatorNode::AlignOf:
[cd623a4]600 {
601 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
[5721a6d]602 return new AlignofExpr( arg->get_decl()->buildType());
[cd623a4]603 } else {
[5721a6d]604 return new AlignofExpr( args.front());
[cd623a4]605 } // if
606 }
[5721a6d]607 case OperatorNode::OffsetOf:
608 {
[2a4b088]609 assert( args.size() == 2 );
610
611 if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args() ) ) {
612 NameExpr *member = dynamic_cast<NameExpr *>( args.back() );
613 assert( member != 0 );
614
615 return new UntypedOffsetofExpr( arg->get_decl()->buildType(), member->get_name() );
616 } else assert( false );
[5721a6d]617 }
[cd623a4]618 case OperatorNode::Attr:
619 {
620 VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
621 assert( var );
622 if ( ! get_args()->get_link() ) {
623 return new AttrExpr( var->build(), ( Expression*)0);
624 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
625 return new AttrExpr( var->build(), arg->get_decl()->buildType());
626 } else {
627 return new AttrExpr( var->build(), args.back());
628 } // if
629 }
630 case OperatorNode::CompLit:
631 throw UnimplementedError( "C99 compound literals" );
632 // the short-circuited operators
633 case OperatorNode::Or:
634 case OperatorNode::And:
635 assert( args.size() == 2);
636 return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
637 case OperatorNode::Cond:
638 {
639 assert( args.size() == 3);
[7f5566b]640 std::list< Expression * >::const_iterator i = args.begin();
[cd623a4]641 Expression *arg1 = notZeroExpr( *i++ );
642 Expression *arg2 = *i++;
643 Expression *arg3 = *i++;
644 return new ConditionalExpr( arg1, arg2, arg3 );
645 }
646 case OperatorNode::NCond:
647 throw UnimplementedError( "GNU 2-argument conditional expression" );
648 case OperatorNode::Comma:
649 {
[b87a5ed]650 assert( args.size() == 2);
[7f5566b]651 std::list< Expression * >::const_iterator i = args.begin();
[cd623a4]652 Expression *ret = *i++;
653 while ( i != args.end() ) {
654 ret = new CommaExpr( ret, *i++ );
[b87a5ed]655 }
[cd623a4]656 return ret;
[3848e0e]657 }
[cd623a4]658 // Tuples
659 case OperatorNode::TupleC:
660 {
661 TupleExpr *ret = new TupleExpr();
662 std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
663 return ret;
664 }
665 default:
666 // shouldn't happen
[5721a6d]667 assert( false );
[cd623a4]668 return 0;
669 } // switch
[51b73452]670}
671
[bdd516a]672void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]673 printDesignation( os );
674 os << "( ";
675 function->printOneLine( os, indent );
676 for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
677 cur->printOneLine( os, indent );
[5721a6d]678 } // for
[b87a5ed]679 os << ") ";
[51b73452]680}
681
[bdd516a]682void CompositeExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]683 printDesignation( os );
[44b5ca0]684 os << string( indent, ' ' ) << "Application of: " << endl;
[b87a5ed]685 function->print( os, indent + ParseNode::indent_by );
[51b73452]686
[44b5ca0]687 os << string( indent, ' ' ) ;
[b87a5ed]688 if ( arguments ) {
689 os << "... on arguments: " << endl;
690 arguments->printList( os, indent + ParseNode::indent_by );
691 } else
692 os << "... on no arguments: " << endl;
[51b73452]693}
694
[a08ba92]695void CompositeExprNode::set_function( ExpressionNode *f ) {
[b87a5ed]696 function = f;
[51b73452]697}
698
[a08ba92]699void CompositeExprNode::set_args( ExpressionNode *args ) {
[b87a5ed]700 arguments = args;
[51b73452]701}
702
[bdd516a]703ExpressionNode *CompositeExprNode::get_function( void ) const {
[b87a5ed]704 return function;
[51b73452]705}
706
[bdd516a]707ExpressionNode *CompositeExprNode::get_args( void ) const {
[b87a5ed]708 return arguments;
[51b73452]709}
710
[a08ba92]711void CompositeExprNode::add_arg( ExpressionNode *arg ) {
[b87a5ed]712 if ( arguments )
713 arguments->set_link( arg );
714 else
715 set_args( arg );
[51b73452]716}
717
[cd623a4]718//##############################################################################
719
[7f5566b]720Expression *AsmExprNode::build() const {
721 return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)constraint->build(), operand->build() );
722}
723
724void AsmExprNode::print( std::ostream &os, int indent ) const {
725 os << string( indent, ' ' ) << "Assembler Expression:" << endl;
726 if ( inout ) {
727 os << string( indent, ' ' ) << "inout: " << std::endl;
728 inout->print( os, indent + 2 );
729 } // if
730 if ( constraint ) {
731 os << string( indent, ' ' ) << "constraint: " << std::endl;
732 constraint->print( os, indent + 2 );
733 } // if
734 if ( operand ) {
735 os << string( indent, ' ' ) << "operand: " << std::endl;
736 operand->print( os, indent + 2 );
737 } // if
738}
739
740void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
741 printDesignation( os );
742 os << "( ";
743 if ( inout ) inout->printOneLine( os, indent + 2 );
744 os << ", ";
745 if ( constraint ) constraint->printOneLine( os, indent + 2 );
746 os << ", ";
747 if ( operand ) operand->printOneLine( os, indent + 2 );
748 os << ") ";
749}
750
751//##############################################################################
752
753void LabelNode::print( std::ostream &os, int indent ) const {}
754
755void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
756
757//##############################################################################
758
[bdd516a]759CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
[51b73452]760
[bdd516a]761CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
[3848e0e]762}
[51b73452]763
[bdd516a]764CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
[51b73452]765}
766
[a08ba92]767CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
[b87a5ed]768 add_arg( exp );
[51b73452]769
[b87a5ed]770 return this;
[51b73452]771}
772
[3848e0e]773CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
[51b73452]774}
775
[cd623a4]776//##############################################################################
777
[bdd516a]778ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
[51b73452]779
[3848e0e]780ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
[51b73452]781}
782
783ValofExprNode::~ValofExprNode() {
[b87a5ed]784 delete body;
[51b73452]785}
786
787void ValofExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]788 printDesignation( os );
[59db689]789 os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
[b87a5ed]790 get_body()->print( os, indent + 4);
[51b73452]791}
792
[3848e0e]793void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]794 assert( false );
[51b73452]795}
796
797Expression *ValofExprNode::build() const {
[b87a5ed]798 return new UntypedValofExpr ( get_body()->build(), maybeBuild< Expression >( get_argName() ) );
[3848e0e]799}
800
[cd623a4]801//##############################################################################
802
[bdd516a]803ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
[b87a5ed]804 if ( init_ == 0 )
805 init = 0;
806 else {
807 DeclarationNode *decl;
808 ExpressionNode *exp;
809
[a61fea9a]810 if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
[b87a5ed]811 init = new StatementNode( decl );
812 else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
813 init = new StatementNode( StatementNode::Exp, exp );
814 else
815 throw SemanticError("Error in for control expression");
816 }
[51b73452]817}
818
819ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
[b87a5ed]820 : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
[51b73452]821}
822
[a08ba92]823ForCtlExprNode::~ForCtlExprNode() {
[b87a5ed]824 delete init;
825 delete condition;
826 delete change;
[51b73452]827}
828
829Expression *ForCtlExprNode::build() const {
[b87a5ed]830 // this shouldn't be used!
831 assert( false );
832 return 0;
[51b73452]833}
834
835void ForCtlExprNode::print( std::ostream &os, int indent ) const{
[59db689]836 os << string( indent,' ' ) << "For Control Expression -- :" << endl;
[a61fea9a]837
[59db689]838 os << string( indent + 2, ' ' ) << "initialization:" << endl;
[a61fea9a]839 if ( init != 0 )
840 init->printList( os, indent + 4 );
841
842 os << string( indent + 2, ' ' ) << "condition: " << endl;
843 if ( condition != 0 )
844 condition->print( os, indent + 4 );
[59db689]845 os << string( indent + 2, ' ' ) << "increment: " << endl;
[a61fea9a]846 if ( change != 0 )
847 change->print( os, indent + 4 );
[51b73452]848}
849
[3848e0e]850void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]851 assert( false );
[51b73452]852}
853
[cd623a4]854//##############################################################################
855
856TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
[51b73452]857}
858
[cd623a4]859TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
[51b73452]860}
861
[3848e0e]862Expression *TypeValueNode::build() const {
[b87a5ed]863 return new TypeExpr( decl->buildType() );
[51b73452]864}
865
[bdd516a]866void TypeValueNode::print( std::ostream &os, int indent ) const {
[b87a5ed]867 os << std::string( indent, ' ' ) << "Type:";
868 get_decl()->print( os, indent + 2);
[51b73452]869}
870
[bdd516a]871void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]872 os << "Type:";
873 get_decl()->print( os, indent + 2);
[51b73452]874}
875
[630a82a]876
877CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
878CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
879
880CompoundLiteralNode::~CompoundLiteralNode() {
881 delete kids;
882 delete type;
883}
884
885CompoundLiteralNode *CompoundLiteralNode::clone() const {
886 return new CompoundLiteralNode( *this );
887}
888
889void CompoundLiteralNode::print( std::ostream &os, int indent ) const {
890 os << string( indent,' ' ) << "CompoundLiteralNode:" << endl;
891
892 os << string( indent + 2, ' ' ) << "type:" << endl;
893 if ( type != 0 )
894 type->print( os, indent + 4 );
895
896 os << string( indent + 2, ' ' ) << "initialization:" << endl;
897 if ( kids != 0 )
898 kids->printList( os, indent + 4 );
899}
900
901void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const {
902 os << "( ";
903 if ( type ) type->print( os );
904 os << ", ";
905 if ( kids ) kids->printOneLine( os );
906 os << ") ";
907}
908
909Expression *CompoundLiteralNode::build() const {
910 Declaration * newDecl = type->build(); // compound literal type
911 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
912 return new CompoundLiteralExpr( newDeclWithType->get_type(), kids->build() );
913 // these types do not have associated type information
914 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) {
915 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), kids->build() );
916 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) {
917 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), kids->build() );
918 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) {
919 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), kids->build() );
920 } else {
921 assert( false );
922 } // if
923}
924
925
[3848e0e]926ExpressionNode *flattenCommas( ExpressionNode *list ) {
[cd623a4]927 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
928 OperatorNode *op;
929 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
930 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
931 composite->add_arg( next );
932 return flattenCommas( composite->get_args() );
933 } // if
934 } // if
[51b73452]935
[b87a5ed]936 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
937 list->set_next( flattenCommas( next ) );
[51b73452]938
[b87a5ed]939 return list;
[51b73452]940}
941
[3848e0e]942ExpressionNode *tupleContents( ExpressionNode *tuple ) {
[b87a5ed]943 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
944 OperatorNode *op = 0;
945 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
946 return composite->get_args();
[cd623a4]947 } // if
[b87a5ed]948 return tuple;
[51b73452]949}
[b87a5ed]950
951// Local Variables: //
952// tab-width: 4 //
953// mode: c++ //
954// compile-command: "make install" //
955// End: //
Note: See TracBrowser for help on using the repository browser.