Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SynTree/AddressExpr.cc

    r906e24d rc5e3208  
    1818#include "Common/utility.h"
    1919
     20// Address expressions are typed based on the following inference rules:
     21//    E : lvalue T  &..& (n references)
     22//   &E :        T *&..& (n references)
     23//
     24//    E : T  &..&        (m references)
     25//   &E : T *&..&        (m-1 references)
     26//
     27// That is, lvalues becomes
     28
     29namespace {
     30        Type * addrType( Type * type ) {
     31                if ( ReferenceType * refType = dynamic_cast< ReferenceType * >( type ) ) {
     32                        return new ReferenceType( refType->get_qualifiers(), addrType( refType->get_base() ) );
     33                } else {
     34                        return new PointerType( Type::Qualifiers(), type->clone() );
     35                }
     36        }
     37}
     38
    2039AddressExpr::AddressExpr( Expression *arg, Expression *_aname ) : Expression( _aname ), arg( arg ) {
    2140        if ( arg->has_result() ) {
    22                 set_result( new PointerType( Type::Qualifiers(), arg->get_result()->clone() ) );
     41                if ( arg->get_result()->get_lvalue() ) {
     42                        // lvalue, retains all layers of reference and gains a pointer inside the references
     43                        set_result( addrType( arg->get_result() ) );
     44                } else {
     45                        // taking address of non-lvalue -- must be a reference, loses one layer of reference
     46                        ReferenceType * refType = safe_dynamic_cast< ReferenceType * >( arg->get_result() );
     47                        set_result( addrType( refType->get_base() ) );
     48                }
     49                // result of & is never an lvalue
     50                get_result()->set_lvalue( false );
    2351        }
    2452}
Note: See TracChangeset for help on using the changeset viewer.