Changeset 54dd994 for src/ResolvExpr
- Timestamp:
- Jun 24, 2019, 10:30:47 AM (7 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 84917e2
- Parents:
- 3c6e417 (diff), 9e0a360 (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:
-
- 9 edited
-
Alternative.cc (modified) (1 diff)
-
Alternative.h (modified) (1 diff)
-
AlternativeFinder.cc (modified) (1 diff)
-
Candidate.hpp (modified) (1 diff)
-
CandidateFinder.cpp (modified) (5 diffs)
-
Cost.h (modified) (3 diffs)
-
RenameVars.cc (modified) (5 diffs)
-
Resolver.cc (modified) (3 diffs)
-
Resolver.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/Alternative.cc
r3c6e417 r54dd994 125 125 } 126 126 127 void splice( AltList& dst, AltList& src ) {128 dst.reserve( dst.size() + src.size() );129 for ( Alternative& alt : src ) {130 dst.push_back( std::move(alt) );131 }132 src.clear();133 }134 135 void spliceBegin( AltList& dst, AltList& src ) {136 splice( src, dst );137 dst.swap( src );138 }139 140 127 } // namespace ResolvExpr 141 128 -
src/ResolvExpr/Alternative.h
r3c6e417 r54dd994 112 112 typedef std::vector< Alternative > AltList; 113 113 114 /// Moves all elements from src to the end of dst115 void splice( AltList& dst, AltList& src );116 117 /// Moves all elements from src to the beginning of dst118 void spliceBegin( AltList& dst, AltList& src );119 120 114 static inline std::ostream & operator<<(std::ostream & os, const ResolvExpr::Alternative & alt) { 121 115 alt.print( os ); -
src/ResolvExpr/AlternativeFinder.cc
r3c6e417 r54dd994 56 56 #define PRINT( text ) if ( resolvep ) { text } 57 57 //#define DEBUG_COST 58 59 using std::move;60 61 /// copies any copyable type62 template<typename T>63 T copy(const T& x) { return x; }64 58 65 59 namespace ResolvExpr { -
src/ResolvExpr/Candidate.hpp
r3c6e417 r54dd994 75 75 using CandidateList = std::vector< CandidateRef >; 76 76 77 /// Splice src after dst, clearing src78 static inline void splice( CandidateList & dst, CandidateList & src ) {79 dst.reserve( dst.size() + src.size() );80 for ( CandidateRef & r : src ) { dst.emplace_back( std::move( r ) ); }81 src.clear();82 }83 84 /// Splice src before dst85 static inline void spliceBegin( CandidateList & dst, CandidateList & src ) {86 splice( src, dst );87 dst.swap( src );88 }89 90 77 /// Sum the cost of a list of candidates 91 78 static inline Cost sumCost( const CandidateList & candidates ) { -
src/ResolvExpr/CandidateFinder.cpp
r3c6e417 r54dd994 39 39 #include "AST/SymbolTable.hpp" 40 40 #include "AST/Type.hpp" 41 #include "Common/utility.h" // for move, copy 41 42 #include "SymTab/Mangler.h" 42 43 #include "SymTab/Validate.h" // for validateType … … 46 47 47 48 namespace ResolvExpr { 48 49 using std::move;50 51 /// partner to move that copies any copyable type52 template<typename T>53 T copy( const T & x ) { return x; }54 49 55 50 const ast::Expr * referenceToRvalueConversion( const ast::Expr * expr, Cost & cost ) { … … 57 52 // cast away reference from expr 58 53 cost.incReference(); 59 return new ast::CastExpr{ expr ->location, expr, expr->result->stripReferences() };54 return new ast::CastExpr{ expr, expr->result->stripReferences() }; 60 55 } 61 56 … … 126 121 ast::ptr< ast::Type > newType = paramType; 127 122 env.apply( newType ); 128 return new ast::CastExpr{ arg ->location, arg, newType };123 return new ast::CastExpr{ arg, newType }; 129 124 130 125 // xxx - *should* be able to resolve this cast, but at the moment pointers are not … … 793 788 794 789 if ( aggrType.as< ast::ReferenceType >() ) { 795 aggrExpr = 796 new ast::CastExpr{ aggrExpr->location, aggrExpr, aggrType->stripReferences() }; 790 aggrExpr = new ast::CastExpr{ aggrExpr, aggrType->stripReferences() }; 797 791 } 798 792 -
src/ResolvExpr/Cost.h
r3c6e417 r54dd994 10 10 // Created On : Sun May 17 09:39:50 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon Apr 29 18:33:44201913 // Update Count : 4912 // Last Modified On : Fri Jun 21 11:39:13 2019 13 // Update Count : 63 14 14 // 15 15 … … 21 21 22 22 namespace ResolvExpr { 23 #if 024 25 //*************************** OLD ***************************26 27 class Cost {28 private:29 Cost( int unsafeCost, int polyCost, int safeCost, int signCost,30 int varCost, int specCost, int referenceCost );31 public:32 Cost & incUnsafe( int inc = 1 );33 Cost & incPoly( int inc = 1 );34 Cost & incSafe( int inc = 1 );35 Cost & incSign( int inc = 1 );36 Cost & incVar( int inc = 1 );37 Cost & decSpec( int inc = 1 );38 Cost & incReference( int inc = 1 );39 40 int get_unsafeCost() const { return unsafeCost; }41 int get_polyCost() const { return polyCost; }42 int get_safeCost() const { return safeCost; }43 int get_signCost() const { return signCost; }44 int get_varCost() const { return varCost; }45 int get_specCost() const { return specCost; }46 int get_referenceCost() const { return referenceCost; }47 48 Cost operator+( const Cost &other ) const;49 Cost &operator+=( const Cost &other );50 bool operator<( const Cost &other ) const;51 bool operator==( const Cost &other ) const;52 bool operator!=( const Cost &other ) const;53 friend std::ostream &operator<<( std::ostream &os, const Cost &cost );54 // returns negative for *this < other, 0 for *this == other, positive for *this > other55 int compare( const Cost &other ) const;56 57 static const Cost zero;58 static const Cost infinity;59 60 static const Cost unsafe;61 static const Cost poly;62 static const Cost safe;63 static const Cost sign;64 static const Cost var;65 static const Cost spec;66 static const Cost reference;67 68 private:69 int unsafeCost; ///< Unsafe (narrowing) conversions70 int polyCost; ///< Count of parameters and return values bound to some poly type71 int safeCost; ///< Safe (widening) conversions72 int signCost; ///< Count of safe sign conversions73 int varCost; ///< Count of polymorphic type variables74 int specCost; ///< Polymorphic type specializations (type assertions), negative cost75 int referenceCost; ///< reference conversions76 };77 78 inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int signCost,79 int varCost, int specCost, int referenceCost )80 : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), signCost( signCost ),81 varCost( varCost ), specCost( specCost ), referenceCost( referenceCost ) {}82 83 inline Cost & Cost::incUnsafe( int inc ) {84 if ( *this == infinity ) return *this;85 unsafeCost += inc;86 return *this;87 }88 89 inline Cost & Cost::incPoly( int inc ) {90 if ( *this == infinity ) return *this;91 polyCost += inc;92 return *this;93 }94 95 inline Cost & Cost::incSafe( int inc ) {96 if ( *this == infinity ) return *this;97 safeCost += inc;98 return *this;99 }100 101 inline Cost & Cost::incSign( int inc ) {102 if ( *this == infinity ) return *this;103 signCost += inc;104 return *this;105 }106 107 inline Cost & Cost::incVar( int inc ) {108 if ( *this == infinity ) return *this;109 varCost += inc;110 return *this;111 }112 113 inline Cost& Cost::decSpec( int dec ) {114 if ( *this == infinity ) return *this;115 specCost -= dec;116 return *this;117 }118 119 inline Cost & Cost::incReference( int inc ) {120 if ( *this == infinity ) return *this;121 referenceCost += inc;122 return *this;123 }124 125 inline Cost Cost::operator+( const Cost &other ) const {126 if ( *this == infinity || other == infinity ) return infinity;127 return Cost{128 unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost,129 signCost + other.signCost, varCost + other.varCost, specCost + other.specCost,130 referenceCost + other.referenceCost };131 }132 133 inline Cost &Cost::operator+=( const Cost &other ) {134 if ( *this == infinity ) return *this;135 if ( other == infinity ) {136 *this = infinity;137 return *this;138 }139 unsafeCost += other.unsafeCost;140 polyCost += other.polyCost;141 safeCost += other.safeCost;142 signCost += other.signCost;143 varCost += other.varCost;144 specCost += other.specCost;145 referenceCost += other.referenceCost;146 return *this;147 }148 149 inline bool Cost::operator<( const Cost &other ) const {150 if ( *this == infinity ) return false;151 if ( other == infinity ) return true;152 153 if ( unsafeCost > other.unsafeCost ) {154 return false;155 } else if ( unsafeCost < other.unsafeCost ) {156 return true;157 } else if ( polyCost > other.polyCost ) {158 return false;159 } else if ( polyCost < other.polyCost ) {160 return true;161 } else if ( safeCost > other.safeCost ) {162 return false;163 } else if ( safeCost < other.safeCost ) {164 return true;165 } else if ( signCost > other.signCost ) {166 return false;167 } else if ( signCost < other.signCost ) {168 return true;169 } else if ( varCost > other.varCost ) {170 return false;171 } else if ( varCost < other.varCost ) {172 return true;173 } else if ( specCost > other.specCost ) {174 return false;175 } else if ( specCost > other.specCost ) {176 return true;177 } else if ( referenceCost > other.referenceCost ) {178 return false;179 } else if ( referenceCost < other.referenceCost ) {180 return true;181 } else {182 return false;183 } // if184 }185 186 inline int Cost::compare( const Cost &other ) const {187 if ( *this == infinity ) return +1;188 if ( other == infinity ) return -1;189 190 int c = unsafeCost - other.unsafeCost; if ( c ) return c;191 c = polyCost - other.polyCost; if ( c ) return c;192 c = safeCost - other.safeCost; if ( c ) return c;193 c = signCost - other.signCost; if ( c ) return c;194 c = varCost - other.varCost; if ( c ) return c;195 c = specCost - other.specCost; if ( c ) return c;196 return referenceCost - other.referenceCost;197 }198 199 inline bool Cost::operator==( const Cost &other ) const {200 return unsafeCost == other.unsafeCost201 && polyCost == other.polyCost202 && safeCost == other.safeCost203 && signCost == other.signCost204 && varCost == other.varCost205 && specCost == other.specCost206 && referenceCost == other.referenceCost;207 }208 209 inline bool Cost::operator!=( const Cost &other ) const {210 return !( *this == other );211 }212 213 inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) {214 return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", "215 << cost.safeCost << ", " << cost.signCost << ", "216 << cost.varCost << ", " << cost.specCost << ", "217 << cost.referenceCost << " )";218 }219 220 #else221 222 //*************************** NEW ***************************223 224 23 // To maximize performance and space, the 7 resolution costs are packed into a single 64-bit word. However, the 225 24 // specialization cost is a negative value so a correction is needed is a few places. … … 371 170 << ", " << cost.get_referenceCost() << " )"; 372 171 } 373 #endif // 0374 172 } // namespace ResolvExpr 375 173 -
src/ResolvExpr/RenameVars.cc
r3c6e417 r54dd994 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:05:18 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : T ue Apr 30 17:07:57201913 // Update Count : 711 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Jun 20 17:39:00 2019 13 // Update Count : 8 14 14 // 15 15 … … 19 19 #include <utility> // for pair 20 20 21 #include "AST/Pass.hpp" 22 #include "AST/Type.hpp" 21 23 #include "Common/PassVisitor.h" 24 #include "Common/ScopedMap.h" 22 25 #include "Common/SemanticError.h" // for SemanticError 23 26 #include "RenameVars.h" … … 28 31 29 32 namespace ResolvExpr { 30 namespace {31 struct RenameVars {32 RenameVars();33 void reset();34 33 35 void previsit( TypeInstType * instType ); 36 void previsit( Type * ); 37 void postvisit( Type * ); 34 namespace { 35 class RenamingData { 36 int level = 0; 37 int resetCount = 0; 38 ScopedMap< std::string, std::string > nameMap; 38 39 39 private: 40 int level, resetCount; 41 std::list< std::unordered_map< std::string, std::string > > mapStack; 42 }; 43 44 PassVisitor<RenameVars> global_renamer; 45 } // namespace 46 47 void renameTyVars( Type * t ) { 48 t->accept( global_renamer ); 49 } 50 51 void resetTyVarRenaming() { 52 global_renamer.pass.reset(); 53 } 54 55 namespace { 56 RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) { 57 mapStack.push_front( std::unordered_map< std::string, std::string >() ); 40 public: 41 void reset() { 42 level = 0; 43 ++resetCount; 58 44 } 59 45 60 void RenameVars::reset() { 61 level = 0; 62 resetCount++; 46 using mapConstIterator = ScopedMap< std::string, std::string >::const_iterator; 47 48 void rename( TypeInstType * type ) { 49 mapConstIterator it = nameMap.find( type->name ); 50 if ( it != nameMap.end() ) { 51 type->name = it->second; 52 } 63 53 } 64 54 65 void RenameVars::previsit( TypeInstType * instType ) { 66 previsit( (Type *)instType ); 67 std::unordered_map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->name ); 68 if ( i != mapStack.front().end() ) { 69 instType->name = i->second; 70 } // if 71 } 72 73 void RenameVars::previsit( Type * type ) { 55 void openLevel( Type * type ) { 74 56 if ( ! type->forall.empty() ) { 75 // copies current name mapping into new mapping 76 mapStack.push_front( mapStack.front() ); 57 nameMap.beginScope(); 77 58 // renames all "forall" type names to `_${level}_${name}' 78 59 for ( auto td : type->forall ) { … … 80 61 output << "_" << resetCount << "_" << level << "_" << td->name; 81 62 std::string newname( output.str() ); 82 mapStack.front()[ td->get_name() ] = newname;63 nameMap[ td->get_name() ] = newname; 83 64 td->name = newname; 84 65 // ditto for assertion names, the next level in … … 89 70 } 90 71 91 void RenameVars::postvisit( Type * type ) { 92 // clears name mapping added by typeBefore() 93 if ( ! type->forall.empty() ) { 94 mapStack.pop_front(); 95 } // if 72 void closeLevel( Type * type ) { 73 if ( !type->forall.empty() ) { 74 nameMap.endScope(); 75 } 96 76 } 97 } // namespace98 77 99 const ast::Type * renameTyVars( const ast::Type * t ) { 100 #warning unimplemented; make sure resetTyVarRenaming() updated when implemented 101 (void)t; 102 assert(false); 103 return t; 104 } 78 const ast::TypeInstType * rename( const ast::TypeInstType * type ) { 79 mapConstIterator it = nameMap.find( type->name ); 80 if ( it != nameMap.end() ) { 81 ast::TypeInstType * mutType = ast::mutate( type ); 82 mutType->name = it->second; 83 type = mutType; 84 } 85 return type; 86 } 87 88 template<typename NodeT> 89 const NodeT * openLevel( const NodeT * type ) { 90 if ( !type->forall.empty() ) { 91 nameMap.beginScope(); 92 // Load new names from this forall clause and perform renaming. 93 NodeT * mutType = ast::mutate( type ); 94 for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) { 95 std::ostringstream output; 96 output << "_" << resetCount << "_" << level << "_" << td->name; 97 std::string newname( output.str() ); 98 nameMap[ td->name ] = newname; 99 ++level; 100 101 ast::TypeDecl * decl = ast::mutate( td.get() ); 102 decl->name = newname; 103 td = decl; 104 } 105 } 106 return type; 107 } 108 109 template<typename NodeT> 110 const NodeT * closeLevel( const NodeT * type ) { 111 if ( !type->forall.empty() ) { 112 nameMap.endScope(); 113 } 114 return type; 115 } 116 }; 117 118 // Global State: 119 RenamingData renaming; 120 121 struct RenameVars { 122 void previsit( TypeInstType * instType ) { 123 renaming.openLevel( (Type*)instType ); 124 renaming.rename( instType ); 125 } 126 void previsit( Type * type ) { 127 renaming.openLevel( type ); 128 } 129 void postvisit( Type * type ) { 130 renaming.closeLevel( type ); 131 } 132 133 const ast::FunctionType * previsit( const ast::FunctionType * type ) { 134 return renaming.openLevel( type ); 135 } 136 const ast::StructInstType * previsit( const ast::StructInstType * type ) { 137 return renaming.openLevel( type ); 138 } 139 const ast::UnionInstType * previsit( const ast::UnionInstType * type ) { 140 return renaming.openLevel( type ); 141 } 142 const ast::TraitInstType * previsit( const ast::TraitInstType * type ) { 143 return renaming.openLevel( type ); 144 } 145 const ast::TypeInstType * previsit( const ast::TypeInstType * type ) { 146 return renaming.rename( renaming.openLevel( type ) ); 147 } 148 const ast::ParameterizedType * postvisit( const ast::ParameterizedType * type ) { 149 return renaming.closeLevel( type ); 150 } 151 }; 152 153 } // namespace 154 155 void renameTyVars( Type * t ) { 156 PassVisitor<RenameVars> renamer; 157 t->accept( renamer ); 158 } 159 160 const ast::Type * renameTyVars( const ast::Type * t ) { 161 ast::Pass<RenameVars> renamer; 162 return t->accept( renamer ); 163 } 164 165 void resetTyVarRenaming() { 166 renaming.reset(); 167 } 168 105 169 } // namespace ResolvExpr 106 170 -
src/ResolvExpr/Resolver.cc
r3c6e417 r54dd994 1109 1109 1110 1110 // set up and resolve expression cast to void 1111 ast::CastExpr * untyped = new ast::CastExpr{ expr ->location, expr};1111 ast::CastExpr * untyped = new ast::CastExpr{ expr }; 1112 1112 CandidateRef choice = findUnfinishedKindExpression( 1113 1113 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() ); … … 1161 1161 ) { 1162 1162 assert( untyped && type ); 1163 ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped ->location, untyped, type };1163 ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type }; 1164 1164 ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab ); 1165 1165 removeExtraneousCast( newExpr, symtab ); … … 1251 1251 ast::Pass< Resolver_new > resolver; 1252 1252 accept_all( translationUnit, resolver ); 1253 } 1254 1255 ast::ptr< ast::Init > resolveCtorInit( 1256 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 1257 ) { 1258 assert( ctorInit ); 1259 ast::Pass< Resolver_new > resolver{ symtab }; 1260 return ctorInit->accept( resolver ); 1253 1261 } 1254 1262 -
src/ResolvExpr/Resolver.h
r3c6e417 r54dd994 29 29 30 30 namespace ast { 31 class ConstructorInit; 31 32 class Decl; 32 33 class DeletedExpr; 34 class Init; 33 35 class StmtExpr; 34 36 class SymbolTable; … … 59 61 ast::ptr< ast::Expr > resolveInVoidContext( 60 62 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env ); 63 /// Resolves a constructor init expression 64 ast::ptr< ast::Init > resolveCtorInit( 65 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab ); 61 66 /// Resolves a statement expression 62 67 ast::ptr< ast::Expr > resolveStmtExpr(
Note:
See TracChangeset
for help on using the changeset viewer.