Changes in / [3cd5fdd:8568319]
- Location:
- src
- Files:
-
- 4 deleted
- 11 edited
-
AST/Print.hpp (modified) (1 diff)
-
AST/SymbolTable.hpp (modified) (1 diff)
-
AST/porting.md (modified) (1 diff)
-
Common/Indenter.h (modified) (1 diff)
-
Makefile.in (modified) (4 diffs)
-
ResolvExpr/AlternativeFinder.cc (modified) (1 diff)
-
ResolvExpr/Candidate.cpp (deleted)
-
ResolvExpr/Candidate.hpp (deleted)
-
ResolvExpr/CandidateFinder.cpp (deleted)
-
ResolvExpr/CandidateFinder.hpp (deleted)
-
ResolvExpr/ResolveAssertions.cc (modified) (2 diffs)
-
ResolvExpr/Resolver.cc (modified) (12 diffs)
-
ResolvExpr/module.mk (modified) (1 diff)
-
ResolvExpr/typeops.h (modified) (1 diff)
-
SynTree/BaseSyntaxNode.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Print.hpp
r3cd5fdd r8568319 29 29 void print( std::ostream & os, const ast::Node * node, Indenter indent = {} ); 30 30 31 /// Wrap any standard format printer (matching above) with integer Indenter constructor 32 template<typename T> 33 inline void print( std::ostream & os, T && x, unsigned int indent ) { 34 print( os, std::forward<T>(x), Indenter{ Indenter::tabsize, indent }); 35 } 36 31 37 /// Print a declaration in its short form 32 38 void printShort( std::ostream & os, const ast::Decl * node, Indenter indent = {} ); 33 39 34 40 inline void printShort( std::ostream & os, const ast::Decl * node, unsigned int indent ) { 35 printShort( os, node, Indenter{ indent } );41 printShort( os, node, Indenter{ Indenter::tabsize, indent } ); 36 42 } 37 43 -
src/AST/SymbolTable.hpp
r3cd5fdd r8568319 85 85 86 86 public: 87 SymbolTable();87 explicit SymbolTable(); 88 88 ~SymbolTable(); 89 89 -
src/AST/porting.md
r3cd5fdd r8568319 295 295 * changed `WidenMode widenMode` => `WidenMode widen` 296 296 297 `Alternative` => `Candidate`298 * `openVars` => `open`299 300 297 [1] https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Type-Attributes.html#Type-Attributes 301 298 -
src/Common/Indenter.h
r3cd5fdd r8568319 18 18 19 19 struct Indenter { 20 static unsigned tabsize; ///< default number of spaces in one level of indentation20 static unsigned tabsize; 21 21 22 unsigned int indent; ///< number of spaces to indent 23 unsigned int amt; ///< spaces in one level of indentation 22 Indenter( unsigned int amt = tabsize, unsigned int indent = 0 ) : amt( amt ), indent( indent ) {} 23 unsigned int amt; // amount 1 level increases indent by (i.e. how much to increase by in operator++) 24 unsigned int indent; 24 25 25 Indenter( unsigned int indent = 0, unsigned int amt = tabsize )26 : indent( indent*amt ), amt( amt ) {}27 28 26 Indenter & operator+=(int nlevels) { indent += amt*nlevels; return *this; } 29 27 Indenter & operator-=(int nlevels) { indent -= amt*nlevels; return *this; } -
src/Makefile.in
r3cd5fdd r8568319 189 189 ResolvExpr/Alternative.$(OBJEXT) \ 190 190 ResolvExpr/AlternativeFinder.$(OBJEXT) \ 191 ResolvExpr/Candidate.$(OBJEXT) \192 ResolvExpr/CandidateFinder.$(OBJEXT) \193 191 ResolvExpr/CastCost.$(OBJEXT) ResolvExpr/CommonType.$(OBJEXT) \ 194 192 ResolvExpr/ConversionCost.$(OBJEXT) \ … … 624 622 ResolvExpr/Alternative.cc \ 625 623 ResolvExpr/AlternativeFinder.cc \ 626 ResolvExpr/Candidate.cpp \627 ResolvExpr/CandidateFinder.cpp \628 624 ResolvExpr/CastCost.cc \ 629 625 ResolvExpr/CommonType.cc \ … … 876 872 ResolvExpr/AlternativeFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 877 873 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 878 ResolvExpr/Candidate.$(OBJEXT): ResolvExpr/$(am__dirstamp) \879 ResolvExpr/$(DEPDIR)/$(am__dirstamp)880 ResolvExpr/CandidateFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \881 ResolvExpr/$(DEPDIR)/$(am__dirstamp)882 874 ResolvExpr/CastCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 883 875 ResolvExpr/$(DEPDIR)/$(am__dirstamp) … … 1262 1254 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AlternativeFinder.Po@am__quote@ 1263 1255 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AlternativePrinter.Po@am__quote@ 1264 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Candidate.Po@am__quote@1265 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CandidateFinder.Po@am__quote@1266 1256 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CastCost.Po@am__quote@ 1267 1257 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CommonType.Po@am__quote@ -
src/ResolvExpr/AlternativeFinder.cc
r3cd5fdd r8568319 136 136 137 137 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt ) { 138 Indenter indent = { indentAmt };138 Indenter indent = { Indenter::tabsize, indentAmt }; 139 139 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) { 140 140 i->print( os, indent ); -
src/ResolvExpr/ResolveAssertions.cc
r3cd5fdd r8568319 365 365 // fail early if any assertion is not resolvable 366 366 if ( ! resolveAssertion( assn, resn ) ) { 367 Indenter tabs{ 3 };367 Indenter tabs{ Indenter::tabsize, 3 }; 368 368 std::ostringstream ss; 369 369 ss << tabs << "Unsatisfiable alternative:\n"; … … 391 391 // fail early if no mutually-compatible assertion satisfaction 392 392 if ( compatible.empty() ) { 393 Indenter tabs{ 3 };393 Indenter tabs{ Indenter::tabsize, 3 }; 394 394 std::ostringstream ss; 395 395 ss << tabs << "Unsatisfiable alternative:\n"; -
src/ResolvExpr/Resolver.cc
r3cd5fdd r8568319 21 21 #include "Alternative.h" // for Alternative, AltList 22 22 #include "AlternativeFinder.h" // for AlternativeFinder, resolveIn... 23 #include "Candidate.hpp"24 #include "CandidateFinder.hpp"25 23 #include "CurrentObject.h" // for CurrentObject 26 24 #include "RenameVars.h" // for RenameVars, global_renamer … … 33 31 #include "AST/Init.hpp" 34 32 #include "AST/Pass.hpp" 35 #include "AST/Print.hpp"36 33 #include "AST/SymbolTable.hpp" 37 34 #include "Common/PassVisitor.h" // for PassVisitor … … 119 116 120 117 namespace { 121 struct DeleteFinder _old: public WithShortCircuiting {118 struct DeleteFinder : public WithShortCircuiting { 122 119 DeletedExpr * delExpr = nullptr; 123 120 void previsit( DeletedExpr * expr ) { … … 133 130 134 131 DeletedExpr * findDeletedExpr( Expression * expr ) { 135 PassVisitor<DeleteFinder _old> finder;132 PassVisitor<DeleteFinder> finder; 136 133 expr->accept( finder ); 137 134 return finder.pass.delExpr; … … 139 136 140 137 namespace { 141 struct StripCasts _old{138 struct StripCasts { 142 139 Expression * postmutate( CastExpr * castExpr ) { 143 140 if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) { … … 152 149 153 150 static void strip( Expression *& expr ) { 154 PassVisitor<StripCasts _old> stripper;151 PassVisitor<StripCasts> stripper; 155 152 expr = expr->acceptMutator( stripper ); 156 153 } … … 160 157 expr->env = oldenv ? oldenv->clone() : new TypeSubstitution; 161 158 env.makeSubstitution( *expr->env ); 162 StripCasts _old::strip( expr ); // remove unnecessary casts that may be buried in an expression159 StripCasts::strip( expr ); // remove unnecessary casts that may be buried in an expression 163 160 } 164 161 … … 943 940 /////////////////////////////////////////////////////////////////////////// 944 941 945 namespace {946 /// Finds deleted expressions in an expression tree947 struct DeleteFinder_new final : public ast::WithShortCircuiting {948 const ast::DeletedExpr * delExpr = nullptr;949 950 void previsit( const ast::DeletedExpr * expr ) {951 if ( delExpr ) { visit_children = false; }952 else { delExpr = expr; }953 }954 955 void previsit( const ast::Expr * ) {956 if ( delExpr ) { visit_children = false; }957 }958 };959 960 /// Check if this expression is or includes a deleted expression961 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) {962 ast::Pass<DeleteFinder_new> finder;963 expr->accept( finder );964 return finder.pass.delExpr;965 }966 967 /// Calls the CandidateFinder and finds the single best candidate968 CandidateRef findUnfinishedKindExpression(969 const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,970 std::function<bool(const Candidate &)> pred, ResolvMode mode = {}971 ) {972 if ( ! untyped ) return nullptr;973 974 // xxx - this isn't thread-safe, but should work until we parallelize the resolver975 static unsigned recursion_level = 0;976 977 ++recursion_level;978 ast::TypeEnvironment env;979 CandidateFinder finder{ symtab, env };980 finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode );981 --recursion_level;982 983 // produce a filtered list of candidates984 CandidateList candidates;985 for ( auto & cand : finder.candidates ) {986 if ( pred( *cand ) ) { candidates.emplace_back( cand ); }987 }988 989 // produce invalid error if no candidates990 if ( candidates.empty() ) {991 SemanticError( untyped,992 toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""),993 "expression: ") );994 }995 996 // search for cheapest candidate997 CandidateList winners;998 bool seen_undeleted = false;999 for ( CandidateRef & cand : candidates ) {1000 int c = winners.empty() ? -1 : cand->cost.compare( winners.front()->cost );1001 1002 if ( c > 0 ) continue; // skip more expensive than winner1003 1004 if ( c < 0 ) {1005 // reset on new cheapest1006 seen_undeleted = ! findDeletedExpr( cand->expr );1007 winners.clear();1008 } else /* if ( c == 0 ) */ {1009 if ( findDeletedExpr( cand->expr ) ) {1010 // skip deleted expression if already seen one equivalent-cost not1011 if ( seen_undeleted ) continue;1012 } else if ( ! seen_undeleted ) {1013 // replace list of equivalent-cost deleted expressions with one non-deleted1014 winners.clear();1015 seen_undeleted = true;1016 }1017 }1018 1019 winners.emplace_back( std::move( cand ) );1020 }1021 1022 // promote candidate.cvtCost to .cost1023 for ( CandidateRef & cand : winners ) {1024 cand->cost = cand->cvtCost;1025 }1026 1027 // produce ambiguous errors, if applicable1028 if ( winners.size() != 1 ) {1029 std::ostringstream stream;1030 stream << "Cannot choose between " << winners.size() << " alternatives for "1031 << kind << (kind != "" ? " " : "") << "expression\n";1032 ast::print( stream, untyped );1033 stream << " Alternatives are:\n";1034 print( stream, winners, 1 );1035 SemanticError( untyped->location, stream.str() );1036 }1037 1038 // single selected choice1039 CandidateRef & choice = winners.front();1040 1041 // fail on only expression deleted1042 if ( ! seen_undeleted ) {1043 SemanticError( untyped->location, choice->expr.get(), "Unique best alternative "1044 "includes deleted identifier in " );1045 }1046 1047 return std::move( choice );1048 }1049 1050 /// Strips extraneous casts out of an expression1051 struct StripCasts_new final {1052 const ast::Expr * postmutate( const ast::CastExpr * castExpr ) {1053 if (1054 castExpr->isGenerated1055 && typesCompatible( castExpr->arg->result, castExpr->result )1056 ) {1057 // generated cast is the same type as its argument, remove it after keeping env1058 ast::ptr<ast::Expr> arg = castExpr->arg;1059 arg.get_and_mutate()->env = castExpr->env;1060 return arg;1061 }1062 return castExpr;1063 }1064 1065 static void strip( ast::ptr< ast::Expr > & expr ) {1066 ast::Pass< StripCasts_new > stripper;1067 expr = expr->accept( stripper );1068 }1069 };1070 1071 /// Establish post-resolver invariants for expressions1072 void finishExpr(1073 ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env,1074 const ast::TypeSubstitution * oldenv = nullptr1075 ) {1076 // set up new type substitution for expression1077 ast::ptr< ast::TypeSubstitution > newenv =1078 oldenv ? oldenv : new ast::TypeSubstitution{};1079 env.writeToSubstitution( *newenv.get_and_mutate() );1080 expr.get_and_mutate()->env = std::move( newenv );1081 // remove unncecessary casts1082 StripCasts_new::strip( expr );1083 }1084 1085 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the1086 /// lowest cost, returning the resolved version1087 ast::ptr< ast::Expr > findKindExpression(1088 const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind,1089 std::function<bool(const Candidate &)> pred, ResolvMode mode = {}1090 ) {1091 if ( ! untyped ) return {};1092 CandidateRef choice =1093 findUnfinishedKindExpression( untyped, symtab, kind, pred, mode );1094 finishExpr( choice->expr, choice->env, untyped->env );1095 return std::move( choice->expr );1096 }1097 1098 /// Predicate for "Candidate has integral type"1099 bool hasIntegralType( const Candidate & i ) {1100 const ast::Type * type = i.expr->result;1101 1102 if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) {1103 return bt->isInteger();1104 } else if (1105 dynamic_cast< const ast::EnumInstType * >( type )1106 || dynamic_cast< const ast::ZeroType * >( type )1107 || dynamic_cast< const ast::OneType * >( type )1108 ) {1109 return true;1110 } else return false;1111 }1112 1113 /// Resolve `untyped` as an integral expression, returning the resolved version1114 ast::ptr< ast::Expr > findIntegralExpression(1115 const ast::Expr * untyped, const ast::SymbolTable & symtab1116 ) {1117 return findKindExpression( untyped, symtab, "condition", hasIntegralType );1118 }1119 }1120 1121 942 class Resolver_new final 1122 943 : public ast::WithSymbolTable, public ast::WithGuards, … … 1126 947 ast::ptr< ast::Type > functionReturn = nullptr; 1127 948 // ast::CurrentObject currentObject = nullptr; 1128 bool inEnumDecl = false;949 // bool inEnumDecl = false; 1129 950 1130 951 public: … … 1132 953 Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; } 1133 954 1134 void previsit( const ast::FunctionDecl * );1135 const ast::FunctionDecl * postvisit( const ast::FunctionDecl * );1136 void previsit( const ast::ObjectDecl * );1137 void previsit( const ast::EnumDecl * );1138 const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl *);1139 1140 void previsit( const ast::ArrayType * );1141 void previsit( const ast::PointerType * );1142 1143 void previsit( const ast::ExprStmt * );1144 void previsit( const ast::AsmExpr * );1145 void previsit( const ast::AsmStmt * );1146 void previsit( const ast::IfStmt * );1147 void previsit( const ast::WhileStmt * );1148 void previsit( const ast::ForStmt * );1149 void previsit( const ast::SwitchStmt * );1150 void previsit( const ast::CaseStmt * );1151 void previsit( const ast::BranchStmt * );1152 void previsit( const ast::ReturnStmt * );1153 void previsit( const ast::ThrowStmt * );1154 void previsit( const ast::CatchStmt * );1155 void previsit( const ast::WaitForStmt * );1156 1157 void previsit( const ast::SingleInit * );1158 void previsit( const ast::ListInit * );1159 void previsit( const ast::ConstructorInit * );955 void previsit( const ast::FunctionDecl * functionDecl ); 956 const ast::FunctionDecl * postvisit( const ast::FunctionDecl * functionDecl ); 957 void previsit( const ast::ObjectDecl * objectDecl ); 958 void previsit( const ast::EnumDecl * enumDecl ); 959 void previsit( const ast::StaticAssertDecl * assertDecl ); 960 961 void previsit( const ast::ArrayType * at ); 962 void previsit( const ast::PointerType * pt ); 963 964 void previsit( const ast::ExprStmt * exprStmt ); 965 void previsit( const ast::AsmExpr * asmExpr ); 966 void previsit( const ast::AsmStmt * asmStmt ); 967 void previsit( const ast::IfStmt * ifStmt ); 968 void previsit( const ast::WhileStmt * whileStmt ); 969 void previsit( const ast::ForStmt * forStmt ); 970 void previsit( const ast::SwitchStmt * switchStmt ); 971 void previsit( const ast::CaseStmt * caseStmt ); 972 void previsit( const ast::BranchStmt * branchStmt ); 973 void previsit( const ast::ReturnStmt * returnStmt ); 974 void previsit( const ast::ThrowStmt * throwStmt ); 975 void previsit( const ast::CatchStmt * catchStmt ); 976 void previsit( const ast::WaitForStmt * stmt ); 977 978 void previsit( const ast::SingleInit * singleInit ); 979 void previsit( const ast::ListInit * listInit ); 980 void previsit( const ast::ConstructorInit * ctorInit ); 1160 981 }; 1161 982 … … 1183 1004 ast::chain_mutate( ret ) 1184 1005 ( &ast::FunctionDecl::type ) 1185 ( &ast::FunctionType::params )[i] 1006 ( &ast::FunctionType::params ) 1007 [i] 1186 1008 ( &ast::ObjectDecl::init ) 1187 1009 ( &ast::SingleInit::value )->env = nullptr; … … 1201 1023 } 1202 1024 1203 void Resolver_new::previsit( const ast::EnumDecl * ) { 1204 // in case we decide to allow nested enums 1205 GuardValue( inEnumDecl ); 1206 inEnumDecl = false; 1207 } 1208 1209 const ast::StaticAssertDecl * Resolver_new::previsit( 1210 const ast::StaticAssertDecl * assertDecl 1211 ) { 1212 ast::ptr< ast::Expr > cond = findIntegralExpression( assertDecl->cond, symtab ); 1213 if ( cond == assertDecl->cond ) return assertDecl; 1214 1215 ast::StaticAssertDecl * ret = mutate( assertDecl ); 1216 ret->cond = cond; 1217 return ret; 1025 void Resolver_new::previsit( const ast::EnumDecl * enumDecl ) { 1026 #warning unimplemented; Resolver port in progress 1027 (void)enumDecl; 1028 assert(false); 1029 } 1030 1031 void Resolver_new::previsit( const ast::StaticAssertDecl * assertDecl ) { 1032 #warning unimplemented; Resolver port in progress 1033 (void)assertDecl; 1034 assert(false); 1218 1035 } 1219 1036 -
src/ResolvExpr/module.mk
r3cd5fdd r8568319 19 19 ResolvExpr/Alternative.cc \ 20 20 ResolvExpr/AlternativeFinder.cc \ 21 ResolvExpr/Candidate.cpp \22 ResolvExpr/CandidateFinder.cpp \23 21 ResolvExpr/CastCost.cc \ 24 22 ResolvExpr/CommonType.cc \ -
src/ResolvExpr/typeops.h
r3cd5fdd r8568319 103 103 104 104 bool typesCompatible( 105 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},105 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 106 106 const ast::TypeEnvironment & env = {} ); 107 107 -
src/SynTree/BaseSyntaxNode.h
r3cd5fdd r8568319 41 41 /// * Expressions should not finish with a newline, since the expression's parent has better information. 42 42 virtual void print( std::ostream & os, Indenter indent = {} ) const = 0; 43 void print( std::ostream & os, unsigned int indent ) { 44 print( os, Indenter{ Indenter::tabsize, indent }); 45 } 43 46 }; 44 47
Note:
See TracChangeset
for help on using the changeset viewer.