Ignore:
Timestamp:
Aug 25, 2017, 10:38:34 AM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
800d275
Parents:
af08051 (diff), 3eab308c (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/SynTree/AddressExpr.cc

    raf08051 r28e58fd  
    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}
Note: See TracChangeset for help on using the changeset viewer.