Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.cpp

    rcf32116 r312029a  
    99// Author           : Aaron B. Moss
    1010// Created On       : Wed May 15 17:00:00 2019
    11 // Last Modified By : Andrew Beach
    12 // Created On       : Thr Jun 26 12:12:00 2019
    13 // Update Count     : 3
     11// Last Modified By : Peter A. Buhr
     12// Created On       : Thr Jun 13 13:38:00 2019
     13// Update Count     : 6
    1414//
    1515
     
    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 );
     
    8871}
    8972
    90 bool UntypedExpr::get_lvalue() const {
    91         std::string fname = InitTweak::getFunctionName( this );
    92         return lvalueFunctionNames.count( fname );
    93 }
    94 
    9573UntypedExpr * UntypedExpr::createAssign( const CodeLocation & loc, Expr * lhs, Expr * rhs ) {
    9674        assert( lhs && rhs );
    9775
    98         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        };
    9979        if ( lhs->result && rhs->result ) {
    10080                // if both expressions are typed, assumes that this assignment is a C bitwise assignment,
     
    128108AddressExpr::AddressExpr( const CodeLocation & loc, const Expr * a ) : Expr( loc ), arg( a ) {
    129109        if ( arg->result ) {
    130                 if ( arg->get_lvalue() ) {
     110                if ( arg->result->is_lvalue() ) {
    131111                        // lvalue, retains all levels of reference, and gains a pointer inside the references
    132112                        Type * res = addrType( arg->result );
     
    159139: Expr( loc, new VoidType{} ), arg( a ), isGenerated( g ) {}
    160140
    161 bool CastExpr::get_lvalue() const {
    162         // This is actually wrong by C, but it works with our current set-up.
    163         return arg->get_lvalue();
    164 }
    165 
    166141// --- KeywordCastExpr
    167142
    168 const std::string & KeywordCastExpr::targetString() const {
    169         static const std::string targetStrs[] = {
    170                 "coroutine", "thread", "monitor"
    171         };
    172         static_assert(
    173                 (sizeof(targetStrs) / sizeof(targetStrs[0])) == ((unsigned long)NUMBER_OF_TARGETS),
    174                 "Each KeywordCastExpr::Target should have a corresponding string representation"
    175         );
    176         return targetStrs[(unsigned long)target];
    177 }
    178 
    179 // --- UntypedMemberExpr
    180 
    181 bool UntypedMemberExpr::get_lvalue() const {
    182         return aggregate->get_lvalue();
     143const char * KeywordCastExpr::targetString() const {
     144        return AggregateDecl::aggrString( target );
    183145}
    184146
     
    191153        assert( aggregate->result );
    192154
    193         // Deep copy on result type avoids mutation on transitively multiply referenced object.
    194         //
    195         // Example, adapted from parts of builtins and bootloader:
    196         //
    197         // forall(dtype T)
    198         // struct __Destructor {
    199         //   T * object;
    200         //   void (*dtor)(T *);
    201         // };
    202         //
    203         // forall(dtype S)
    204         // void foo(__Destructor(S) &d) {
    205         //   if (d.dtor) {  // here
    206         //   }
    207         // }
    208         //
    209         // Let e be the "d.dtor" guard espression, which is MemberExpr after resolve.  Let d be the
    210         // declaration of member __Destructor.dtor (an ObjectDecl), as accessed via the top-level
    211         // declaration of __Destructor.  Consider the types e.result and d.type.  In the old AST, one
    212         // is a clone of the other.  Ordinary new-AST use would set them up as a multiply-referenced
    213         // object.
    214         //
    215         // e.result: PointerType
    216         // .base: FunctionType
    217         // .params.front(): ObjectDecl, the anonymous parameter of type T*
    218         // .type: PointerType
    219         // .base: TypeInstType
    220         // let x = that
    221         // let y = similar, except start from d.type
    222         //
    223         // Consider two code lines down, genericSubstitution(...).apply(result).
    224         //
    225         // Applying this chosen-candidate's type substitution means modifying x, substituting
    226         // S for T.  This mutation should affect x and not y.
    227 
    228         result = deepCopy(mem->get_type());
    229 
     155        // take ownership of member type
     156        result = mem->get_type();
    230157        // substitute aggregate generic parameters into member type
    231158        genericSubstitution( aggregate->result ).apply( result );
     
    234161}
    235162
    236 MemberExpr::MemberExpr( const CodeLocation & loc, const DeclWithType * mem, const Expr * agg,
    237     MemberExpr::NoOpConstruction overloadSelector )
    238 : Expr( loc ), member( mem ), aggregate( agg ) {
    239         assert( member );
    240         assert( aggregate );
    241         assert( aggregate->result );
    242         (void) overloadSelector;
    243 }
    244 
    245 bool MemberExpr::get_lvalue() const {
    246         // This is actually wrong by C, but it works with our current set-up.
    247         return true;
    248 }
    249 
    250163// --- VariableExpr
    251164
     
    257170        assert( var );
    258171        assert( var->get_type() );
    259         auto r = shallowCopy( var->get_type() );
    260         r->qualifiers |= CV::Lvalue;
    261         result = r;
    262 }
    263 
    264 bool VariableExpr::get_lvalue() const {
    265         // It isn't always an lvalue, but it is never an rvalue.
    266         return true;
     172        result = var->get_type();
     173        add_qualifiers( result, CV::Lvalue );
    267174}
    268175
     
    350257        const CodeLocation & loc, const Expr * a1, const Expr * a2, LogicalFlag ia )
    351258: Expr( loc, new BasicType{ BasicType::SignedInt } ), arg1( a1 ), arg2( a2 ), isAnd( ia ) {}
    352 
    353 // --- CommaExpr
    354 bool CommaExpr::get_lvalue() const {
    355         // This is wrong by C, but the current implementation uses it.
    356         // (ex: Specialize, Lvalue and Box)
    357         return arg2->get_lvalue();
    358 }
    359259
    360260// --- ConstructorExpr
     
    379279}
    380280
    381 bool CompoundLiteralExpr::get_lvalue() const {
    382         return true;
    383 }
    384 
    385281// --- TupleExpr
    386282
     
    398294        result = type->types[ index ];
    399295        add_qualifiers( result, CV::Lvalue );
    400 }
    401 
    402 bool TupleIndexExpr::get_lvalue() const {
    403         return tuple->get_lvalue();
    404296}
    405297
Note: See TracChangeset for help on using the changeset viewer.