Changeset c5e3208


Ignore:
Timestamp:
Jul 12, 2017, 5:20:59 PM (4 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
c6976ba
Parents:
49148d5
Message:

Properly assign types to AddressExpr?

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SynTree/AddressExpr.cc

    r49148d5 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                 if ( ReferenceType * refType = dynamic_cast< ReferenceType * > ( arg->get_result() ) ) {
    23                         // xxx - very temporary, make &ref look like **
    24                         set_result( new PointerType( Type::Qualifiers( Type::Lvalue ), refType->get_base()->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() ) );
    2544                } else {
    26                         set_result( new PointerType( Type::Qualifiers(), arg->get_result()->clone() ) );
     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() ) );
    2748                }
     49                // result of & is never an lvalue
     50                get_result()->set_lvalue( false );
    2851        }
    2952}
Note: See TracChangeset for help on using the changeset viewer.