Changeset 2a301ff for src/ResolvExpr
- Timestamp:
- Aug 31, 2023, 11:31:15 PM (20 months ago)
- 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. - Location:
- src/ResolvExpr
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
TabularUnified src/ResolvExpr/CommonType.cc ¶
r92355883 r2a301ff 696 696 void postvisit( const ast::BasicType * basic ) { 697 697 if ( auto basic2 = dynamic_cast< const ast::BasicType * >( type2 ) ) { 698 #warning remove casts when `commonTypes` moved to new AST699 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 */711 698 ast::BasicType::Kind kind; 712 699 if (basic->kind != basic2->kind && !widen.first && !widen.second) return; … … 719 706 result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers }; 720 707 } 721 722 708 } else if ( 723 709 dynamic_cast< const ast::ZeroType * >( type2 ) 724 710 || dynamic_cast< const ast::OneType * >( type2 ) 725 711 ) { 726 #warning remove casts when `commonTypes` moved to new AST727 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 */736 712 if (widen.second) { 737 713 result = new ast::BasicType{ basic->kind, basic->qualifiers | type2->qualifiers }; 738 714 } 739 715 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { 740 #warning remove casts when `commonTypes` moved to new AST741 716 const ast::EnumDecl* enumDecl = enumInst->base; 742 717 if ( enumDecl->base ) { 743 718 result = enumDecl->base.get(); 744 719 } else { 720 #warning remove casts when `commonTypes` moved to new AST 745 721 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ]; 746 722 if ( … … 763 739 auto entry = open.find( *var ); 764 740 if ( entry != open.end() ) { 765 // if (tenv.lookup(*var)) {766 741 ast::AssertionSet need, have; 767 742 if ( ! tenv.bindVar( -
TabularUnified src/ResolvExpr/ResolveTypeof.h ¶
r92355883 r2a301ff 30 30 Type *resolveTypeof( Type*, const SymTab::Indexer &indexer ); 31 31 const ast::Type * resolveTypeof( const ast::Type *, const ResolveContext & ); 32 const ast::Type * fixArrayType( const ast::Type *, const ResolveContext & ); 32 33 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ResolveContext & ); 33 34 const ast::ObjectDecl * fixObjectInit( const ast::ObjectDecl * decl , const ResolveContext &); -
TabularUnified src/ResolvExpr/Unify.cc ¶
r92355883 r2a301ff 32 32 #include "AST/Type.hpp" 33 33 #include "AST/TypeEnvironment.hpp" 34 #include "Common/Eval.h" // for eval 34 35 #include "Common/PassVisitor.h" // for PassVisitor 35 36 #include "CommonType.hpp" // for commonType … … 779 780 } 780 781 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 781 903 class Unify_new final : public ast::WithShortCircuiting { 782 904 const ast::Type * type2; … … 820 942 if ( ! array2 ) return; 821 943 822 // to unify, array types must both be VLA or both not VLA and both must have a823 // dimension expression or not have a dimension824 944 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; 834 952 } 835 953 … … 1180 1298 auto var1 = dynamic_cast< const ast::TypeInstType * >( type1 ); 1181 1299 auto var2 = dynamic_cast< const ast::TypeInstType * >( type2 ); 1182 ast::OpenVarSet::const_iterator1183 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();1187 1300 bool isopen1 = var1 && env.lookup(*var1); 1188 1301 bool isopen2 = var2 && env.lookup(*var2); 1189 1302 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 } */1201 1303 if ( isopen1 && isopen2 ) { 1202 1304 if ( var1->base->kind != var2->base->kind ) return false; … … 1208 1310 } else if ( isopen2 ) { 1209 1311 return env.bindVar( var2, type1, ast::TypeData{var2->base}, need, have, open, widen ); 1210 } else {1312 } else { 1211 1313 return ast::Pass<Unify_new>::read( 1212 1314 type1, type2, env, need, have, open, widen ); 1213 1315 } 1214 1215 1316 } 1216 1317
Note: See TracChangeset
for help on using the changeset viewer.