Ignore:
Timestamp:
Aug 16, 2016, 3:20:06 PM (9 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
1f6d4624
Parents:
950f7a7 (diff), 7880579 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/ExpressionNode.cc

    r950f7a7 r7527e63  
    1010// Created On       : Sat May 16 13:17:07 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul  5 13:41:55 2016
    13 // Update Count     : 320
     12// Last Modified On : Tue Aug 16 00:09:20 2016
     13// Update Count     : 495
    1414//
    1515
    1616#include <cassert>
    1717#include <cctype>
     18#include <climits>
     19#include <cstdio>
    1820#include <algorithm>
    1921#include <sstream>
    20 #include <cstdio>
    2122
    2223#include "ParseNode.h"
     
    3132using namespace std;
    3233
    33 ExpressionNode::ExpressionNode() : ParseNode() {}
    34 
    35 ExpressionNode::ExpressionNode( const string *name ) : ParseNode( name ) {}
    36 
    37 ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.name ), extension( other.extension ) {
    38         if ( other.argName ) {
    39                 argName = other.argName->clone();
    40         } else {
    41                 argName = 0;
    42         } // if
    43 }
    44 
    45 ExpressionNode * ExpressionNode::set_argName( const std::string *aName ) {
    46         argName = new VarRefNode( aName );
    47         return this;
    48 }
    49 
    50 ExpressionNode * ExpressionNode::set_argName( ExpressionNode *aDesignator ) {
    51         argName = aDesignator;
    52         return this;
    53 }
    54 
    55 void ExpressionNode::printDesignation( std::ostream &os, int indent ) const {
    56         if ( argName ) {
    57                 os << string( indent, ' ' ) << "(designated by:  ";
    58                 argName->printOneLine( os, indent );
    59                 os << ")" << std::endl;
    60         } // if
    61 }
     34ExpressionNode::ExpressionNode( const ExpressionNode &other ) : ParseNode( other.get_name() ), extension( other.extension ) {}
    6235
    6336//##############################################################################
    6437
    65 NullExprNode::NullExprNode() {}
    66 
    67 NullExprNode *NullExprNode::clone() const {
    68         return new NullExprNode();
    69 }
    70 
    71 void NullExprNode::print( std::ostream & os, int indent ) const {
    72         printDesignation( os );
    73         os << "null expression";
    74 }
    75 
    76 void NullExprNode::printOneLine( std::ostream & os, int indent ) const {
    77         printDesignation( os );
    78         os << "null";
    79 }
    80 
    81 Expression *NullExprNode::build() const {
    82         return 0;
    83 }
    84 
    85 CommaExprNode *ExpressionNode::add_to_list( ExpressionNode *exp ) {
    86         return new CommaExprNode( this, exp );
    87 }
    88 
    89 //##############################################################################
    90 
    91 ConstantNode::ConstantNode( ConstantExpr *expr ) : expr( expr ) {
    92 } // ConstantNode::ConstantNode
    93 
    94 ConstantNode *ConstantNode::appendstr( const std::string *newValue ) {
    95         assert( newValue != 0 );
    96 
    97         string value = expr->get_constant()->get_value();
    98 
    99         // "abc" "def" "ghi" => "abcdefghi", remove new text from quotes and insert before last quote in old string.
    100         value.insert( value.length() - 1, newValue->substr( 1, newValue->length() - 2 ) );
    101         expr->get_constant()->set_value( value );
    102 
    103         delete newValue;                                                                        // allocated by lexer
    104         return this;
    105 }
    106 
    107 void ConstantNode::printOneLine( std::ostream &os, int indent ) const {
    108         // os << string( indent, ' ' );
    109         // printDesignation( os );
    110 
    111         // switch ( type ) {
    112         //   case Integer:
    113         //   case Float:
    114         //      os << value ;
    115         //      break;
    116         //   case Character:
    117         //      os << "'" << value << "'";
    118         //      break;
    119         //   case String:
    120         //      os << '"' << value << '"';
    121         //      break;
    122         // } // switch
    123 
    124         // os << ' ';
    125 }
    126 
    127 void ConstantNode::print( std::ostream &os, int indent ) const {
    128         printOneLine( os, indent );
    129         os << endl;
    130 }
    131 
    132 Expression *ConstantNode::build() const {
    133         return expr->clone();
    134 }
    135 
    136 //##############################################################################
    137 
    138 VarRefNode::VarRefNode() : isLabel( false ) {}
    139 
    140 VarRefNode::VarRefNode( const string *name_, bool labelp ) : ExpressionNode( name_ ), isLabel( labelp ) {}
    141 
    142 VarRefNode::VarRefNode( const VarRefNode &other ) : ExpressionNode( other ), isLabel( other.isLabel ) {
    143 }
    144 
    145 Expression *VarRefNode::build() const {
    146         return new NameExpr( get_name(), maybeBuild< Expression >( get_argName() ) );
    147 }
    148 
    149 void VarRefNode::printOneLine( std::ostream &os, int indent ) const {
    150         printDesignation( os );
    151         os << get_name() << ' ';
    152 }
    153 
    154 void VarRefNode::print( std::ostream &os, int indent ) const {
    155         printDesignation( os );
    156         os << string( indent, ' ' ) << "Referencing: ";
    157         os << "Variable: " << get_name();
    158         os << endl;
    159 }
    160 
    161 //##############################################################################
    162 
    163 DesignatorNode::DesignatorNode( ExpressionNode *expr, bool isArrayIndex ) : isArrayIndex( isArrayIndex ) {
    164         set_argName( expr );
    165         assert( get_argName() );
    166 
    167         if ( ! isArrayIndex ) {
    168                 if ( VarRefNode * var = dynamic_cast< VarRefNode * >( expr ) ) {
    169 
    170                         stringstream ss( var->get_name() );
    171                         double value;
    172                         if ( ss >> value ) {
    173                                 // this is a floating point constant. It MUST be
    174                                 // ".0" or ".1", otherwise the program is invalid
    175                                 if ( ! (var->get_name() == ".0" || var->get_name() == ".1") ) {
    176                                         throw SemanticError( "invalid designator name: " + var->get_name() );
    177                                 } // if
    178                                 var->set_name( var->get_name().substr(1) );
     38// Difficult to separate extra parts of constants during lexing because actions are not allow in the middle of patterns:
     39//
     40//              prefix action constant action suffix
     41//
     42// Alternatively, breaking a pattern using BEGIN does not work if the following pattern can be empty:
     43//
     44//              constant BEGIN CONT ...
     45//              <CONT>(...)? BEGIN 0 ... // possible empty suffix
     46//
     47// because the CONT rule is NOT triggered if the pattern is empty. Hence, constants are reparsed here to determine their
     48// type.
     49
     50static Type::Qualifiers emptyQualifiers;                                // no qualifiers on constants
     51
     52static inline bool checkU( char c ) { return c == 'u' || c == 'U'; }
     53static inline bool checkL( char c ) { return c == 'l' || c == 'L'; }
     54static inline bool checkF( char c ) { return c == 'f' || c == 'F'; }
     55static inline bool checkD( char c ) { return c == 'd' || c == 'D'; }
     56static inline bool checkI( char c ) { return c == 'i' || c == 'I'; }
     57static inline bool checkX( char c ) { return c == 'x' || c == 'X'; }
     58
     59Expression *build_constantInteger( std::string & str ) {
     60        static const BasicType::Kind kind[2][3] = {
     61                { BasicType::SignedInt, BasicType::LongSignedInt, BasicType::LongLongSignedInt },
     62                { BasicType::UnsignedInt, BasicType::LongUnsignedInt, BasicType::LongLongUnsignedInt },
     63        };
     64        bool dec = true, Unsigned = false;                                      // decimal, unsigned constant
     65        int size;                                                                                       // 0 => int, 1 => long, 2 => long long
     66        unsigned long long v;                                                           // converted integral value
     67        size_t last = str.length() - 1;                                         // last character of constant
     68
     69        if ( str[0] == '0' ) {                                                          // octal/hex constant ?
     70                dec = false;
     71                if ( last != 0 && checkX( str[1] ) ) {                  // hex constant ?
     72                        sscanf( (char *)str.c_str(), "%llx", &v );
     73                        //printf( "%llx %llu\n", v, v );
     74                } else {                                                                                // octal constant
     75                        sscanf( (char *)str.c_str(), "%llo", &v );
     76                        //printf( "%llo %llu\n", v, v );
     77                } // if
     78        } else {                                                                                        // decimal constant ?
     79                sscanf( (char *)str.c_str(), "%llu", &v );
     80                //printf( "%llu %llu\n", v, v );
     81        } // if
     82
     83        if ( v <= INT_MAX ) {                                                           // signed int
     84                size = 0;
     85        } else if ( v <= UINT_MAX && ! dec ) {                          // unsigned int
     86                size = 0;
     87                Unsigned = true;                                                                // unsigned
     88        } else if ( v <= LONG_MAX ) {                                           // signed long int
     89                size = 1;
     90        } else if ( v <= ULONG_MAX && ( ! dec || LONG_MAX == LLONG_MAX ) ) { // signed long int
     91                size = 1;
     92                Unsigned = true;                                                                // unsigned long int
     93        } else if ( v <= LLONG_MAX ) {                                          // signed long long int
     94                size = 2;
     95        } else {                                                                                        // unsigned long long int
     96                size = 2;
     97                Unsigned = true;                                                                // unsigned long long int
     98        } // if
     99
     100        if ( checkU( str[last] ) ) {                                            // suffix 'u' ?
     101                Unsigned = true;
     102                if ( last > 0 && checkL( str[last - 1] ) ) {    // suffix 'l' ?
     103                        size = 1;
     104                        if ( last > 1 && checkL( str[last - 2] ) ) { // suffix 'll' ?
     105                                size = 2;
    179106                        } // if
    180107                } // if
    181         } // if
    182 }
    183 
    184 DesignatorNode::DesignatorNode( const DesignatorNode &other ) : ExpressionNode( other ), isArrayIndex( other.isArrayIndex ) {
    185 }
    186 
    187 class DesignatorFixer : public Mutator {
    188 public:
    189         virtual Expression* mutate( NameExpr *nameExpr ) {
    190                 if ( nameExpr->get_name() == "0" || nameExpr->get_name() == "1" ) {
    191                         Constant val( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), nameExpr->get_name() );
    192                         delete nameExpr;
    193                         return new ConstantExpr( val );
    194                 }
    195                 return nameExpr;
    196         }
    197 };
    198 
    199 Expression *DesignatorNode::build() const {
    200         Expression * ret = maybeBuild<Expression>(get_argName());
    201 
    202         if ( isArrayIndex ) {
    203                 // need to traverse entire structure and change any instances of 0 or 1 to
    204                 // ConstantExpr
    205                 DesignatorFixer fixer;
    206                 ret = ret->acceptMutator( fixer );
    207         } // if
    208 
    209         return ret;
    210 }
    211 
    212 void DesignatorNode::printOneLine( std::ostream &os, int indent ) const {
    213         if ( get_argName() ) {
    214                 if ( isArrayIndex ) {
    215                         os << "[";
    216                         get_argName()->printOneLine( os, indent );
    217                         os << "]";
     108        } else if ( checkL( str[ last ] ) ) {                           // suffix 'l' ?
     109                size = 1;
     110                if ( last > 0 && checkL( str[last - 1] ) ) {    // suffix 'll' ?
     111                        size = 2;
     112                        if ( last > 1 && checkU( str[last - 2] ) ) { // suffix 'u' ?
     113                                Unsigned = true;
     114                        } // if
    218115                } else {
    219                         os << ".";
    220                         get_argName()->printOneLine( os, indent );
    221                 }
    222         } // if
    223 }
    224 
    225 void DesignatorNode::print( std::ostream &os, int indent ) const {
    226         if ( get_argName() ) {
    227                 if ( isArrayIndex ) {
    228                         os << "[";
    229                         get_argName()->print( os, indent );
    230                         os << "]";
    231                 } else {
    232                         os << ".";
    233                         get_argName()->print( os, indent );
    234                 }
    235         } // if
    236 }
    237 
    238 //##############################################################################
    239 
    240 static const char *opName[] = {
    241         "TupleC", "Comma", "TupleFieldSel", // "TuplePFieldSel", // n-adic
    242         // triadic
    243         "Cond", "NCond",
     116                        if ( last > 0 && checkU( str[last - 1] ) ) { // suffix 'u' ?
     117                                Unsigned = true;
     118                        } // if
     119                } // if
     120        } // if
     121
     122        return new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[Unsigned][size] ), str ) );
     123} // build_constantInteger
     124
     125Expression *build_constantFloat( 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
     136        if ( checkI( str[last] ) ) {                                            // imaginary ?
     137                complx = true;
     138                last -= 1;                                                                              // backup one character
     139        } // if
     140
     141        if ( checkF( str[last] ) ) {                                            // float ?
     142                size = 0;
     143        } else if ( checkD( str[last] ) ) {                                     // double ?
     144                size = 1;
     145        } else if ( checkL( str[last] ) ) {                                     // long double ?
     146                size = 2;
     147        } // if
     148        if ( ! complx && checkI( str[last - 1] ) ) {            // imaginary ?
     149                complx = true;
     150        } // if
     151
     152        return new ConstantExpr( Constant( new BasicType( emptyQualifiers, kind[complx][size] ), str ) );
     153} // build_constantFloat
     154
     155Expression *build_constantChar( std::string & str ) {
     156        return new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::Char ), str ) );
     157} // build_constantChar
     158
     159ConstantExpr *build_constantStr( std::string & str ) {
     160        // string should probably be a primitive type
     161        ArrayType *at = new ArrayType( emptyQualifiers, new BasicType( emptyQualifiers, BasicType::Char ),
     162                                new ConstantExpr( Constant( new BasicType( emptyQualifiers, BasicType::UnsignedInt ),
     163                                                                                        toString( str.size()+1-2 ) ) ),  // +1 for '\0' and -2 for '"'
     164                                                                   false, false );
     165        return new ConstantExpr( Constant( at, str ) );
     166} // build_constantStr
     167
     168NameExpr * build_varref( const string *name, bool labelp ) {
     169        return new NameExpr( *name, nullptr );
     170}
     171
     172static const char *OperName[] = {
    244173        // diadic
    245         "SizeOf", "AlignOf", "OffsetOf", "Attr", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
     174        "SizeOf", "AlignOf", "OffsetOf", "?+?", "?-?", "?*?", "?/?", "?%?", "||", "&&",
    246175        "?|?", "?&?", "?^?", "Cast", "?<<?", "?>>?", "?<?", "?>?", "?<=?", "?>=?", "?==?", "?!=?",
    247176        "?=?", "?*=?", "?/=?", "?%=?", "?+=?", "?-=?", "?<<=?", "?>>=?", "?&=?", "?^=?", "?|=?",
    248         "?[?]", "FieldSel", "PFieldSel", "Range",
     177        "?[?]", "...",
    249178        // monadic
    250179        "+?", "-?", "AddressOf", "*?", "!?", "~?", "++?", "?++", "--?", "?--", "&&"
    251180};
    252181
    253 OperatorNode::OperatorNode( Type t ) : type( t ) {}
    254 
    255 OperatorNode::OperatorNode( const OperatorNode &other ) : ExpressionNode( other ), type( other.type ) {
    256 }
    257 
    258 OperatorNode::~OperatorNode() {}
    259 
    260 OperatorNode::Type OperatorNode::get_type( void ) const{
    261         return type;
    262 }
    263 
    264 void OperatorNode::printOneLine( std::ostream &os, int indent ) const {
    265         printDesignation( os );
    266         os << opName[ type ] << ' ';
    267 }
    268 
    269 void OperatorNode::print( std::ostream &os, int indent ) const{
    270         printDesignation( os );
    271         os << string( indent, ' ' ) << "Operator: " << opName[type] << endl;
    272         return;
    273 }
    274 
    275 const char *OperatorNode::get_typename( void ) const{
    276         return opName[ type ];
    277 }
    278 
    279 //##############################################################################
    280 
    281 CompositeExprNode::CompositeExprNode() : ExpressionNode(), function( 0 ), arguments( 0 ) {
    282 }
    283 
    284 CompositeExprNode::CompositeExprNode( const string *name_ ) : ExpressionNode( name_ ), function( 0 ), arguments( 0 ) {
    285 }
    286 
    287 CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *args ):
    288         function( f ), arguments( args ) {
    289 }
    290 
    291 CompositeExprNode::CompositeExprNode( ExpressionNode *f, ExpressionNode *arg1, ExpressionNode *arg2):
    292         function( f ), arguments( arg1 ) {
    293         arguments->set_link( arg2 );
    294 }
    295 
    296 CompositeExprNode::CompositeExprNode( const CompositeExprNode &other ) : ExpressionNode( other ), function( maybeClone( other.function ) ), arguments( 0 ) {
    297         ParseNode *cur = other.arguments;
    298         while ( cur ) {
    299                 if ( arguments ) {
    300                         arguments->set_link( cur->clone() );
    301                 } else {
    302                         arguments = ( ExpressionNode*)cur->clone();
    303                 } // if
    304                 cur = cur->get_link();
    305         }
    306 }
    307 
    308 CompositeExprNode::~CompositeExprNode() {
    309         delete function;
    310         delete arguments;
    311 }
    312 
    313 #include "Common/utility.h"
    314 
    315 Expression *CompositeExprNode::build() const {
    316         OperatorNode *op;
    317         std::list<Expression *> args;
    318 
    319         buildList( get_args(), args );
    320 
    321         if ( ! ( op = dynamic_cast<OperatorNode *>( function ) ) ) { // function as opposed to operator
    322                 return new UntypedExpr( maybeBuild<Expression>(function), args, maybeBuild< Expression >( get_argName() ));
    323         } // if
    324 
    325         switch ( op->get_type()) {
    326           case OperatorNode::Incr:
    327           case OperatorNode::Decr:
    328           case OperatorNode::IncrPost:
    329           case OperatorNode::DecrPost:
    330           case OperatorNode::Assign:
    331           case OperatorNode::MulAssn:
    332           case OperatorNode::DivAssn:
    333           case OperatorNode::ModAssn:
    334           case OperatorNode::PlusAssn:
    335           case OperatorNode::MinusAssn:
    336           case OperatorNode::LSAssn:
    337           case OperatorNode::RSAssn:
    338           case OperatorNode::AndAssn:
    339           case OperatorNode::ERAssn:
    340           case OperatorNode::OrAssn:
    341                 // the rewrite rules for these expressions specify that the first argument has its address taken
    342                 assert( ! args.empty() );
    343                 args.front() = new AddressExpr( args.front() );
    344                 break;
    345           default:              // do nothing
    346                 ;
    347         } // switch
    348 
    349         switch ( op->get_type() ) {
    350           case OperatorNode::Incr:
    351           case OperatorNode::Decr:
    352           case OperatorNode::IncrPost:
    353           case OperatorNode::DecrPost:
    354           case OperatorNode::Assign:
    355           case OperatorNode::MulAssn:
    356           case OperatorNode::DivAssn:
    357           case OperatorNode::ModAssn:
    358           case OperatorNode::PlusAssn:
    359           case OperatorNode::MinusAssn:
    360           case OperatorNode::LSAssn:
    361           case OperatorNode::RSAssn:
    362           case OperatorNode::AndAssn:
    363           case OperatorNode::ERAssn:
    364           case OperatorNode::OrAssn:
    365           case OperatorNode::Plus:
    366           case OperatorNode::Minus:
    367           case OperatorNode::Mul:
    368           case OperatorNode::Div:
    369           case OperatorNode::Mod:
    370           case OperatorNode::BitOr:
    371           case OperatorNode::BitAnd:
    372           case OperatorNode::Xor:
    373           case OperatorNode::LShift:
    374           case OperatorNode::RShift:
    375           case OperatorNode::LThan:
    376           case OperatorNode::GThan:
    377           case OperatorNode::LEThan:
    378           case OperatorNode::GEThan:
    379           case OperatorNode::Eq:
    380           case OperatorNode::Neq:
    381           case OperatorNode::Index:
    382           case OperatorNode::Range:
    383           case OperatorNode::UnPlus:
    384           case OperatorNode::UnMinus:
    385           case OperatorNode::PointTo:
    386           case OperatorNode::Neg:
    387           case OperatorNode::BitNeg:
    388           case OperatorNode::LabelAddress:
    389                 return new UntypedExpr( new NameExpr( opName[ op->get_type() ] ), args );
    390           case OperatorNode::AddressOf:
    391                 assert( args.size() == 1 );
    392                 assert( args.front() );
    393 
    394                 return new AddressExpr( args.front() );
    395           case OperatorNode::Cast:
    396                 {
    397                         TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args());
    398                         assert( arg );
    399 
    400                         DeclarationNode *decl_node = arg->get_decl();
    401                         ExpressionNode *expr_node = dynamic_cast<ExpressionNode *>( arg->get_link());
    402 
    403                         Type *targetType = decl_node->buildType();
    404                         if ( dynamic_cast< VoidType* >( targetType ) ) {
    405                                 delete targetType;
    406                                 return new CastExpr( maybeBuild<Expression>(expr_node), maybeBuild< Expression >( get_argName() ) );
    407                         } else {
    408                                 return new CastExpr( maybeBuild<Expression>(expr_node),targetType, maybeBuild< Expression >( get_argName() ) );
    409                         } // if
    410                 }
    411           case OperatorNode::FieldSel:
    412                 {
    413                         assert( args.size() == 2 );
    414 
    415                         NameExpr *member = dynamic_cast<NameExpr *>( args.back());
    416                         // TupleExpr *memberTup = dynamic_cast<TupleExpr *>( args.back());
    417 
    418                         if ( member != 0 ) {
    419                                 UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), args.front());
    420                                 delete member;
    421                                 return ret;
    422                                 /* else if ( memberTup != 0 )
    423                                    {
    424                                    UntypedMemberExpr *ret = new UntypedMemberExpr( memberTup->get_name(), args.front());
    425                                    delete member;
    426                                    return ret;
    427                                    } */
    428                         } else
    429                                 assert( false );
    430                 }
    431           case OperatorNode::PFieldSel:
    432                 {
    433                         assert( args.size() == 2 );
    434 
    435                         NameExpr *member = dynamic_cast<NameExpr *>( args.back());  // modify for Tuples   xxx
    436                         assert( member != 0 );
    437 
    438                         UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    439                         deref->get_args().push_back( args.front() );
    440 
    441                         UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
    442                         delete member;
    443                         return ret;
    444                 }
    445           case OperatorNode::SizeOf:
    446                 {
    447                         if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
    448                                 return new SizeofExpr( arg->get_decl()->buildType());
    449                         } else {
    450                                 return new SizeofExpr( args.front());
    451                         } // if
    452                 }
    453           case OperatorNode::AlignOf:
    454                 {
    455                         if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
    456                                 return new AlignofExpr( arg->get_decl()->buildType());
    457                         } else {
    458                                 return new AlignofExpr( args.front());
    459                         } // if
    460                 }
    461           case OperatorNode::OffsetOf:
    462                 {
    463                         assert( args.size() == 2 );
    464 
    465                         if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args() ) ) {
    466                                 NameExpr *member = dynamic_cast<NameExpr *>( args.back() );
    467                                 assert( member != 0 );
    468 
    469                                 return new UntypedOffsetofExpr( arg->get_decl()->buildType(), member->get_name() );
    470                         } else assert( false );
    471                 }
    472           case OperatorNode::Attr:
    473                 {
    474                         VarRefNode *var = dynamic_cast<VarRefNode *>( get_args());
    475                         assert( var );
    476                         if ( ! get_args()->get_link() ) {
    477                                 return new AttrExpr( maybeBuild<Expression>(var), ( Expression*)0);
    478                         } else if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()->get_link()) ) {
    479                                 return new AttrExpr( maybeBuild<Expression>(var), arg->get_decl()->buildType());
    480                         } else {
    481                                 return new AttrExpr( maybeBuild<Expression>(var), args.back());
    482                         } // if
    483                 }
    484           case OperatorNode::Or:
    485           case OperatorNode::And:
    486                 assert( args.size() == 2);
    487                 return new LogicalExpr( notZeroExpr( args.front() ), notZeroExpr( args.back() ), ( op->get_type() == OperatorNode::And ) );
    488           case OperatorNode::Cond:
    489                 {
    490                         assert( args.size() == 3);
    491                         std::list< Expression * >::const_iterator i = args.begin();
    492                         Expression *arg1 = notZeroExpr( *i++ );
    493                         Expression *arg2 = *i++;
    494                         Expression *arg3 = *i++;
    495                         return new ConditionalExpr( arg1, arg2, arg3 );
    496                 }
    497           case OperatorNode::NCond:
    498                 throw UnimplementedError( "GNU 2-argument conditional expression" );
    499           case OperatorNode::Comma:
    500                 {
    501                         assert( args.size() == 2);
    502                         std::list< Expression * >::const_iterator i = args.begin();
    503                         Expression *ret = *i++;
    504                         while ( i != args.end() ) {
    505                                 ret = new CommaExpr( ret, *i++ );
    506                         }
    507                         return ret;
    508                 }
    509                 // Tuples
    510           case OperatorNode::TupleC:
    511                 {
    512                         TupleExpr *ret = new TupleExpr();
    513                         std::copy( args.begin(), args.end(), back_inserter( ret->get_exprs() ) );
    514                         return ret;
    515                 }
    516           default:
    517                 // shouldn't happen
    518                 assert( false );
    519                 return 0;
    520         } // switch
    521 }
    522 
    523 void CompositeExprNode::printOneLine( std::ostream &os, int indent ) const {
    524         printDesignation( os );
    525         os << "( ";
    526         function->printOneLine( os, indent );
    527         for ( ExpressionNode *cur = arguments; cur != 0; cur = dynamic_cast< ExpressionNode* >( cur->get_link() ) ) {
    528                 cur->printOneLine( os, indent );
    529         } // for
    530         os << ") ";
    531 }
    532 
    533 void CompositeExprNode::print( std::ostream &os, int indent ) const {
    534         printDesignation( os );
    535         os << string( indent, ' ' ) << "Application of: " << endl;
    536         function->print( os, indent + ParseNode::indent_by );
    537 
    538         os << string( indent, ' ' ) ;
    539         if ( arguments ) {
    540                 os << "... on arguments: " << endl;
    541                 arguments->printList( os, indent + ParseNode::indent_by );
    542         } else
    543                 os << "... on no arguments: " << endl;
    544 }
    545 
    546 void CompositeExprNode::set_function( ExpressionNode *f ) {
    547         function = f;
    548 }
    549 
    550 void CompositeExprNode::set_args( ExpressionNode *args ) {
    551         arguments = args;
    552 }
    553 
    554 ExpressionNode *CompositeExprNode::get_function( void ) const {
    555         return function;
    556 }
    557 
    558 ExpressionNode *CompositeExprNode::get_args( void ) const {
    559         return arguments;
    560 }
    561 
    562 void CompositeExprNode::add_arg( ExpressionNode *arg ) {
    563         if ( arguments )
    564                 arguments->set_link( arg );
    565         else
    566                 set_args( arg );
    567 }
    568 
    569 //##############################################################################
    570 
    571 Expression *AsmExprNode::build() const {
    572         return new AsmExpr( maybeBuild< Expression >( inout ), (ConstantExpr *)maybeBuild<Expression>(constraint), maybeBuild<Expression>(operand) );
    573 }
    574 
    575 void AsmExprNode::print( std::ostream &os, int indent ) const {
    576         os << string( indent, ' ' ) << "Assembler Expression:" << endl;
    577         if ( inout ) {
    578                 os << string( indent, ' ' ) << "inout: " << std::endl;
    579                 inout->print( os, indent + 2 );
    580         } // if
    581         if ( constraint ) {
    582                 os << string( indent, ' ' ) << "constraint: " << std::endl;
    583                 constraint->print( os, indent + 2 );
    584         } // if
    585         if ( operand ) {
    586                 os << string( indent, ' ' ) << "operand: " << std::endl;
    587                 operand->print( os, indent + 2 );
    588         } // if
    589 }
    590 
    591 void AsmExprNode::printOneLine( std::ostream &os, int indent ) const {
    592         printDesignation( os );
    593         os << "( ";
    594         if ( inout ) inout->printOneLine( os, indent + 2 );
    595         os << ", ";
    596         if ( constraint ) constraint->printOneLine( os, indent + 2 );
    597         os << ", ";
    598         if ( operand ) operand->printOneLine( os, indent + 2 );
    599         os << ") ";
    600 }
    601 
    602 //##############################################################################
    603 
    604 void LabelNode::print( std::ostream &os, int indent ) const {}
    605 
    606 void LabelNode::printOneLine( std::ostream &os, int indent ) const {}
    607 
    608 //##############################################################################
    609 
    610 CommaExprNode::CommaExprNode(): CompositeExprNode( new OperatorNode( OperatorNode::Comma )) {}
    611 
    612 CommaExprNode::CommaExprNode( ExpressionNode *exp ) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp ) {
    613 }
    614 
    615 CommaExprNode::CommaExprNode( ExpressionNode *exp1, ExpressionNode *exp2) : CompositeExprNode( new OperatorNode( OperatorNode::Comma ), exp1, exp2) {
    616 }
    617 
    618 CommaExprNode *CommaExprNode::add_to_list( ExpressionNode *exp ) {
    619         add_arg( exp );
    620 
    621         return this;
    622 }
    623 
    624 CommaExprNode::CommaExprNode( const CommaExprNode &other ) : CompositeExprNode( other ) {
    625 }
    626 
    627 //##############################################################################
    628 
    629 ValofExprNode::ValofExprNode( StatementNode *s ): body( s ) {}
    630 
    631 ValofExprNode::ValofExprNode( const ValofExprNode &other ) : ExpressionNode( other ), body( maybeClone( body ) ) {
    632 }
    633 
    634 ValofExprNode::~ValofExprNode() {
    635         delete body;
    636 }
    637 
    638 void ValofExprNode::print( std::ostream &os, int indent ) const {
    639         printDesignation( os );
    640         os << string( indent, ' ' ) << "Valof Expression:" << std::endl;
    641         get_body()->print( os, indent + 4);
    642 }
    643 
    644 void ValofExprNode::printOneLine( std::ostream &, int indent ) const {
    645         assert( false );
    646 }
    647 
    648 Expression *ValofExprNode::build() const {
    649         return new UntypedValofExpr ( maybeBuild<Statement>(get_body()), maybeBuild< Expression >( get_argName() ) );
    650 }
    651 
    652 //##############################################################################
    653 
    654 ForCtlExprNode::ForCtlExprNode( ParseNode *init_, ExpressionNode *cond, ExpressionNode *incr ) throw ( SemanticError ) : condition( cond ), change( incr ) {
    655         if ( init_ == 0 )
    656                 init = 0;
    657         else {
    658                 DeclarationNode *decl;
    659                 ExpressionNode *exp;
    660 
    661                 if (( decl = dynamic_cast<DeclarationNode *>(init_) ) != 0)
    662                         init = new StatementNode( decl );
    663                 else if (( exp = dynamic_cast<ExpressionNode *>( init_)) != 0)
    664                         init = new StatementNode( StatementNode::Exp, exp );
    665                 else
    666                         throw SemanticError("Error in for control expression");
    667         }
    668 }
    669 
    670 ForCtlExprNode::ForCtlExprNode( const ForCtlExprNode &other )
    671         : ExpressionNode( other ), init( maybeClone( other.init ) ), condition( maybeClone( other.condition ) ), change( maybeClone( other.change ) ) {
    672 }
    673 
    674 ForCtlExprNode::~ForCtlExprNode() {
    675         delete init;
    676         delete condition;
    677         delete change;
    678 }
    679 
    680 Expression *ForCtlExprNode::build() const {
    681         // this shouldn't be used!
    682         assert( false );
    683         return 0;
    684 }
    685 
    686 void ForCtlExprNode::print( std::ostream &os, int indent ) const{
    687         os << string( indent,' ' ) << "For Control Expression -- :" << endl;
    688 
    689         os << string( indent + 2, ' ' ) << "initialization:" << endl;
    690         if ( init != 0 )
    691                 init->printList( os, indent + 4 );
    692 
    693         os << string( indent + 2, ' ' ) << "condition: " << endl;
    694         if ( condition != 0 )
    695                 condition->print( os, indent + 4 );
    696         os << string( indent + 2, ' ' ) << "increment: " << endl;
    697         if ( change != 0 )
    698                 change->print( os, indent + 4 );
    699 }
    700 
    701 void ForCtlExprNode::printOneLine( std::ostream &, int indent ) const {
    702         assert( false );
    703 }
    704 
    705 //##############################################################################
    706 
    707 TypeValueNode::TypeValueNode( DeclarationNode *decl ) : decl( decl ) {
    708 }
    709 
    710 TypeValueNode::TypeValueNode( const TypeValueNode &other ) : ExpressionNode( other ), decl( maybeClone( other.decl ) ) {
    711 }
    712 
    713 Expression *TypeValueNode::build() const {
     182Expression *build_cast( DeclarationNode *decl_node, ExpressionNode *expr_node ) {
     183        Type *targetType = decl_node->buildType();
     184        if ( dynamic_cast< VoidType * >( targetType ) ) {
     185                delete targetType;
     186                return new CastExpr( maybeBuild< Expression >(expr_node) );
     187        } else {
     188                return new CastExpr( maybeBuild< Expression >(expr_node), targetType );
     189        } // if
     190}
     191
     192Expression *build_fieldSel( ExpressionNode *expr_node, NameExpr *member ) {
     193        UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), maybeBuild< Expression >(expr_node) );
     194        delete member;
     195        return ret;
     196}
     197
     198Expression *build_pfieldSel( ExpressionNode *expr_node, NameExpr *member ) {
     199        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     200        deref->get_args().push_back( maybeBuild< Expression >(expr_node) );
     201        UntypedMemberExpr *ret = new UntypedMemberExpr( member->get_name(), deref );
     202        delete member;
     203        return ret;
     204}
     205
     206Expression *build_addressOf( ExpressionNode *expr_node ) {
     207                return new AddressExpr( maybeBuild< Expression >(expr_node) );
     208}
     209Expression *build_sizeOfexpr( ExpressionNode *expr_node ) {
     210        return new SizeofExpr( maybeBuild< Expression >(expr_node) );
     211}
     212Expression *build_sizeOftype( DeclarationNode *decl_node ) {
     213        return new SizeofExpr( decl_node->buildType() );
     214}
     215Expression *build_alignOfexpr( ExpressionNode *expr_node ) {
     216        return new AlignofExpr( maybeBuild< Expression >(expr_node) );
     217}
     218Expression *build_alignOftype( DeclarationNode *decl_node ) {
     219        return new AlignofExpr( decl_node->buildType() );
     220}
     221Expression *build_offsetOf( DeclarationNode *decl_node, NameExpr *member ) {
     222        return new UntypedOffsetofExpr( decl_node->buildType(), member->get_name() );
     223}
     224
     225Expression *build_and_or( ExpressionNode *expr_node1, ExpressionNode *expr_node2, bool kind ) {
     226        return new LogicalExpr( notZeroExpr( maybeBuild< Expression >(expr_node1) ), notZeroExpr( maybeBuild< Expression >(expr_node2) ), kind );
     227}
     228
     229Expression *build_unary_val( OperKinds op, ExpressionNode *expr_node ) {
     230        std::list< Expression * > args;
     231        args.push_back( maybeBuild< Expression >(expr_node) );
     232        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     233}
     234Expression *build_unary_ptr( OperKinds op, ExpressionNode *expr_node ) {
     235        std::list< Expression * > args;
     236        args.push_back( new AddressExpr( maybeBuild< Expression >(expr_node) ) );
     237        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     238}
     239Expression *build_binary_val( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
     240        std::list< Expression * > args;
     241        args.push_back( maybeBuild< Expression >(expr_node1) );
     242        args.push_back( maybeBuild< Expression >(expr_node2) );
     243        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     244}
     245Expression *build_binary_ptr( OperKinds op, ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
     246        std::list< Expression * > args;
     247        args.push_back( new AddressExpr( maybeBuild< Expression >(expr_node1) ) );
     248        args.push_back( maybeBuild< Expression >(expr_node2) );
     249        return new UntypedExpr( new NameExpr( OperName[ (int)op ] ), args );
     250}
     251
     252Expression *build_cond( ExpressionNode *expr_node1, ExpressionNode *expr_node2, ExpressionNode *expr_node3 ) {
     253        return new ConditionalExpr( notZeroExpr( maybeBuild< Expression >(expr_node1) ), maybeBuild< Expression >(expr_node2), maybeBuild< Expression >(expr_node3) );
     254}
     255
     256Expression *build_comma( ExpressionNode *expr_node1, ExpressionNode *expr_node2 ) {
     257        return new CommaExpr( maybeBuild< Expression >(expr_node1), maybeBuild< Expression >(expr_node2) );
     258}
     259
     260Expression *build_attrexpr( NameExpr *var, ExpressionNode * expr_node ) {
     261        return new AttrExpr( var, maybeBuild< Expression >(expr_node) );
     262}
     263Expression *build_attrtype( NameExpr *var, DeclarationNode * decl_node ) {
     264        return new AttrExpr( var, decl_node->buildType() );
     265}
     266
     267Expression *build_tuple( ExpressionNode * expr_node ) {
     268        TupleExpr *ret = new TupleExpr();
     269        buildList( expr_node, ret->get_exprs() );
     270        return ret;
     271}
     272
     273Expression *build_func( ExpressionNode * function, ExpressionNode * expr_node ) {
     274        std::list< Expression * > args;
     275
     276        buildList( expr_node, args );
     277        return new UntypedExpr( maybeBuild< Expression >(function), args, nullptr );
     278}
     279
     280Expression *build_range( ExpressionNode * low, ExpressionNode *high ) {
     281        Expression *low_cexpr = maybeBuild< Expression >( low );
     282        Expression *high_cexpr = maybeBuild< Expression >( high );
     283        return new RangeExpr( low_cexpr, high_cexpr );
     284}
     285
     286Expression *build_asmexpr( ExpressionNode *inout, ConstantExpr *constraint, ExpressionNode *operand ) {
     287        return new AsmExpr( maybeBuild< Expression >( inout ), constraint, maybeBuild< Expression >(operand) );
     288}
     289
     290Expression *build_valexpr( StatementNode *s ) {
     291        return new UntypedValofExpr( maybeBuild< Statement >(s), nullptr );
     292}
     293Expression *build_typevalue( DeclarationNode *decl ) {
    714294        return new TypeExpr( decl->buildType() );
    715295}
    716296
    717 void TypeValueNode::print( std::ostream &os, int indent ) const {
    718         os << std::string( indent, ' ' ) << "Type:";
    719         get_decl()->print( os, indent + 2);
    720 }
    721 
    722 void TypeValueNode::printOneLine( std::ostream &os, int indent ) const {
    723         os << "Type:";
    724         get_decl()->print( os, indent + 2);
    725 }
    726 
    727 
    728 CompoundLiteralNode::CompoundLiteralNode( DeclarationNode *type, InitializerNode *kids ) : type( type ), kids( kids ) {}
    729 CompoundLiteralNode::CompoundLiteralNode( const CompoundLiteralNode &other ) : ExpressionNode( other ), type( other.type ), kids( other.kids ) {}
    730 
    731 CompoundLiteralNode::~CompoundLiteralNode() {
    732         delete kids;
    733         delete type;
    734 }
    735 
    736 CompoundLiteralNode *CompoundLiteralNode::clone() const {
    737         return new CompoundLiteralNode( *this );
    738 }
    739 
    740 void CompoundLiteralNode::print( std::ostream &os, int indent ) const {
    741         os << string( indent,' ' ) << "CompoundLiteralNode:" << endl;
    742 
    743         os << string( indent + 2, ' ' ) << "type:" << endl;
    744         if ( type != 0 )
    745                 type->print( os, indent + 4 );
    746 
    747         os << string( indent + 2, ' ' ) << "initialization:" << endl;
    748         if ( kids != 0 )
    749                 kids->printList( os, indent + 4 );
    750 }
    751 
    752 void CompoundLiteralNode::printOneLine( std::ostream &os, int indent ) const {
    753         os << "( ";
    754         if ( type ) type->print( os );
    755         os << ", ";
    756         if ( kids ) kids->printOneLine( os );
    757         os << ") ";
    758 }
    759 
    760 Expression *CompoundLiteralNode::build() const {
    761         Declaration * newDecl = maybeBuild<Declaration>(type); // compound literal type
     297Expression *build_compoundLiteral( DeclarationNode *decl_node, InitializerNode *kids ) {
     298        Declaration * newDecl = maybeBuild< Declaration >(decl_node); // compound literal type
    762299        if ( DeclarationWithType * newDeclWithType = dynamic_cast< DeclarationWithType * >( newDecl ) ) { // non-sue compound-literal type
    763                 return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild<Initializer>(kids) );
     300                return new CompoundLiteralExpr( newDeclWithType->get_type(), maybeBuild< Initializer >(kids) );
    764301        // these types do not have associated type information
    765302        } else if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( newDecl )  ) {
    766                 return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild<Initializer>(kids) );
     303                return new CompoundLiteralExpr( new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ), maybeBuild< Initializer >(kids) );
    767304        } else if ( UnionDecl * newDeclUnionDecl = dynamic_cast< UnionDecl * >( newDecl )  ) {
    768                 return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild<Initializer>(kids) );
     305                return new CompoundLiteralExpr( new UnionInstType( Type::Qualifiers(), newDeclUnionDecl->get_name() ), maybeBuild< Initializer >(kids) );
    769306        } else if ( EnumDecl * newDeclEnumDecl = dynamic_cast< EnumDecl * >( newDecl )  ) {
    770                 return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild<Initializer>(kids) );
     307                return new CompoundLiteralExpr( new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() ), maybeBuild< Initializer >(kids) );
    771308        } else {
    772309                assert( false );
    773310        } // if
    774 }
    775 
    776 
    777 ExpressionNode *flattenCommas( ExpressionNode *list ) {
    778         if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( list ) ) {
    779                 OperatorNode *op;
    780                 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::Comma ) ) {
    781                         if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
    782                                 composite->add_arg( next );
    783                         return flattenCommas( composite->get_args() );
    784                 } // if
    785         } // if
    786 
    787         if ( ExpressionNode *next = dynamic_cast< ExpressionNode * >( list->get_link() ) )
    788                 list->set_next( flattenCommas( next ) );
    789 
    790         return list;
    791 }
    792 
    793 ExpressionNode *tupleContents( ExpressionNode *tuple ) {
    794         if ( CompositeExprNode *composite = dynamic_cast< CompositeExprNode * >( tuple ) ) {
    795                 OperatorNode *op = 0;
    796                 if ( ( op = dynamic_cast< OperatorNode * >( composite->get_function() )) && ( op->get_type() == OperatorNode::TupleC ) )
    797                         return composite->get_args();
    798         } // if
    799         return tuple;
    800311}
    801312
Note: See TracChangeset for help on using the changeset viewer.