Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SynTree/AddressExpr.cc

    rea6332d r5809461  
    2121#include "Type.h"            // for PointerType, Type, Type::Qualifiers
    2222
     23// Address expressions are typed based on the following inference rules:
     24//    E : lvalue T  &..& (n references)
     25//   &E :        T *&..& (n references)
     26//
     27//    E : T  &..&        (m references)
     28//   &E : T *&..&        (m-1 references)
     29//
     30// That is, lvalues becomes
     31
     32namespace {
     33        Type * addrType( Type * type ) {
     34                if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( type ) ) {
     35                        return new ReferenceType( refType->get_qualifiers(), addrType( refType->get_base() ) );
     36                } else {
     37                        return new PointerType( Type::Qualifiers(), type->clone() );
     38                }
     39        }
     40}
     41
    2342AddressExpr::AddressExpr( Expression *arg, Expression *_aname ) : Expression( _aname ), arg( arg ) {
    2443        if ( arg->has_result() ) {
    25                 set_result( new PointerType( Type::Qualifiers(), arg->get_result()->clone() ) );
     44                if ( arg->get_result()->get_lvalue() ) {
     45                        // lvalue, retains all layers of reference and gains a pointer inside the references
     46                        set_result( addrType( arg->get_result() ) );
     47                } else {
     48                        // taking address of non-lvalue -- must be a reference, loses one layer of reference
     49                        ReferenceType * refType = safe_dynamic_cast< ReferenceType * >( arg->get_result() );
     50                        set_result( addrType( refType->get_base() ) );
     51                }
     52                // result of & is never an lvalue
     53                get_result()->set_lvalue( false );
    2654        }
    2755}
     
    4270}
    4371
     72LabelAddressExpr::LabelAddressExpr( const Label &arg ) : arg( arg ) {
     73        // label address always has type void *
     74        result = new PointerType( Type::Qualifiers(), new VoidType( Type::Qualifiers() ) );
     75}
     76LabelAddressExpr::LabelAddressExpr( const LabelAddressExpr & other ) : Expression( other ), arg( other.arg ) {}
     77LabelAddressExpr::~LabelAddressExpr() {}
     78
     79void LabelAddressExpr::print( std::ostream & os, int indent ) const {
     80        os << "Address of label:" << std::endl << std::string( indent+2, ' ' ) << arg;
     81}
     82
    4483// Local Variables: //
    4584// tab-width: 4 //
Note: See TracChangeset for help on using the changeset viewer.