- Timestamp:
- Jul 31, 2019, 3:23:04 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- ae265b55, f49b3fc
- Parents:
- 504eb72
- Location:
- src/AST
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Expr.cpp
r504eb72 r2890212 20 20 #include <vector> 21 21 22 #include "Copy.hpp" // for shallowCopy 22 23 #include "Eval.hpp" // for call 23 24 #include "GenericSubstitution.hpp" … … 174 175 assert( var ); 175 176 assert( var->get_type() ); 176 result = var->get_type(); 177 add_qualifiers( result, CV::Lvalue ); 177 auto r = shallowCopy( var->get_type() ); 178 r->qualifiers |= CV::Lvalue; 179 result = r; 178 180 } 179 181 -
src/AST/Node.hpp
r504eb72 r2890212 96 96 assertf( 97 97 node->weak_count == 0, 98 "Error: mutating node with weak references to it will invalid edsome references"98 "Error: mutating node with weak references to it will invalidate some references" 99 99 ); 100 100 return node->clone(); … … 106 106 // skip mutate if equivalent 107 107 if ( node->*field == val ) return node; 108 108 109 109 // mutate and return 110 110 node_t * ret = mutate( node ); -
src/AST/TypeEnvironment.hpp
r504eb72 r2890212 38 38 /// Adding this comparison operator significantly improves assertion satisfaction run time for 39 39 /// some cases. The current satisfaction algorithm's speed partially depends on the order of 40 /// assertions. Assertions which have fewer possible matches should appear before assertions 41 /// which have more possible matches. This seems to imply that this could be further improved 42 /// by providing an indexer as an additional argument and ordering based on the number of 40 /// assertions. Assertions which have fewer possible matches should appear before assertions 41 /// which have more possible matches. This seems to imply that this could be further improved 42 /// by providing an indexer as an additional argument and ordering based on the number of 43 43 /// matches of the same kind (object, function) for the names of the declarations. 44 44 /// 45 /// I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this 45 /// I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this 46 46 /// comparator. 47 47 /// 48 /// Note: since this compares pointers for position, minor changes in the source file that 49 /// affect memory layout can alter compilation time in unpredictable ways. For example, the 50 /// placement of a line directive can reorder type pointers with respect to each other so that 51 /// assertions are seen in different orders, causing a potentially different number of 52 /// unification calls when resolving assertions. I've seen a TU go from 36 seconds to 27 53 /// seconds by reordering line directives alone, so it would be nice to fix this comparison so 54 /// that assertions compare more consistently. I've tried to modify this to compare on mangle 55 /// name instead of type as the second comparator, but this causes some assertions to never be 48 /// Note: since this compares pointers for position, minor changes in the source file that 49 /// affect memory layout can alter compilation time in unpredictable ways. For example, the 50 /// placement of a line directive can reorder type pointers with respect to each other so that 51 /// assertions are seen in different orders, causing a potentially different number of 52 /// unification calls when resolving assertions. I've seen a TU go from 36 seconds to 27 53 /// seconds by reordering line directives alone, so it would be nice to fix this comparison so 54 /// that assertions compare more consistently. I've tried to modify this to compare on mangle 55 /// name instead of type as the second comparator, but this causes some assertions to never be 56 56 /// recorded. More investigation is needed. 57 57 struct AssertCompare { … … 87 87 void print( std::ostream &, const OpenVarSet &, Indenter indent = {} ); 88 88 89 /// Represents an equivalence class of bound type variables, optionally with the concrete type 89 /// Represents an equivalence class of bound type variables, optionally with the concrete type 90 90 /// they bind to. 91 91 struct EqvClass { … … 96 96 97 97 EqvClass() : vars(), bound(), allowWidening( true ), data() {} 98 98 99 99 /// Copy-with-bound constructor 100 EqvClass( const EqvClass & o, const Type * b ) 100 EqvClass( const EqvClass & o, const Type * b ) 101 101 : vars( o.vars ), bound( b ), allowWidening( o.allowWidening ), data( o.data ) {} 102 102 … … 143 143 void writeToSubstitution( TypeSubstitution & sub ) const; 144 144 145 template< typename node_t , enum Node::ref_type ref_t>146 int apply( ptr_base< node_t, ref_t >& type ) const {145 template< typename node_t > 146 auto apply( node_t && type ) const { 147 147 TypeSubstitution sub; 148 148 writeToSubstitution( sub ); 149 return sub.apply( type);150 } 151 152 template< typename node_t , enum Node::ref_type ref_t>153 int applyFree( ptr_base< node_t, ref_t >& type ) const {149 return sub.apply( std::forward<node_t>(type) ); 150 } 151 152 template< typename node_t > 153 auto applyFree( node_t && type ) const { 154 154 TypeSubstitution sub; 155 155 writeToSubstitution( sub ); 156 return sub.applyFree( type);156 return sub.applyFree( std::forward<node_t>(type) ); 157 157 } 158 158 … … 173 173 void addActual( const TypeEnvironment & actualEnv, OpenVarSet & openVars ); 174 174 175 /// Binds the type class represented by `typeInst` to the type `bindTo`; will add the class if 175 /// Binds the type class represented by `typeInst` to the type `bindTo`; will add the class if 176 176 /// needed. Returns false on failure. 177 bool bindVar( 178 const TypeInstType * typeInst, const Type * bindTo, const TypeDecl::Data & data, 179 AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 177 bool bindVar( 178 const TypeInstType * typeInst, const Type * bindTo, const TypeDecl::Data & data, 179 AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 180 180 ResolvExpr::WidenMode widen, const SymbolTable & symtab ); 181 182 /// Binds the type classes represented by `var1` and `var2` together; will add one or both 181 182 /// Binds the type classes represented by `var1` and `var2` together; will add one or both 183 183 /// classes if needed. Returns false on failure. 184 bool bindVarToVar( 185 const TypeInstType * var1, const TypeInstType * var2, TypeDecl::Data && data, 186 AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 184 bool bindVarToVar( 185 const TypeInstType * var1, const TypeInstType * var2, TypeDecl::Data && data, 186 AssertionSet & need, AssertionSet & have, const OpenVarSet & openVars, 187 187 ResolvExpr::WidenMode widen, const SymbolTable & symtab ); 188 188 … … 199 199 200 200 /// Unifies the type bound of `to` with the type bound of `from`, returning false if fails 201 bool mergeBound( 201 bool mergeBound( 202 202 EqvClass & to, const EqvClass & from, OpenVarSet & openVars, const SymbolTable & symtab ); 203 203 204 204 /// Merges two type classes from local environment, returning false if fails 205 bool mergeClasses( 206 ClassList::iterator to, ClassList::iterator from, OpenVarSet & openVars, 205 bool mergeClasses( 206 ClassList::iterator to, ClassList::iterator from, OpenVarSet & openVars, 207 207 const SymbolTable & symtab ); 208 208 -
src/AST/TypeSubstitution.cpp
r504eb72 r2890212 146 146 ptr<Type> newType = i->second; // force clone if needed 147 147 add_qualifiers( newType, inst->qualifiers ); 148 // Note: need to recursively apply substitution to the new type because normalize does not 148 // Note: need to recursively apply substitution to the new type because normalize does not 149 149 // substitute bound vars, but bound vars must be substituted when not in freeOnly mode. 150 150 newType = newType->accept( *visitor ); … … 159 159 } else { 160 160 subCount++; 161 delete nameExpr;162 161 return i->second; 163 162 } // if -
src/AST/TypeSubstitution.hpp
r504eb72 r2890212 44 44 TypeSubstitution &operator=( const TypeSubstitution &other ); 45 45 46 template< typename SynTreeClass > int apply( const SynTreeClass *& input ) const; 47 template< typename SynTreeClass > int applyFree( const SynTreeClass *& input ) const; 46 template< typename SynTreeClass > 47 struct ApplyResult { 48 const SynTreeClass * node; 49 int count; 50 }; 51 52 template< typename SynTreeClass > ApplyResult<SynTreeClass> apply( const SynTreeClass * input ) const; 53 template< typename SynTreeClass > ApplyResult<SynTreeClass> applyFree( const SynTreeClass * input ) const; 48 54 49 55 template< typename node_t, enum Node::ref_type ref_t > 50 56 int apply( ptr_base< node_t, ref_t > & input ) const { 51 57 const node_t * p = input.get(); 52 intret = apply(p);53 input = p;54 return ret ;58 auto ret = apply(p); 59 input = ret.node; 60 return ret.count; 55 61 } 56 62 … … 58 64 int applyFree( ptr_base< node_t, ref_t > & input ) const { 59 65 const node_t * p = input.get(); 60 intret = applyFree(p);61 input = p;62 return ret ;66 auto ret = applyFree(p); 67 input = ret.node; 68 return ret.count; 63 69 } 64 70 … … 175 181 176 182 template< typename SynTreeClass > 177 int TypeSubstitution::apply( const SynTreeClass *&input ) const {183 TypeSubstitution::ApplyResult<SynTreeClass> TypeSubstitution::apply( const SynTreeClass * input ) const { 178 184 assert( input ); 179 185 Pass<Substituter> sub( *this, false ); 180 186 input = strict_dynamic_cast< const SynTreeClass * >( input->accept( sub ) ); 181 /// std::cerr << "substitution result is: "; 182 /// newType->print( std::cerr ); 183 /// std::cerr << std::endl; 184 return sub.pass.subCount; 187 return { input, sub.pass.subCount }; 185 188 } 186 189 187 190 template< typename SynTreeClass > 188 int TypeSubstitution::applyFree( const SynTreeClass *&input ) const {191 TypeSubstitution::ApplyResult<SynTreeClass> TypeSubstitution::applyFree( const SynTreeClass * input ) const { 189 192 assert( input ); 190 193 Pass<Substituter> sub( *this, true ); 191 194 input = strict_dynamic_cast< const SynTreeClass * >( input->accept( sub ) ); 192 /// std::cerr << "substitution result is: "; 193 /// newType->print( std::cerr ); 194 /// std::cerr << std::endl; 195 return sub.pass.subCount; 195 return { input, sub.pass.subCount }; 196 196 } 197 197
Note: See TracChangeset
for help on using the changeset viewer.