Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.cpp

    r3e5dd913 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
    69 UntypedExpr * UntypedExpr::createDeref( const CodeLocation & loc, const Expr * arg ) {
     50UntypedExpr * UntypedExpr::createDeref( const CodeLocation & loc, Expr * arg ) {
    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        }
     
    8771}
    8872
    89 bool UntypedExpr::get_lvalue() const {
    90         std::string fname = InitTweak::getFunctionName( this );
    91         return lvalueFunctionNames.count( fname );
    92 }
    93 
    94 UntypedExpr * UntypedExpr::createAssign( const CodeLocation & loc, const Expr * lhs, const Expr * rhs ) {
     73UntypedExpr * UntypedExpr::createAssign( const CodeLocation & loc, Expr * lhs, Expr * rhs ) {
    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
     155        // take ownership of member type
    208156        result = mem->get_type();
    209 
    210157        // substitute aggregate generic parameters into member type
    211158        genericSubstitution( aggregate->result ).apply( result );
    212         // ensure appropriate restrictions from aggregate type
    213         add_qualifiers( result, aggregate->result->qualifiers );
    214 }
    215 
    216 MemberExpr::MemberExpr( const CodeLocation & loc, const DeclWithType * mem, const Expr * agg,
    217     MemberExpr::NoOpConstruction overloadSelector )
    218 : Expr( loc ), member( mem ), aggregate( agg ) {
    219         assert( member );
    220         assert( aggregate );
    221         assert( aggregate->result );
    222         (void) overloadSelector;
    223 }
    224 
    225 bool MemberExpr::get_lvalue() const {
    226         // This is actually wrong by C, but it works with our current set-up.
    227         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;
    228182}
    229183
     
    303257        const CodeLocation & loc, const Expr * a1, const Expr * a2, LogicalFlag ia )
    304258: Expr( loc, new BasicType{ BasicType::SignedInt } ), arg1( a1 ), arg2( a2 ), isAnd( ia ) {}
    305 
    306 // --- CommaExpr
    307 bool CommaExpr::get_lvalue() const {
    308         // This is wrong by C, but the current implementation uses it.
    309         // (ex: Specialize, Lvalue and Box)
    310         return arg2->get_lvalue();
    311 }
    312259
    313260// --- ConstructorExpr
     
    329276        assert( t && i );
    330277        result = t;
    331 }
    332 
    333 bool CompoundLiteralExpr::get_lvalue() const {
    334         return true;
     278        add_qualifiers( result, CV::Lvalue );
    335279}
    336280
     
    349293        // like MemberExpr, TupleIndexExpr is always an lvalue
    350294        result = type->types[ index ];
    351 }
    352 
    353 bool TupleIndexExpr::get_lvalue() const {
    354         return tuple->get_lvalue();
     295        add_qualifiers( result, CV::Lvalue );
    355296}
    356297
Note: See TracChangeset for help on using the changeset viewer.