Changeset 2a301ff for src/ResolvExpr


Ignore:
Timestamp:
Aug 31, 2023, 11:31:15 PM (10 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
950c58e
Parents:
92355883 (diff), 686912c (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:

Resolve conflict

Location:
src/ResolvExpr
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/ResolvExpr/CommonType.cc

    r92355883 r2a301ff  
    696696                void postvisit( const ast::BasicType * basic ) {
    697697                        if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) {
    698                                 #warning remove casts when `commonTypes` moved to new AST
    699                                
    700                                 /*
    701                                 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ];
    702                                 if (
    703                                         ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers )
    704                                                 || widen.first )
    705                                         && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers )
    706                                                 || widen.second )
    707                                 ) {
    708                                         result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
    709                                 }
    710                                 */
    711698                                ast::BasicType::Kind kind;
    712699                                if (basic->kind != basic2->kind && !widen.first && !widen.second) return;
     
    719706                                        result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers };
    720707                                }
    721                                
    722708                        } else if (
    723709                                dynamic_cast< const ast::ZeroType * >( type2 )
    724710                                || dynamic_cast< const ast::OneType * >( type2 )
    725711                        ) {
    726                                 #warning remove casts when `commonTypes` moved to new AST
    727                                 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
    728                                 /*
    729                                 if ( // xxx - what does qualifier even do here??
    730                                         ( ( basic->qualifiers >= type2->qualifiers )
    731                                                 || widen.first )
    732                                          && ( ( /* kind != basic->kind && basic->qualifiers <= type2->qualifiers )
    733                                                 || widen.second )
    734                                 )
    735                                 */
    736712                                if (widen.second) {
    737713                                        result = new ast::BasicType{ basic->kind, basic->qualifiers | type2->qualifiers };
    738714                                }
    739715                        } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) {
    740                                 #warning remove casts when `commonTypes` moved to new AST
    741716                                const ast::EnumDecl* enumDecl = enumInst->base;
    742717                                if ( enumDecl->base ) {
    743718                                        result = enumDecl->base.get();
    744719                                } else {
     720                                        #warning remove casts when `commonTypes` moved to new AST
    745721                                        ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ];
    746722                                        if (
     
    763739                                auto entry = open.find( *var );
    764740                                if ( entry != open.end() ) {
    765                                 // if (tenv.lookup(*var)) {
    766741                                        ast::AssertionSet need, have;
    767742                                        if ( ! tenv.bindVar(
  • src/ResolvExpr/ResolveTypeof.h

    r92355883 r2a301ff  
    3030        Type *resolveTypeof( Type*, const SymTab::Indexer &indexer );
    3131        const ast::Type * resolveTypeof( const ast::Type *, const ResolveContext & );
     32        const ast::Type * fixArrayType( const ast::Type *, const ResolveContext & );
    3233        const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & );
    3334        const ast::ObjectDecl * fixObjectInit( const ast::ObjectDecl * decl , const ResolveContext &);
  • src/ResolvExpr/Unify.cc

    r92355883 r2a301ff  
    3232#include "AST/Type.hpp"
    3333#include "AST/TypeEnvironment.hpp"
     34#include "Common/Eval.h"            // for eval
    3435#include "Common/PassVisitor.h"     // for PassVisitor
    3536#include "CommonType.hpp"           // for commonType
     
    779780        }
    780781
     782        // Unification of Expressions
     783        //
     784        // Boolean outcome (obvious):  Are they basically spelled the same?
     785        // Side effect of binding variables (subtle):  if `sizeof(int)` ===_expr `sizeof(T)` then `int` ===_ty `T`
     786        //
     787        // Context:  if `float[VAREXPR1]` ===_ty `float[VAREXPR2]` then `VAREXPR1` ===_expr `VAREXPR2`
     788        // where the VAREXPR are meant as notational metavariables representing the fact that unification always
     789        // sees distinct ast::VariableExpr objects at these positions
     790
     791        static bool unify( const ast::Expr * e1, const ast::Expr * e2, ast::TypeEnvironment & env,
     792                ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     793                WidenMode widen );
     794
     795        class UnifyExpr final : public ast::WithShortCircuiting {
     796                const ast::Expr * e2;
     797                ast::TypeEnvironment & tenv;
     798                ast::AssertionSet & need;
     799                ast::AssertionSet & have;
     800                const ast::OpenVarSet & open;
     801                WidenMode widen;
     802        public:
     803                bool result;
     804
     805        private:
     806
     807                void tryMatchOnStaticValue( const ast::Expr * e1 ) {
     808                        Evaluation r1 = eval(e1);
     809                        Evaluation r2 = eval(e2);
     810
     811                        if ( ! r1.hasKnownValue ) return;
     812                        if ( ! r2.hasKnownValue ) return;
     813
     814                        if (r1.knownValue != r2.knownValue) return;
     815
     816                        visit_children = false;
     817                        result = true;
     818                }
     819
     820        public:
     821
     822                void previsit( const ast::Node * ) { assert(false); }
     823
     824                void previsit( const ast::Expr * e1 ) {
     825                        tryMatchOnStaticValue( e1 );
     826                        visit_children = false;
     827                }
     828
     829                void previsit( const ast::CastExpr * e1 ) {
     830                        tryMatchOnStaticValue( e1 );
     831
     832                        if (result) {
     833                                assert (visit_children == false);
     834                        } else {
     835                                assert (visit_children == true);
     836                                visit_children = false;
     837
     838                                auto e2c = dynamic_cast< const ast::CastExpr * >( e2 );
     839                                if ( ! e2c ) return;
     840
     841                                // inspect casts' target types
     842                                if ( ! unifyExact(
     843                                        e1->result, e2c->result, tenv, need, have, open, widen ) ) return;
     844
     845                                // inspect casts' inner expressions
     846                                result = unify( e1->arg, e2c->arg, tenv, need, have, open, widen );
     847                        }
     848                }
     849
     850                void previsit( const ast::VariableExpr * e1 ) {
     851                        tryMatchOnStaticValue( e1 );
     852
     853                        if (result) {
     854                                assert (visit_children == false);
     855                        } else {
     856                                assert (visit_children == true);
     857                                visit_children = false;
     858
     859                                auto e2v = dynamic_cast< const ast::VariableExpr * >( e2 );
     860                                if ( ! e2v ) return;
     861
     862                                assert(e1->var);
     863                                assert(e2v->var);
     864
     865                                // conservative: variable exprs match if their declarations are represented by the same C++ AST object
     866                                result = (e1->var == e2v->var);
     867                        }
     868                }
     869
     870                void previsit( const ast::SizeofExpr * e1 ) {
     871                        tryMatchOnStaticValue( e1 );
     872
     873                        if (result) {
     874                                assert (visit_children == false);
     875                        } else {
     876                                assert (visit_children == true);
     877                                visit_children = false;
     878
     879                                auto e2so = dynamic_cast< const ast::SizeofExpr * >( e2 );
     880                                if ( ! e2so ) return;
     881
     882                                assert((e1->type != nullptr) ^ (e1->expr != nullptr));
     883                                assert((e2so->type != nullptr) ^ (e2so->expr != nullptr));
     884                                if ( ! (e1->type && e2so->type) )  return;
     885
     886                                // expression unification calls type unification (mutual recursion)
     887                                result = unifyExact( e1->type, e2so->type, tenv, need, have, open, widen );
     888                        }
     889                }
     890
     891                UnifyExpr( const ast::Expr * e2, ast::TypeEnvironment & env, ast::AssertionSet & need,
     892                        ast::AssertionSet & have, const ast::OpenVarSet & open, WidenMode widen )
     893                : e2( e2 ), tenv(env), need(need), have(have), open(open), widen(widen), result(false) {}
     894        };
     895
     896        static bool unify( const ast::Expr * e1, const ast::Expr * e2, ast::TypeEnvironment & env,
     897                ast::AssertionSet & need, ast::AssertionSet & have, const ast::OpenVarSet & open,
     898                WidenMode widen ) {
     899                assert( e1 && e2 );
     900                return ast::Pass<UnifyExpr>::read( e1, e2, env, need, have, open, widen );
     901        }
     902
    781903        class Unify_new final : public ast::WithShortCircuiting {
    782904                const ast::Type * type2;
     
    820942                        if ( ! array2 ) return;
    821943
    822                         // to unify, array types must both be VLA or both not VLA and both must have a
    823                         // dimension expression or not have a dimension
    824944                        if ( array->isVarLen != array2->isVarLen ) return;
    825                         if ( ! array->isVarLen && ! array2->isVarLen
    826                                         && array->dimension && array2->dimension ) {
    827                                 auto ce1 = array->dimension.as< ast::ConstantExpr >();
    828                                 auto ce2 = array2->dimension.as< ast::ConstantExpr >();
    829 
    830                                 // see C11 Reference Manual 6.7.6.2.6
    831                                 // two array types with size specifiers that are integer constant expressions are
    832                                 // compatible if both size specifiers have the same constant value
    833                                 if ( ce1 && ce2 && ce1->intValue() != ce2->intValue() ) return;
     945                        if ( (array->dimension != nullptr) != (array2->dimension != nullptr) ) return;
     946
     947                        if ( array->dimension ) {
     948                                assert( array2->dimension );
     949                                // type unification calls expression unification (mutual recursion)
     950                                if ( ! unify(array->dimension, array2->dimension,
     951                                    tenv, need, have, open, widen) ) return;
    834952                        }
    835953
     
    11801298                auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 );
    11811299                auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 );
    1182                 ast::OpenVarSet::const_iterator
    1183                         entry1 = var1 ? open.find( *var1 ) : open.end(),
    1184                         entry2 = var2 ? open.find( *var2 ) : open.end();
    1185                 // bool isopen1 = entry1 != open.end();
    1186                 // bool isopen2 = entry2 != open.end();
    11871300                bool isopen1 = var1 && env.lookup(*var1);
    11881301                bool isopen2 = var2 && env.lookup(*var2);
    11891302
    1190                 /*
    1191                 if ( isopen1 && isopen2 ) {
    1192                         if ( entry1->second.kind != entry2->second.kind ) return false;
    1193                         return env.bindVarToVar(
    1194                                 var1, var2, ast::TypeData{ entry1->second, entry2->second }, need, have,
    1195                                 open, widen );
    1196                 } else if ( isopen1 ) {
    1197                         return env.bindVar( var1, type2, entry1->second, need, have, open, widen );
    1198                 } else if ( isopen2 ) {
    1199                         return env.bindVar( var2, type1, entry2->second, need, have, open, widen, symtab );
    1200                 } */
    12011303                if ( isopen1 && isopen2 ) {
    12021304                        if ( var1->base->kind != var2->base->kind ) return false;
     
    12081310                } else if ( isopen2 ) {
    12091311                        return env.bindVar( var2, type1, ast::TypeData{var2->base}, need, have, open, widen );
    1210                 }else {
     1312                } else {
    12111313                        return ast::Pass<Unify_new>::read(
    12121314                                type1, type2, env, need, have, open, widen );
    12131315                }
    1214                
    12151316        }
    12161317
Note: See TracChangeset for help on using the changeset viewer.