Changeset f27331c


Ignore:
Timestamp:
Nov 30, 2021, 2:34:25 PM (7 weeks ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
master
Children:
56f519b
Parents:
2cf3b87
Message:

Factored the AddressExpr? constructor body into a helper that makes it clear what it does.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.cpp

    r2cf3b87 rf27331c  
    99// Author           : Aaron B. Moss
    1010// Created On       : Wed May 15 17:00:00 2019
    11 // Last Modified By : Peter A. Buhr
    12 // Created On       : Thr Jun 13 13:38:00 2019
    13 // Update Count     : 6
     11// Last Modified By : Andrew Beach
     12// Created On       : Tue Nov 30 14:23:00 2021
     13// Update Count     : 7
    1414//
    1515
     
    141141        /// The type of the address of a type.
    142142        /// Caller is responsible for managing returned memory
    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 };
     143        Type * addrType( const ptr<Type> & type ) {
     144                if ( auto refType = type.as< ReferenceType >() ) {
     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 
    152 AddressExpr::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;
     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 );
    158164                } else {
    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                         }
     165                        SemanticError( loc, arg->result.get(),
     166                                "Attempt to take address of non-lvalue expression: " );
    168167                }
    169168        }
    170169}
     170
     171AddressExpr::AddressExpr( const CodeLocation & loc, const Expr * a ) :
     172        Expr( loc, addrExprType( loc, a ) ), arg( a )
     173{}
    171174
    172175// --- LabelAddressExpr
Note: See TracChangeset for help on using the changeset viewer.