Changeset f02f546 for src/ResolvExpr
- Timestamp:
- Jun 21, 2023, 1:28:09 PM (12 months ago)
- Branches:
- master
- Children:
- 6065281f
- Parents:
- 2de175ce
- Location:
- src/ResolvExpr
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/ResolveTypeof.h
r2de175ce rf02f546 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 } // namespace ResolvExpr -
src/ResolvExpr/Unify.cc
r2de175ce rf02f546 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
Note: See TracChangeset
for help on using the changeset viewer.