Changeset 58fe85a for src/AST/Expr.cpp


Ignore:
Timestamp:
Jan 7, 2021, 3:27:00 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
2b4daf2, 64aeca0
Parents:
3c64c668 (diff), eef8dfb (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' into park_unpark

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Expr.cpp

    r3c64c668 r58fe85a  
    2020#include <vector>
    2121
     22#include "Copy.hpp"                // for shallowCopy
     23#include "Eval.hpp"                // for call
    2224#include "GenericSubstitution.hpp"
     25#include "LinkageSpec.hpp"
    2326#include "Stmt.hpp"
    2427#include "Type.hpp"
     
    2730#include "Common/SemanticError.h"
    2831#include "GenPoly/Lvalue.h"        // for referencesPermissable
    29 #include "InitTweak/InitTweak.h"   // for getPointerBase
     32#include "InitTweak/InitTweak.h"   // for getFunction, getPointerBase
    3033#include "ResolvExpr/typeops.h"    // for extractResultType
    3134#include "Tuples/Tuples.h"         // for makeTupleType
    3235
    3336namespace ast {
     37
     38namespace {
     39        std::set<std::string> const lvalueFunctionNames = {"*?", "?[?]"};
     40}
     41
     42// --- Expr
     43bool Expr::get_lvalue() const {
     44        return false;
     45}
    3446
    3547// --- ApplicationExpr
     
    4658}
    4759
     60bool 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
    4867// --- UntypedExpr
    4968
    50 UntypedExpr * UntypedExpr::createDeref( const CodeLocation & loc, Expr * arg ) {
     69UntypedExpr * UntypedExpr::createDeref( const CodeLocation & loc, const Expr * arg ) {
    5170        assert( arg );
    5271
    53         UntypedExpr * ret = new UntypedExpr{
    54                 loc, new NameExpr{loc, "*?"}, std::vector<ptr<Expr>>{ ptr<Expr>{ arg } }
    55         };
     72        UntypedExpr * ret = call( loc, "*?", arg );
    5673        if ( const Type * ty = arg->result ) {
    5774                const Type * base = InitTweak::getPointerBase( ty );
     
    6582                        // base type
    6683                        ret->result = base;
    67                         add_qualifiers( ret->result, CV::Lvalue );
    6884                }
    6985        }
     
    7187}
    7288
    73 UntypedExpr * UntypedExpr::createAssign( const CodeLocation & loc, Expr * lhs, Expr * rhs ) {
     89bool UntypedExpr::get_lvalue() const {
     90        std::string fname = InitTweak::getFunctionName( this );
     91        return lvalueFunctionNames.count( fname );
     92}
     93
     94UntypedExpr * UntypedExpr::createAssign( const CodeLocation & loc, const Expr * lhs, const Expr * rhs ) {
    7495        assert( lhs && rhs );
    7596
    76         UntypedExpr * ret = new UntypedExpr{
    77                 loc, new NameExpr{loc, "?=?"}, std::vector<ptr<Expr>>{ ptr<Expr>{ lhs }, ptr<Expr>{ rhs } }
    78         };
     97        UntypedExpr * ret = call( loc, "?=?", lhs, rhs );
    7998        if ( lhs->result && rhs->result ) {
    8099                // if both expressions are typed, assumes that this assignment is a C bitwise assignment,
     
    83102        }
    84103        return ret;
     104}
     105
     106// --- VariableExpr
     107
     108VariableExpr::VariableExpr( const CodeLocation & loc )
     109: Expr( loc ), var( nullptr ) {}
     110
     111VariableExpr::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
     118bool VariableExpr::get_lvalue() const {
     119        // It isn't always an lvalue, but it is never an rvalue.
     120        return true;
     121}
     122
     123VariableExpr * 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;
    85129}
    86130
     
    108152AddressExpr::AddressExpr( const CodeLocation & loc, const Expr * a ) : Expr( loc ), arg( a ) {
    109153        if ( arg->result ) {
    110                 if ( arg->result->is_lvalue() ) {
     154                if ( arg->get_lvalue() ) {
    111155                        // lvalue, retains all levels of reference, and gains a pointer inside the references
    112156                        Type * res = addrType( arg->result );
    113                         res->set_lvalue( false ); // result of & is never an lvalue
    114157                        result = res;
    115158                } else {
     
    118161                                        dynamic_cast< const ReferenceType * >( arg->result.get() ) ) {
    119162                                Type * res = addrType( refType->base );
    120                                 res->set_lvalue( false ); // result of & is never an lvalue
    121163                                result = res;
    122164                        } else {
     
    139181: Expr( loc, new VoidType{} ), arg( a ), isGenerated( g ) {}
    140182
     183bool 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
    141188// --- KeywordCastExpr
    142189
    143190const char * KeywordCastExpr::targetString() const {
    144191        return AggregateDecl::aggrString( target );
     192}
     193
     194// --- UntypedMemberExpr
     195
     196bool UntypedMemberExpr::get_lvalue() const {
     197        return aggregate->get_lvalue();
    145198}
    146199
     
    153206        assert( aggregate->result );
    154207
    155         // take ownership of member type
    156208        result = mem->get_type();
     209
    157210        // substitute aggregate generic parameters into member type
    158211        genericSubstitution( aggregate->result ).apply( result );
    159         // ensure lvalue and appropriate restrictions from aggregate type
    160         add_qualifiers( result, aggregate->result->qualifiers | CV::Lvalue );
    161 }
    162 
    163 // --- VariableExpr
    164 
    165 VariableExpr::VariableExpr( const CodeLocation & loc )
    166 : Expr( loc ), var( nullptr ) {}
    167 
    168 VariableExpr::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 
    176 VariableExpr * 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;
     212        // ensure appropriate restrictions from aggregate type
     213        add_qualifiers( result, aggregate->result->qualifiers );
     214}
     215
     216MemberExpr::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
     225bool MemberExpr::get_lvalue() const {
     226        // This is actually wrong by C, but it works with our current set-up.
     227        return true;
    182228}
    183229
     
    258304: Expr( loc, new BasicType{ BasicType::SignedInt } ), arg1( a1 ), arg2( a2 ), isAnd( ia ) {}
    259305
     306// --- CommaExpr
     307bool 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}
     312
    260313// --- ConstructorExpr
    261314
     
    276329        assert( t && i );
    277330        result = t;
    278         add_qualifiers( result, CV::Lvalue );
     331}
     332
     333bool CompoundLiteralExpr::get_lvalue() const {
     334        return true;
    279335}
    280336
     
    293349        // like MemberExpr, TupleIndexExpr is always an lvalue
    294350        result = type->types[ index ];
    295         add_qualifiers( result, CV::Lvalue );
     351}
     352
     353bool TupleIndexExpr::get_lvalue() const {
     354        return tuple->get_lvalue();
    296355}
    297356
Note: See TracChangeset for help on using the changeset viewer.