source: src/Parser/ExpressionNode.cc@ e7aed49

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 e7aed49 was e04ef3a, checked in by Peter A. Buhr <pabuhr@…>, 9 years ago

add gcc extension, first attempt, not done yet

  • Property mode set to 100644
File size: 29.0 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
[e04ef3a]12// Last Modified On : Mon Jun 13 14:46:17 2016
13// Update Count : 307
[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
[e04ef3a]34ExpressionNode::ExpressionNode() : ParseNode() {}
[51b73452]35
[e04ef3a]36ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) {}
[51b73452]37
[e04ef3a]38ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) {
[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 {
[e04ef3a]346 Expression * ret = maybeBuild<Expression>(get_argName());
[e869d663]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
[e04ef3a]391 "SizeOf", "AlignOf", "OffsetOf", "Attr", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
[5721a6d]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
[e04ef3a]468 return new UntypedExpr( maybeBuild<Expression>(function), 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;
[e04ef3a]552 return new CastExpr( maybeBuild<Expression>(expr_node), maybeBuild< Expression >( get_argName() ) );
[cd623a4]553 } else {
[e04ef3a]554 return new CastExpr( maybeBuild<Expression>(expr_node),targetType, maybeBuild< Expression >( get_argName() ) );
[cd623a4]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() ) {
[e04ef3a]623 return new AttrExpr( maybeBuild<Expression>(var), ( Expression*)0);
[cd623a4]624 } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
[e04ef3a]625 return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType());
[cd623a4]626 } else {
[e04ef3a]627 return new AttrExpr( maybeBuild<Expression>(var), args.back());
[cd623a4]628 } // if
629 }
630 case OperatorNode::Or:
631 case OperatorNode::And:
632 assert( args.size() == 2);
633 return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
634 case OperatorNode::Cond:
635 {
636 assert( args.size() == 3);
[7f5566b]637 std::list< Expression * >::const_iterator i = args.begin();
[cd623a4]638 Expression *arg1 = notZeroExpr( *i++ );
639 Expression *arg2 = *i++;
640 Expression *arg3 = *i++;
641 return new ConditionalExpr( arg1, arg2, arg3 );
642 }
643 case OperatorNode::NCond:
644 throw UnimplementedError( "GNU 2-argument conditional expression" );
645 case OperatorNode::Comma:
646 {
[b87a5ed]647 assert( args.size() == 2);
[7f5566b]648 std::list< Expression * >::const_iterator i = args.begin();
[cd623a4]649 Expression *ret = *i++;
650 while ( i != args.end() ) {
651 ret = new CommaExpr( ret, *i++ );
[b87a5ed]652 }
[cd623a4]653 return ret;
[3848e0e]654 }
[cd623a4]655 // Tuples
656 case OperatorNode::TupleC:
657 {
658 TupleExpr *ret = new TupleExpr();
659 std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
660 return ret;
661 }
662 default:
663 // shouldn't happen
[5721a6d]664 assert( false );
[cd623a4]665 return 0;
666 } // switch
[51b73452]667}
668
[bdd516a]669void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]670 printDesignation( os );
671 os << "( ";
672 function->printOneLine( os, indent );
673 for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
674 cur->printOneLine( os, indent );
[5721a6d]675 } // for
[b87a5ed]676 os << ") ";
[51b73452]677}
678
[bdd516a]679void CompositeExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]680 printDesignation( os );
[44b5ca0]681 os << string( indent, ' ' ) << "Application of: " << endl;
[b87a5ed]682 function->print( os, indent + ParseNode::indent_by );
[51b73452]683
[44b5ca0]684 os << string( indent, ' ' ) ;
[b87a5ed]685 if ( arguments ) {
686 os << "... on arguments: " << endl;
687 arguments->printList( os, indent + ParseNode::indent_by );
688 } else
689 os << "... on no arguments: " << endl;
[51b73452]690}
691
[a08ba92]692void CompositeExprNode::set_function( ExpressionNode *f ) {
[b87a5ed]693 function = f;
[51b73452]694}
695
[a08ba92]696void CompositeExprNode::set_args( ExpressionNode *args ) {
[b87a5ed]697 arguments = args;
[51b73452]698}
699
[bdd516a]700ExpressionNode *CompositeExprNode::get_function( void ) const {
[b87a5ed]701 return function;
[51b73452]702}
703
[bdd516a]704ExpressionNode *CompositeExprNode::get_args( void ) const {
[b87a5ed]705 return arguments;
[51b73452]706}
707
[a08ba92]708void CompositeExprNode::add_arg( ExpressionNode *arg ) {
[b87a5ed]709 if ( arguments )
710 arguments->set_link( arg );
711 else
712 set_args( arg );
[51b73452]713}
714
[cd623a4]715//##############################################################################
716
[7f5566b]717Expression *AsmExprNode::build() const {
[e04ef3a]718 return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) );
[7f5566b]719}
720
721void AsmExprNode::print( std::ostream &os, int indent ) const {
722 os << string( indent, ' ' ) << "Assembler Expression:" << endl;
723 if ( inout ) {
724 os << string( indent, ' ' ) << "inout: " << std::endl;
725 inout->print( os, indent + 2 );
726 } // if
727 if ( constraint ) {
728 os << string( indent, ' ' ) << "constraint: " << std::endl;
729 constraint->print( os, indent + 2 );
730 } // if
731 if ( operand ) {
732 os << string( indent, ' ' ) << "operand: " << std::endl;
733 operand->print( os, indent + 2 );
734 } // if
735}
736
737void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
738 printDesignation( os );
739 os << "( ";
740 if ( inout ) inout->printOneLine( os, indent + 2 );
741 os << ", ";
742 if ( constraint ) constraint->printOneLine( os, indent + 2 );
743 os << ", ";
744 if ( operand ) operand->printOneLine( os, indent + 2 );
745 os << ") ";
746}
747
748//##############################################################################
749
750void LabelNode::print( std::ostream &os, int indent ) const {}
751
752void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
753
754//##############################################################################
755
[bdd516a]756CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
[51b73452]757
[bdd516a]758CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
[3848e0e]759}
[51b73452]760
[bdd516a]761CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
[51b73452]762}
763
[a08ba92]764CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
[b87a5ed]765 add_arg( exp );
[51b73452]766
[b87a5ed]767 return this;
[51b73452]768}
769
[3848e0e]770CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
[51b73452]771}
772
[cd623a4]773//##############################################################################
774
[bdd516a]775ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
[51b73452]776
[3848e0e]777ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
[51b73452]778}
779
780ValofExprNode::~ValofExprNode() {
[b87a5ed]781 delete body;
[51b73452]782}
783
784void ValofExprNode::print( std::ostream &os, int indent ) const {
[b87a5ed]785 printDesignation( os );
[59db689]786 os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
[b87a5ed]787 get_body()->print( os, indent + 4);
[51b73452]788}
789
[3848e0e]790void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]791 assert( false );
[51b73452]792}
793
794Expression *ValofExprNode::build() const {
[e04ef3a]795 return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) );
[3848e0e]796}
797
[cd623a4]798//##############################################################################
799
[bdd516a]800ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
[b87a5ed]801 if ( init_ == 0 )
802 init = 0;
803 else {
804 DeclarationNode *decl;
805 ExpressionNode *exp;
806
[a61fea9a]807 if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
[b87a5ed]808 init = new StatementNode( decl );
809 else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
810 init = new StatementNode( StatementNode::Exp, exp );
811 else
812 throw SemanticError("Error in for control expression");
813 }
[51b73452]814}
815
816ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
[b87a5ed]817 : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
[51b73452]818}
819
[a08ba92]820ForCtlExprNode::~ForCtlExprNode() {
[b87a5ed]821 delete init;
822 delete condition;
823 delete change;
[51b73452]824}
825
826Expression *ForCtlExprNode::build() const {
[b87a5ed]827 // this shouldn't be used!
828 assert( false );
829 return 0;
[51b73452]830}
831
832void ForCtlExprNode::print( std::ostream &os, int indent ) const{
[59db689]833 os << string( indent,' ' ) << "For Control Expression -- :" << endl;
[a61fea9a]834
[59db689]835 os << string( indent + 2, ' ' ) << "initialization:" << endl;
[a61fea9a]836 if ( init != 0 )
837 init->printList( os, indent + 4 );
838
839 os << string( indent + 2, ' ' ) << "condition: " << endl;
840 if ( condition != 0 )
841 condition->print( os, indent + 4 );
[59db689]842 os << string( indent + 2, ' ' ) << "increment: " << endl;
[a61fea9a]843 if ( change != 0 )
844 change->print( os, indent + 4 );
[51b73452]845}
846
[3848e0e]847void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
[b87a5ed]848 assert( false );
[51b73452]849}
850
[cd623a4]851//##############################################################################
852
853TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
[51b73452]854}
855
[cd623a4]856TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
[51b73452]857}
858
[3848e0e]859Expression *TypeValueNode::build() const {
[b87a5ed]860 return new TypeExpr( decl->buildType() );
[51b73452]861}
862
[bdd516a]863void TypeValueNode::print( std::ostream &os, int indent ) const {
[b87a5ed]864 os << std::string( indent, ' ' ) << "Type:";
865 get_decl()->print( os, indent + 2);
[51b73452]866}
867
[bdd516a]868void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
[b87a5ed]869 os << "Type:";
870 get_decl()->print( os, indent + 2);
[51b73452]871}
872
[630a82a]873
874CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
875CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
876
877CompoundLiteralNode::~CompoundLiteralNode() {
878 delete kids;
879 delete type;
880}
881
882CompoundLiteralNode *CompoundLiteralNode::clone() const {
883 return new CompoundLiteralNode( *this );
884}
885
886void CompoundLiteralNode::print( std::ostream &os, int indent ) const {
887 os << string( indent,' ' ) << "CompoundLiteralNode:" << endl;
888
889 os << string( indent + 2, ' ' ) << "type:" << endl;
890 if ( type != 0 )
891 type->print( os, indent + 4 );
892
893 os << string( indent + 2, ' ' ) << "initialization:" << endl;
894 if ( kids != 0 )
895 kids->printList( os, indent + 4 );
896}
897
898void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const {
899 os << "( ";
900 if ( type ) type->print( os );
901 os << ", ";
902 if ( kids ) kids->printOneLine( os );
903 os << ") ";
904}
905
906Expression *CompoundLiteralNode::build() const {
[e04ef3a]907 Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type
[630a82a]908 if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
[e04ef3a]909 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) );
[630a82a]910 // these types do not have associated type information
911 } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl ) ) {
[e04ef3a]912 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild<Initializer>(kids) );
[630a82a]913 } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl ) ) {
[e04ef3a]914 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild<Initializer>(kids) );
[630a82a]915 } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl ) ) {
[e04ef3a]916 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild<Initializer>(kids) );
[630a82a]917 } else {
918 assert( false );
919 } // if
920}
921
922
[3848e0e]923ExpressionNode *flattenCommas( ExpressionNode *list ) {
[cd623a4]924 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
925 OperatorNode *op;
926 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
927 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
928 composite->add_arg( next );
929 return flattenCommas( composite->get_args() );
930 } // if
931 } // if
[51b73452]932
[b87a5ed]933 if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
934 list->set_next( flattenCommas( next ) );
[51b73452]935
[b87a5ed]936 return list;
[51b73452]937}
938
[3848e0e]939ExpressionNode *tupleContents( ExpressionNode *tuple ) {
[b87a5ed]940 if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
941 OperatorNode *op = 0;
942 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
943 return composite->get_args();
[cd623a4]944 } // if
[b87a5ed]945 return tuple;
[51b73452]946}
[b87a5ed]947
948// Local Variables: //
949// tab-width: 4 //
950// mode: c++ //
951// compile-command: "make install" //
952// End: //
Note: See TracBrowser for help on using the repository browser.