Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.cpp

    rd5631b3 r312029a  
    2020#include <vector>
    2121
    22 #include "Copy.hpp"                // for shallowCopy
    23 #include "Eval.hpp"                // for call
    2422#include "GenericSubstitution.hpp"
    25 #include "LinkageSpec.hpp"
    2623#include "Stmt.hpp"
    2724#include "Type.hpp"
     
    3027#include "Common/SemanticError.h"
    3128#include "GenPoly/Lvalue.h"        // for referencesPermissable
    32 #include "InitTweak/InitTweak.h"   // for getFunction, getPointerBase
     29#include "InitTweak/InitTweak.h"   // for getPointerBase
    3330#include "ResolvExpr/typeops.h"    // for extractResultType
    3431#include "Tuples/Tuples.h"         // for makeTupleType
    3532
    3633namespace ast {
    37 
    38 namespace {
    39         std::set<std::string> const lvalueFunctionNames = {"*?", "?[?]"};
    40 }
    41 
    42 // --- Expr
    43 bool Expr::get_lvalue() const {
    44         return false;
    45 }
    4634
    4735// --- ApplicationExpr
     
    5846}
    5947
    60 bool ApplicationExpr::get_lvalue() const {
    61         if ( const DeclWithType * func = InitTweak::getFunction( this ) ) {
    62                 return func->linkage == Linkage::Intrinsic && lvalueFunctionNames.count( func->name );
    63         }
    64         return false;
    65 }
    66 
    6748// --- UntypedExpr
    6849
     
    7051        assert( arg );
    7152
    72         UntypedExpr * ret = call( loc, "*?", arg );
     53        UntypedExpr * ret = new UntypedExpr{
     54                loc, new NameExpr{loc, "*?"}, std::vector<ptr<Expr>>{ ptr<Expr>{ arg } }
     55        };
    7356        if ( const Type * ty = arg->result ) {
    7457                const Type * base = InitTweak::getPointerBase( ty );
     
    8265                        // base type
    8366                        ret->result = base;
     67                        add_qualifiers( ret->result, CV::Lvalue );
    8468                }
    8569        }
    8670        return ret;
    87 }
    88 
    89 bool UntypedExpr::get_lvalue() const {
    90         std::string fname = InitTweak::getFunctionName( this );
    91         return lvalueFunctionNames.count( fname );
    9271}
    9372
     
    9574        assert( lhs && rhs );
    9675
    97         UntypedExpr * ret = call( loc, "?=?", lhs, rhs );
     76        UntypedExpr * ret = new UntypedExpr{
     77                loc, new NameExpr{loc, "?=?"}, std::vector<ptr<Expr>>{ ptr<Expr>{ lhs }, ptr<Expr>{ rhs } }
     78        };
    9879        if ( lhs->result && rhs->result ) {
    9980                // if both expressions are typed, assumes that this assignment is a C bitwise assignment,
     
    10283        }
    10384        return ret;
    104 }
    105 
    106 // --- VariableExpr
    107 
    108 VariableExpr::VariableExpr( const CodeLocation & loc )
    109 : Expr( loc ), var( nullptr ) {}
    110 
    111 VariableExpr::VariableExpr( const CodeLocation & loc, const DeclWithType * v )
    112 : Expr( loc ), var( v ) {
    113         assert( var );
    114         assert( var->get_type() );
    115         result = shallowCopy( var->get_type() );
    116 }
    117 
    118 bool VariableExpr::get_lvalue() const {
    119         // It isn't always an lvalue, but it is never an rvalue.
    120         return true;
    121 }
    122 
    123 VariableExpr * VariableExpr::functionPointer(
    124                 const CodeLocation & loc, const FunctionDecl * decl ) {
    125         // wrap usually-determined result type in a pointer
    126         VariableExpr * funcExpr = new VariableExpr{ loc, decl };
    127         funcExpr->result = new PointerType{ funcExpr->result };
    128         return funcExpr;
    12985}
    13086
     
    152108AddressExpr::AddressExpr( const CodeLocation & loc, const Expr * a ) : Expr( loc ), arg( a ) {
    153109        if ( arg->result ) {
    154                 if ( arg->get_lvalue() ) {
     110                if ( arg->result->is_lvalue() ) {
    155111                        // lvalue, retains all levels of reference, and gains a pointer inside the references
    156112                        Type * res = addrType( arg->result );
     113                        res->set_lvalue( false ); // result of & is never an lvalue
    157114                        result = res;
    158115                } else {
     
    161118                                        dynamic_cast< const ReferenceType * >( arg->result.get() ) ) {
    162119                                Type * res = addrType( refType->base );
     120                                res->set_lvalue( false ); // result of & is never an lvalue
    163121                                result = res;
    164122                        } else {
     
    181139: Expr( loc, new VoidType{} ), arg( a ), isGenerated( g ) {}
    182140
    183 bool CastExpr::get_lvalue() const {
    184         // This is actually wrong by C, but it works with our current set-up.
    185         return arg->get_lvalue();
    186 }
    187 
    188141// --- KeywordCastExpr
    189142
    190143const char * KeywordCastExpr::targetString() const {
    191144        return AggregateDecl::aggrString( target );
    192 }
    193 
    194 // --- UntypedMemberExpr
    195 
    196 bool UntypedMemberExpr::get_lvalue() const {
    197         return aggregate->get_lvalue();
    198145}
    199146
     
    206153        assert( aggregate->result );
    207154
    208         // Deep copy on result type avoids mutation on transitively multiply referenced object.
    209         //
    210         // Example, adapted from parts of builtins and bootloader:
    211         //
    212         // forall(dtype T)
    213         // struct __Destructor {
    214         //   T * object;
    215         //   void (*dtor)(T *);
    216         // };
    217         //
    218         // forall(dtype S)
    219         // void foo(__Destructor(S) &d) {
    220         //   if (d.dtor) {  // here
    221         //   }
    222         // }
    223         //
    224         // Let e be the "d.dtor" guard espression, which is MemberExpr after resolve.  Let d be the
    225         // declaration of member __Destructor.dtor (an ObjectDecl), as accessed via the top-level
    226         // declaration of __Destructor.  Consider the types e.result and d.type.  In the old AST, one
    227         // is a clone of the other.  Ordinary new-AST use would set them up as a multiply-referenced
    228         // object.
    229         //
    230         // e.result: PointerType
    231         // .base: FunctionType
    232         // .params.front(): ObjectDecl, the anonymous parameter of type T*
    233         // .type: PointerType
    234         // .base: TypeInstType
    235         // let x = that
    236         // let y = similar, except start from d.type
    237         //
    238         // Consider two code lines down, genericSubstitution(...).apply(result).
    239         //
    240         // Applying this chosen-candidate's type substitution means modifying x, substituting
    241         // S for T.  This mutation should affect x and not y.
    242 
    243         result = deepCopy(mem->get_type());
    244 
     155        // take ownership of member type
     156        result = mem->get_type();
    245157        // substitute aggregate generic parameters into member type
    246158        genericSubstitution( aggregate->result ).apply( result );
    247         // ensure appropriate restrictions from aggregate type
    248         add_qualifiers( result, aggregate->result->qualifiers );
    249 }
    250 
    251 MemberExpr::MemberExpr( const CodeLocation & loc, const DeclWithType * mem, const Expr * agg,
    252     MemberExpr::NoOpConstruction overloadSelector )
    253 : Expr( loc ), member( mem ), aggregate( agg ) {
    254         assert( member );
    255         assert( aggregate );
    256         assert( aggregate->result );
    257         (void) overloadSelector;
    258 }
    259 
    260 bool MemberExpr::get_lvalue() const {
    261         // This is actually wrong by C, but it works with our current set-up.
    262         return true;
     159        // ensure lvalue and appropriate restrictions from aggregate type
     160        add_qualifiers( result, aggregate->result->qualifiers | CV::Lvalue );
     161}
     162
     163// --- VariableExpr
     164
     165VariableExpr::VariableExpr( const CodeLocation & loc )
     166: Expr( loc ), var( nullptr ) {}
     167
     168VariableExpr::VariableExpr( const CodeLocation & loc, const DeclWithType * v )
     169: Expr( loc ), var( v ) {
     170        assert( var );
     171        assert( var->get_type() );
     172        result = var->get_type();
     173        add_qualifiers( result, CV::Lvalue );
     174}
     175
     176VariableExpr * VariableExpr::functionPointer(
     177                const CodeLocation & loc, const FunctionDecl * decl ) {
     178        // wrap usually-determined result type in a pointer
     179        VariableExpr * funcExpr = new VariableExpr{ loc, decl };
     180        funcExpr->result = new PointerType{ funcExpr->result };
     181        return funcExpr;
    263182}
    264183
     
    338257        const CodeLocation & loc, const Expr * a1, const Expr * a2, LogicalFlag ia )
    339258: Expr( loc, new BasicType{ BasicType::SignedInt } ), arg1( a1 ), arg2( a2 ), isAnd( ia ) {}
    340 
    341 // --- CommaExpr
    342 bool CommaExpr::get_lvalue() const {
    343         // This is wrong by C, but the current implementation uses it.
    344         // (ex: Specialize, Lvalue and Box)
    345         return arg2->get_lvalue();
    346 }
    347259
    348260// --- ConstructorExpr
     
    364276        assert( t && i );
    365277        result = t;
    366 }
    367 
    368 bool CompoundLiteralExpr::get_lvalue() const {
    369         return true;
     278        add_qualifiers( result, CV::Lvalue );
    370279}
    371280
     
    384293        // like MemberExpr, TupleIndexExpr is always an lvalue
    385294        result = type->types[ index ];
    386 }
    387 
    388 bool TupleIndexExpr::get_lvalue() const {
    389         return tuple->get_lvalue();
     295        add_qualifiers( result, CV::Lvalue );
    390296}
    391297
Note: See TracChangeset for help on using the changeset viewer.