Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.cpp

    rf27331c rb91bfde  
    99// Author           : Aaron B. Moss
    1010// Created On       : Wed May 15 17:00:00 2019
    11 // Last Modified By : Andrew Beach
    12 // Created On       : Tue Nov 30 14:23:00 2021
    13 // Update Count     : 7
     11// Last Modified By : Peter A. Buhr
     12// Created On       : Thr Jun 13 13:38:00 2019
     13// Update Count     : 6
    1414//
    1515
     
    141141        /// The type of the address of a type.
    142142        /// Caller is responsible for managing returned memory
    143         Type * addrType( const ptr<Type> & type ) {
    144                 if ( auto refType = type.as< ReferenceType >() ) {
    145                         return new ReferenceType( addrType( refType->base ), refType->qualifiers );
     143        Type * addrType( const Type * type ) {
     144                if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * >( type ) ) {
     145                        return new ReferenceType{ addrType( refType->base ), refType->qualifiers };
    146146                } else {
    147                         return new PointerType( type );
     147                        return new PointerType{ type };
    148148                }
    149149        }
    150 
    151         /// The type of the address of an expression.
    152         /// Caller is responsible for managing returned memory
    153         Type * addrExprType( const CodeLocation & loc, const Expr * arg ) {
    154                 assert( arg );
    155                 // If the expression's type is unknown, the address type is unknown.
    156                 if ( nullptr == arg->result ) {
    157                         return nullptr;
    158                 // An lvalue is transformed directly.
    159                 } else if ( arg->get_lvalue() ) {
    160                         return addrType( arg->result );
    161                 // Strip a layer of reference to "create" an lvalue expression.
    162                 } else if ( auto refType = arg->result.as< ReferenceType >() ) {
    163                         return addrType( refType->base );
     150}
     151
     152AddressExpr::AddressExpr( const CodeLocation & loc, const Expr * a ) : Expr( loc ), arg( a ) {
     153        if ( arg->result ) {
     154                if ( arg->get_lvalue() ) {
     155                        // lvalue, retains all levels of reference, and gains a pointer inside the references
     156                        Type * res = addrType( arg->result );
     157                        result = res;
    164158                } else {
    165                         SemanticError( loc, arg->result.get(),
    166                                 "Attempt to take address of non-lvalue expression: " );
     159                        // taking address of non-lvalue, must be a reference, loses one layer of reference
     160                        if ( const ReferenceType * refType =
     161                                        dynamic_cast< const ReferenceType * >( arg->result.get() ) ) {
     162                                Type * res = addrType( refType->base );
     163                                result = res;
     164                        } else {
     165                                SemanticError( loc, arg->result.get(),
     166                                        "Attempt to take address of non-lvalue expression: " );
     167                        }
    167168                }
    168169        }
    169170}
    170 
    171 AddressExpr::AddressExpr( const CodeLocation & loc, const Expr * a ) :
    172         Expr( loc, addrExprType( loc, a ) ), arg( a )
    173 {}
    174171
    175172// --- LabelAddressExpr
Note: See TracChangeset for help on using the changeset viewer.