Changes in / [83b52f1:96ac72c0]
- Files:
-
- 6 added
- 1 deleted
- 35 edited
-
Jenkinsfile (deleted)
-
Jenkinsfile_disabled (added)
-
src/AST/Attribute.hpp (modified) (1 diff)
-
src/AST/Convert.cpp (modified) (1 diff)
-
src/AST/Copy.hpp (added)
-
src/AST/Decl.cpp (modified) (1 diff)
-
src/AST/Decl.hpp (modified) (6 diffs)
-
src/AST/Eval.hpp (added)
-
src/AST/Expr.cpp (modified) (3 diffs)
-
src/AST/Expr.hpp (modified) (1 diff)
-
src/AST/ForallSubstitutionTable.cpp (added)
-
src/AST/ForallSubstitutionTable.hpp (added)
-
src/AST/ForallSubstitutor.hpp (added)
-
src/AST/Init.hpp (modified) (1 diff)
-
src/AST/Node.cpp (modified) (2 diffs)
-
src/AST/Node.hpp (modified) (7 diffs)
-
src/AST/Pass.hpp (modified) (6 diffs)
-
src/AST/Pass.impl.hpp (modified) (12 diffs)
-
src/AST/Pass.proto.hpp (modified) (3 diffs)
-
src/AST/Stmt.hpp (modified) (1 diff)
-
src/AST/Type.cpp (modified) (8 diffs)
-
src/AST/Type.hpp (modified) (12 diffs)
-
src/AST/TypeSubstitution.cpp (modified) (6 diffs)
-
src/AST/TypeSubstitution.hpp (modified) (1 diff)
-
src/AST/module.mk (modified) (1 diff)
-
src/Common/ScopedMap.h (modified) (1 diff)
-
src/Makefile.in (modified) (4 diffs)
-
src/ResolvExpr/AdjustExprType.cc (modified) (1 diff)
-
src/ResolvExpr/CandidateFinder.cpp (modified) (8 diffs)
-
src/ResolvExpr/CandidateFinder.hpp (modified) (1 diff)
-
src/ResolvExpr/CommonType.cc (modified) (1 diff)
-
src/ResolvExpr/ConversionCost.cc (modified) (3 diffs)
-
src/ResolvExpr/PolyCost.cc (modified) (1 diff)
-
src/ResolvExpr/RenameVars.cc (modified) (11 diffs)
-
src/ResolvExpr/ResolveTypeof.cc (modified) (1 diff)
-
src/ResolvExpr/Resolver.cc (modified) (4 diffs)
-
src/ResolvExpr/SpecCost.cc (modified) (3 diffs)
-
src/SymTab/Autogen.h (modified) (5 diffs)
-
src/Tuples/Explode.cc (modified) (1 diff)
-
src/Tuples/Explode.h (modified) (2 diffs)
-
src/Tuples/TupleAssignment.cc (modified) (6 diffs)
-
src/main.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Attribute.hpp
r83b52f1 r96ac72c0 51 51 template<typename node_t> 52 52 friend node_t * mutate(const node_t * node); 53 template<typename node_t> 54 friend node_t * shallowCopy(const node_t * node); 53 55 }; 54 56 -
src/AST/Convert.cpp
r83b52f1 r96ac72c0 608 608 609 609 tgt->result = get<Type>().accept1(src->result); 610 // Unconditionally use a clone of the result type. 611 // We know this will leak some objects: much of the immediate conversion result. 612 // In some cases, using the conversion result directly gives unintended object sharing. 613 // A parameter (ObjectDecl, a child of a FunctionType) is shared by the weak-ref cache. 614 // But tgt->result must be fully owned privately by tgt. 615 // Applying these conservative copies here means 616 // - weak references point at the declaration's copy, not these expr.result copies (good) 617 // - we copy more objects than really needed (bad, tolerated) 618 if (tgt->result) { 619 tgt->result = tgt->result->clone(); 620 } 610 621 return visitBaseExpr_skipResultType(src, tgt); 611 622 } -
src/AST/Decl.cpp
r83b52f1 r96ac72c0 52 52 53 53 const Type * FunctionDecl::get_type() const { return type.get(); } 54 void FunctionDecl::set_type(Type * t) { type = strict_dynamic_cast< FunctionType* >( t ); } 54 void FunctionDecl::set_type( const Type * t ) { 55 type = strict_dynamic_cast< const FunctionType * >( t ); 56 } 55 57 56 58 // --- TypeDecl -
src/AST/Decl.hpp
r83b52f1 r96ac72c0 32 32 33 33 // Must be included in *all* AST classes; should be #undef'd at the end of the file 34 #define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node); 34 #define MUTATE_FRIEND \ 35 template<typename node_t> friend node_t * mutate(const node_t * node); \ 36 template<typename node_t> friend node_t * shallowCopy(const node_t * node); 35 37 36 38 namespace ast { … … 87 89 virtual const Type * get_type() const = 0; 88 90 /// Set type of this declaration. May be verified by subclass 89 virtual void set_type( Type *) = 0;91 virtual void set_type( const Type * ) = 0; 90 92 91 93 const DeclWithType * accept( Visitor & v ) const override = 0; … … 110 112 111 113 const Type* get_type() const override { return type; } 112 void set_type( Type * ty ) override { type = ty; }114 void set_type( const Type * ty ) override { type = ty; } 113 115 114 116 const DeclWithType * accept( Visitor& v ) const override { return v.visit( this ); } … … 132 134 133 135 const Type * get_type() const override; 134 void set_type( Type * t) override;136 void set_type( const Type * t ) override; 135 137 136 138 bool has_body() const { return stmts; } … … 149 151 std::vector<ptr<DeclWithType>> assertions; 150 152 151 NamedTypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, 152 Type* b, Linkage::Spec spec = Linkage::Cforall ) 153 NamedTypeDecl( 154 const CodeLocation & loc, const std::string & name, Storage::Classes storage, 155 const Type * b, Linkage::Spec spec = Linkage::Cforall ) 153 156 : Decl( loc, name, storage, spec ), base( b ), params(), assertions() {} 154 157 … … 185 188 }; 186 189 187 TypeDecl( const CodeLocation& loc, const std::string& name, Storage::Classes storage, Type* b, 188 TypeVar::Kind k, bool s, Type* i = nullptr ) 190 TypeDecl( 191 const CodeLocation & loc, const std::string & name, Storage::Classes storage, 192 const Type * b, TypeVar::Kind k, bool s, const Type * i = nullptr ) 189 193 : NamedTypeDecl( loc, name, storage, b ), kind( k ), sized( k == TypeVar::Ttype || s ), 190 194 init( i ) {} -
src/AST/Expr.cpp
r83b52f1 r96ac72c0 20 20 #include <vector> 21 21 22 #include "Eval.hpp" // for call 22 23 #include "GenericSubstitution.hpp" 23 24 #include "Stmt.hpp" … … 51 52 assert( arg ); 52 53 53 UntypedExpr * ret = new UntypedExpr{ 54 loc, new NameExpr{loc, "*?"}, std::vector<ptr<Expr>>{ ptr<Expr>{ arg } } 55 }; 54 UntypedExpr * ret = call( loc, "*?", arg ); 56 55 if ( const Type * ty = arg->result ) { 57 56 const Type * base = InitTweak::getPointerBase( ty ); … … 74 73 assert( lhs && rhs ); 75 74 76 UntypedExpr * ret = new UntypedExpr{ 77 loc, new NameExpr{loc, "?=?"}, std::vector<ptr<Expr>>{ ptr<Expr>{ lhs }, ptr<Expr>{ rhs } } 78 }; 75 UntypedExpr * ret = call( loc, "?=?", lhs, rhs ); 79 76 if ( lhs->result && rhs->result ) { 80 77 // if both expressions are typed, assumes that this assignment is a C bitwise assignment, -
src/AST/Expr.hpp
r83b52f1 r96ac72c0 30 30 31 31 // Must be included in *all* AST classes; should be #undef'd at the end of the file 32 #define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node); 32 #define MUTATE_FRIEND \ 33 template<typename node_t> friend node_t * mutate(const node_t * node); \ 34 template<typename node_t> friend node_t * shallowCopy(const node_t * node); 35 33 36 34 37 class ConverterOldToNew; -
src/AST/Init.hpp
r83b52f1 r96ac72c0 25 25 26 26 // Must be included in *all* AST classes; should be #undef'd at the end of the file 27 #define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node); 27 #define MUTATE_FRIEND \ 28 template<typename node_t> friend node_t * mutate(const node_t * node); \ 29 template<typename node_t> friend node_t * shallowCopy(const node_t * node); 28 30 29 31 namespace ast { -
src/AST/Node.cpp
r83b52f1 r96ac72c0 17 17 #include "Fwd.hpp" 18 18 19 #include <csignal> // MEMORY DEBUG -- for raise 19 20 #include <iostream> 20 21 … … 29 30 #include "Print.hpp" 30 31 31 template< typename node_t, enum ast::Node::ref_type ref_t > 32 void ast::ptr_base<node_t, ref_t>::_inc( const node_t * node ) { node->increment(ref_t); } 33 34 template< typename node_t, enum ast::Node::ref_type ref_t > 35 void ast::ptr_base<node_t, ref_t>::_dec( const node_t * node ) { node->decrement(ref_t); } 36 37 template< typename node_t, enum ast::Node::ref_type ref_t > 38 void ast::ptr_base<node_t, ref_t>::_check() const { if(node) assert(node->was_ever_strong == false || node->strong_count > 0); } 32 /// MEMORY DEBUG -- allows breaking on ref-count changes of dynamically chosen object. 33 /// Process to use in GDB: 34 /// break ast::Node::_trap() 35 /// run 36 /// set variable MEM_TRAP_OBJ = <target> 37 /// disable <first breakpoint> 38 /// continue 39 void * MEM_TRAP_OBJ = nullptr; 40 41 void _trap( const void * node ) { 42 if ( node == MEM_TRAP_OBJ ) std::raise(SIGTRAP); 43 } 44 45 template< typename node_t, enum ast::Node::ref_type ref_t > 46 void ast::ptr_base<node_t, ref_t>::_inc( const node_t * node ) { 47 node->increment(ref_t); 48 _trap( node ); 49 } 50 51 template< typename node_t, enum ast::Node::ref_type ref_t > 52 void ast::ptr_base<node_t, ref_t>::_dec( const node_t * node, bool do_delete ) { 53 _trap( node ); 54 node->decrement(ref_t, do_delete ); 55 } 56 57 template< typename node_t, enum ast::Node::ref_type ref_t > 58 void ast::ptr_base<node_t, ref_t>::_check() const { 59 // if(node) assert(node->was_ever_strong == false || node->strong_count > 0); 60 } 39 61 40 62 template< typename node_t, enum ast::Node::ref_type ref_t > -
src/AST/Node.hpp
r83b52f1 r96ac72c0 38 38 Node& operator= (const Node&) = delete; 39 39 Node& operator= (Node&&) = delete; 40 virtual ~Node() = default;40 virtual ~Node() {} 41 41 42 42 virtual const Node * accept( Visitor & v ) const = 0; … … 57 57 template<typename node_t> 58 58 friend node_t * mutate(const node_t * node); 59 template<typename node_t> 60 friend node_t * shallowCopy(const node_t * node); 59 61 60 62 mutable size_t strong_count = 0; … … 69 71 } 70 72 71 void decrement(ast::Node::ref_type ref ) const {73 void decrement(ast::Node::ref_type ref, bool do_delete = true) const { 72 74 switch (ref) { 73 75 case ref_type::strong: strong_count--; break; … … 75 77 } 76 78 77 if( !strong_count && !weak_count) {79 if( do_delete && !strong_count && !weak_count) { 78 80 delete this; 79 81 } … … 123 125 (ret->*field)[i] = std::forward< field_t >( val ); 124 126 return ret; 127 } 128 129 /// Mutate an entire indexed collection by cloning to accepted value 130 template<typename node_t, typename parent_t, typename coll_t> 131 const node_t * mutate_each( const node_t * node, coll_t parent_t::* field, Visitor & v ) { 132 for ( unsigned i = 0; i < (node->*field).size(); ++i ) { 133 node = mutate_field_index( node, field, i, (node->*field)[i]->accept( v ) ); 134 } 135 return node; 125 136 } 126 137 … … 219 230 operator const node_t * () const { _check(); return node; } 220 231 232 const node_t * release() { 233 const node_t * ret = node; 234 if ( node ) { 235 _dec(node, false); 236 node = nullptr; 237 } 238 return ret; 239 } 240 221 241 /// wrapper for convenient access to dynamic_cast 222 242 template<typename o_node_t> … … 244 264 245 265 void _inc( const node_t * other ); 246 void _dec( const node_t * other );266 void _dec( const node_t * other, bool do_delete = true ); 247 267 void _check() const; 248 268 -
src/AST/Pass.hpp
r83b52f1 r96ac72c0 35 35 #include "AST/SymbolTable.hpp" 36 36 37 #include "AST/ForallSubstitutionTable.hpp" 38 37 39 // Private prelude header, needed for some of the magic tricks this class pulls off 38 40 #include "AST/Pass.proto.hpp" … … 46 48 // 47 49 // Several additional features are available through inheritance 48 // | WithTypeSubstitution - provides polymorphic const TypeSubstitution * env for the 49 // current expression 50 // | WithStmtsToAdd - provides the ability to insert statements before or after the current 51 // statement by adding new statements into stmtsToAddBefore or 52 // stmtsToAddAfter respectively. 53 // | WithDeclsToAdd - provides the ability to insert declarations before or after the current 54 // declarations by adding new DeclStmt into declsToAddBefore or 55 // declsToAddAfter respectively. 56 // | WithShortCircuiting - provides the ability to skip visiting child nodes; set visit_children 57 // to false in pre{visit,visit} to skip visiting children 58 // | WithGuards - provides the ability to save/restore data like a LIFO stack; to save, 59 // call GuardValue with the variable to save, the variable will 60 // automatically be restored to its previous value after the corresponding 61 // postvisit/postmutate teminates. 62 // | WithVisitorRef - provides an pointer to the templated visitor wrapper 63 // | WithSymbolTable - provides symbol table functionality 50 // | WithTypeSubstitution - provides polymorphic const TypeSubstitution * env for the 51 // current expression 52 // | WithStmtsToAdd - provides the ability to insert statements before or after the current 53 // statement by adding new statements into stmtsToAddBefore or 54 // stmtsToAddAfter respectively. 55 // | WithDeclsToAdd - provides the ability to insert declarations before or after the 56 // current declarations by adding new DeclStmt into declsToAddBefore or 57 // declsToAddAfter respectively. 58 // | WithShortCircuiting - provides the ability to skip visiting child nodes; set visit_children 59 // to false in pre{visit,visit} to skip visiting children 60 // | WithGuards - provides the ability to save/restore data like a LIFO stack; to save, 61 // call GuardValue with the variable to save, the variable will 62 // automatically be restored to its previous value after the 63 // corresponding postvisit/postmutate teminates. 64 // | WithVisitorRef - provides an pointer to the templated visitor wrapper 65 // | WithSymbolTable - provides symbol table functionality 66 // | WithForallSubstitutor - maintains links between TypeInstType and TypeDecl under mutation 64 67 //------------------------------------------------------------------------------------------------- 65 68 template< typename pass_t > … … 201 204 container_t< ptr<node_t> > call_accept( const container_t< ptr<node_t> > & container ); 202 205 206 /// Mutate forall-list, accounting for presence of type substitution map 207 template<typename node_t> 208 void mutate_forall( const node_t *& ); 209 203 210 public: 204 211 /// Logic to call the accept and mutate the parent if needed, delegates call to accept … … 209 216 /// Internal RAII guard for symbol table features 210 217 struct guard_symtab { 211 guard_symtab( Pass<pass_t> & pass ): pass( pass ) { __pass::symtab::enter(pass , 0); }212 ~guard_symtab() { __pass::symtab::leave(pass , 0); }218 guard_symtab( Pass<pass_t> & pass ): pass( pass ) { __pass::symtab::enter(pass.pass, 0); } 219 ~guard_symtab() { __pass::symtab::leave(pass.pass, 0); } 213 220 Pass<pass_t> & pass; 214 221 }; … … 216 223 /// Internal RAII guard for scope features 217 224 struct guard_scope { 218 guard_scope( Pass<pass_t> & pass ): pass( pass ) { __pass::scope::enter(pass , 0); }219 ~guard_scope() { __pass::scope::leave(pass , 0); }225 guard_scope( Pass<pass_t> & pass ): pass( pass ) { __pass::scope::enter(pass.pass, 0); } 226 ~guard_scope() { __pass::scope::leave(pass.pass, 0); } 220 227 Pass<pass_t> & pass; 228 }; 229 230 /// Internal RAII guard for forall substitutions 231 struct guard_forall_subs { 232 guard_forall_subs( Pass<pass_t> & pass, const ParameterizedType * type ) 233 : pass( pass ), type( type ) { __pass::forall::enter(pass.pass, 0, type ); } 234 ~guard_forall_subs() { __pass::forall::leave(pass.pass, 0, type ); } 235 Pass<pass_t> & pass; 236 const ParameterizedType * type; 221 237 }; 222 238 … … 313 329 SymbolTable symtab; 314 330 }; 331 332 /// Use when the templated visitor needs to keep TypeInstType instances properly linked to TypeDecl 333 struct WithForallSubstitutor { 334 ForallSubstitutionTable subs; 335 }; 336 315 337 } 316 338 -
src/AST/Pass.impl.hpp
r83b52f1 r96ac72c0 127 127 , decltype( node->accept(*this) ) 128 128 >::type 129 130 129 { 131 130 __pedantic_pass_assert( __visit_children() ); 132 __pedantic_pass_assert( expr);131 __pedantic_pass_assert( node ); 133 132 134 133 static_assert( !std::is_base_of<ast::Expr, node_t>::value, "ERROR"); … … 323 322 } 324 323 324 325 template< typename pass_t > 326 template< typename node_t > 327 void ast::Pass< pass_t >::mutate_forall( const node_t *& node ) { 328 if ( auto subs = __pass::forall::subs( pass, 0 ) ) { 329 // tracking TypeDecl substitution, full clone 330 if ( node->forall.empty() ) return; 331 332 node_t * mut = mutate( node ); 333 mut->forall = subs->clone( node->forall, *this ); 334 node = mut; 335 } else { 336 // not tracking TypeDecl substitution, just mutate 337 maybe_accept( node, &node_t::forall ); 338 } 339 } 325 340 } 326 341 … … 429 444 guard_symtab guard { *this }; 430 445 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 431 static ast:: ObjectDecl func(432 node->location, "__func__",433 new ast::ArrayType (434 new ast::BasicType ( ast::BasicType::Char, ast::CV::Qualifiers( ast::CV::Const ) ),446 static ast::ptr< ast::ObjectDecl > func{ new ast::ObjectDecl{ 447 CodeLocation{}, "__func__", 448 new ast::ArrayType{ 449 new ast::BasicType{ ast::BasicType::Char, ast::CV::Const }, 435 450 nullptr, VariableLen, DynamicDim 436 )437 );438 __pass::symtab::addId( pass, 0, &func );451 } 452 } }; 453 __pass::symtab::addId( pass, 0, func ); 439 454 VISIT( 440 455 maybe_accept( node, &FunctionDecl::type ); … … 610 625 VISIT({ 611 626 // do not enter a new scope if inFunction is true - needs to check old state before the assignment 612 auto guard1 = makeFuncGuard( [this, inFunction = this->inFunction]() {613 if ( ! inFunction ) __pass::symtab::enter(pass, 0);614 }, [this, inFunction = this->inFunction]() {615 if ( ! inFunction ) __pass::symtab::leave(pass, 0);627 auto guard1 = makeFuncGuard( [this, inFunctionCpy = this->inFunction]() { 628 if ( ! inFunctionCpy ) __pass::symtab::enter(pass, 0); 629 }, [this, inFunctionCpy = this->inFunction]() { 630 if ( ! inFunctionCpy ) __pass::symtab::leave(pass, 0); 616 631 }); 617 632 ValueGuard< bool > guard2( inFunction ); … … 1667 1682 VISIT_START( node ); 1668 1683 1669 VISIT( 1670 maybe_accept( node, &FunctionType::forall ); 1684 VISIT({ 1685 guard_forall_subs forall_guard { *this, node }; 1686 mutate_forall( node ); 1671 1687 maybe_accept( node, &FunctionType::returns ); 1672 1688 maybe_accept( node, &FunctionType::params ); 1673 )1689 }) 1674 1690 1675 1691 VISIT_END( Type, node ); … … 1686 1702 VISIT({ 1687 1703 guard_symtab guard { *this }; 1688 maybe_accept( node, &StructInstType::forall ); 1704 guard_forall_subs forall_guard { *this, node }; 1705 mutate_forall( node ); 1689 1706 maybe_accept( node, &StructInstType::params ); 1690 1707 }) … … 1699 1716 VISIT_START( node ); 1700 1717 1701 __pass::symtab::add Struct( pass, 0, node->name );1702 1703 {1718 __pass::symtab::addUnion( pass, 0, node->name ); 1719 1720 VISIT({ 1704 1721 guard_symtab guard { *this }; 1705 maybe_accept( node, &UnionInstType::forall ); 1722 guard_forall_subs forall_guard { *this, node }; 1723 mutate_forall( node ); 1706 1724 maybe_accept( node, &UnionInstType::params ); 1707 } 1725 }) 1708 1726 1709 1727 VISIT_END( Type, node ); … … 1716 1734 VISIT_START( node ); 1717 1735 1718 VISIT( 1719 maybe_accept( node, &EnumInstType::forall ); 1736 VISIT({ 1737 guard_forall_subs forall_guard { *this, node }; 1738 mutate_forall( node ); 1720 1739 maybe_accept( node, &EnumInstType::params ); 1721 )1740 }) 1722 1741 1723 1742 VISIT_END( Type, node ); … … 1730 1749 VISIT_START( node ); 1731 1750 1732 VISIT( 1733 maybe_accept( node, &TraitInstType::forall ); 1751 VISIT({ 1752 guard_forall_subs forall_guard { *this, node }; 1753 mutate_forall( node ); 1734 1754 maybe_accept( node, &TraitInstType::params ); 1735 )1755 }) 1736 1756 1737 1757 VISIT_END( Type, node ); … … 1745 1765 1746 1766 VISIT( 1747 maybe_accept( node, &TypeInstType::forall ); 1748 maybe_accept( node, &TypeInstType::params ); 1767 { 1768 guard_forall_subs forall_guard { *this, node }; 1769 mutate_forall( node ); 1770 maybe_accept( node, &TypeInstType::params ); 1771 } 1772 // ensure that base re-bound if doing substitution 1773 __pass::forall::replace( pass, 0, node ); 1749 1774 ) 1750 1775 … … 1895 1920 guard_symtab guard { *this }; 1896 1921 auto new_node = p.second->accept( *this ); 1897 if (new_node != p.second) mutated = false;1922 if (new_node != p.second) mutated = true; 1898 1923 new_map.insert({ p.first, new_node }); 1899 1924 } … … 1911 1936 guard_symtab guard { *this }; 1912 1937 auto new_node = p.second->accept( *this ); 1913 if (new_node != p.second) mutated = false;1938 if (new_node != p.second) mutated = true; 1914 1939 new_map.insert({ p.first, new_node }); 1915 1940 } -
src/AST/Pass.proto.hpp
r83b52f1 r96ac72c0 263 263 template<typename pass_t> 264 264 static inline void leave( pass_t &, long ) {} 265 } ;266 267 // Finally certain pass desire an up to date symbol table automatically265 } // namespace scope 266 267 // Certain passes desire an up to date symbol table automatically 268 268 // detect the presence of a member name `symtab` and call all the members appropriately 269 269 namespace symtab { 270 270 // Some simple scoping rules 271 271 template<typename pass_t> 272 static inline auto enter( pass_t & pass, int ) -> decltype( pass.symtab .enterScope(), void() ) {272 static inline auto enter( pass_t & pass, int ) -> decltype( pass.symtab, void() ) { 273 273 pass.symtab.enterScope(); 274 274 } … … 278 278 279 279 template<typename pass_t> 280 static inline auto leave( pass_t & pass, int ) -> decltype( pass.symtab .leaveScope(), void() ) {280 static inline auto leave( pass_t & pass, int ) -> decltype( pass.symtab, void() ) { 281 281 pass.symtab.leaveScope(); 282 282 } … … 356 356 #undef SYMTAB_FUNC1 357 357 #undef SYMTAB_FUNC2 358 }; 359 }; 360 }; 358 } // namespace symtab 359 360 // Some passes need to mutate TypeDecl and properly update their pointing TypeInstType. 361 // Detect the presence of a member name `subs` and call all members appropriately 362 namespace forall { 363 // Some simple scoping rules 364 template<typename pass_t> 365 static inline auto enter( pass_t & pass, int, const ast::ParameterizedType * type ) 366 -> decltype( pass.subs, void() ) { 367 if ( ! type->forall.empty() ) pass.subs.beginScope(); 368 } 369 370 template<typename pass_t> 371 static inline auto enter( pass_t &, long, const ast::ParameterizedType * ) {} 372 373 template<typename pass_t> 374 static inline auto leave( pass_t & pass, int, const ast::ParameterizedType * type ) 375 -> decltype( pass.subs, void() ) { 376 if ( ! type->forall.empty() ) { pass.subs.endScope(); } 377 } 378 379 template<typename pass_t> 380 static inline auto leave( pass_t &, long, const ast::ParameterizedType * ) {} 381 382 // Get the substitution table, if present 383 template<typename pass_t> 384 static inline auto subs( pass_t & pass, int ) -> decltype( &pass.subs ) { 385 return &pass.subs; 386 } 387 388 template<typename pass_t> 389 static inline ast::ForallSubstitutionTable * subs( pass_t &, long ) { return nullptr; } 390 391 // Replaces a TypeInstType's base TypeDecl according to the table 392 template<typename pass_t> 393 static inline auto replace( pass_t & pass, int, const ast::TypeInstType *& inst ) 394 -> decltype( pass.subs, void() ) { 395 inst = ast::mutate_field( 396 inst, &ast::TypeInstType::base, pass.subs.replace( inst->base ) ); 397 } 398 399 template<typename pass_t> 400 static inline auto replace( pass_t &, long, const ast::TypeInstType *& ) {} 401 402 } // namespace forall 403 } // namespace __pass 404 } // namespace ast -
src/AST/Stmt.hpp
r83b52f1 r96ac72c0 27 27 28 28 // Must be included in *all* AST classes; should be #undef'd at the end of the file 29 #define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node); 29 #define MUTATE_FRIEND \ 30 template<typename node_t> friend node_t * mutate(const node_t * node); \ 31 template<typename node_t> friend node_t * shallowCopy(const node_t * node); 30 32 31 33 namespace ast { -
src/AST/Type.cpp
r83b52f1 r96ac72c0 21 21 22 22 #include "Decl.hpp" 23 #include "ForallSubstitutor.hpp" // for substituteForall 23 24 #include "Init.hpp" 25 #include "Common/utility.h" // for copy, move 24 26 #include "InitTweak/InitTweak.h" // for getPointerBase 25 27 #include "Tuples/Tuples.h" // for isTtype … … 91 93 ); 92 94 95 // --- ParameterizedType 96 97 void ParameterizedType::initWithSub( 98 const ParameterizedType & o, Pass< ForallSubstitutor > & sub 99 ) { 100 forall = sub.pass( o.forall ); 101 } 102 93 103 // --- FunctionType 104 105 FunctionType::FunctionType( const FunctionType & o ) 106 : ParameterizedType( o.qualifiers, copy( o.attributes ) ), returns(), params(), 107 isVarArgs( o.isVarArgs ) { 108 Pass< ForallSubstitutor > sub; 109 initWithSub( o, sub ); // initialize substitution map 110 returns = sub.pass( o.returns ); // apply to return and parameter types 111 params = sub.pass( o.params ); 112 } 94 113 95 114 namespace { … … 107 126 108 127 // --- ReferenceToType 128 129 void ReferenceToType::initWithSub( const ReferenceToType & o, Pass< ForallSubstitutor > & sub ) { 130 ParameterizedType::initWithSub( o, sub ); // initialize substitution 131 params = sub.pass( o.params ); // apply to parameters 132 } 133 134 ReferenceToType::ReferenceToType( const ReferenceToType & o ) 135 : ParameterizedType( o.qualifiers, copy( o.attributes ) ), params(), name( o.name ), 136 hoistType( o.hoistType ) { 137 Pass< ForallSubstitutor > sub; 138 initWithSub( o, sub ); 139 } 140 109 141 std::vector<readonly<Decl>> ReferenceToType::lookup( const std::string& name ) const { 110 142 assertf( aggr(), "Must have aggregate to perform lookup" ); … … 119 151 // --- StructInstType 120 152 121 StructInstType::StructInstType( const StructDecl * b, CV::Qualifiers q,122 std::vector<ptr<Attribute>>&& as )123 : ReferenceToType( b->name, q, std::move(as) ), base( b ) {}153 StructInstType::StructInstType( 154 const StructDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as ) 155 : ReferenceToType( b->name, q, move(as) ), base( b ) {} 124 156 125 157 bool StructInstType::isComplete() const { return base ? base->body : false; } … … 127 159 // --- UnionInstType 128 160 129 UnionInstType::UnionInstType( const UnionDecl * b, CV::Qualifiers q,130 std::vector<ptr<Attribute>>&& as )131 : ReferenceToType( b->name, q, std::move(as) ), base( b ) {}161 UnionInstType::UnionInstType( 162 const UnionDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as ) 163 : ReferenceToType( b->name, q, move(as) ), base( b ) {} 132 164 133 165 bool UnionInstType::isComplete() const { return base ? base->body : false; } … … 135 167 // --- EnumInstType 136 168 137 EnumInstType::EnumInstType( const EnumDecl * b, CV::Qualifiers q,138 std::vector<ptr<Attribute>>&& as )139 : ReferenceToType( b->name, q, std::move(as) ), base( b ) {}169 EnumInstType::EnumInstType( 170 const EnumDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as ) 171 : ReferenceToType( b->name, q, move(as) ), base( b ) {} 140 172 141 173 bool EnumInstType::isComplete() const { return base ? base->body : false; } … … 143 175 // --- TraitInstType 144 176 145 TraitInstType::TraitInstType( const TraitDecl * b, CV::Qualifiers q,146 std::vector<ptr<Attribute>>&& as )147 : ReferenceToType( b->name, q, std::move(as) ), base( b ) {}177 TraitInstType::TraitInstType( 178 const TraitDecl * b, CV::Qualifiers q, std::vector<ptr<Attribute>>&& as ) 179 : ReferenceToType( b->name, q, move(as) ), base( b ) {} 148 180 149 181 // --- TypeInstType 182 183 TypeInstType::TypeInstType( const TypeInstType & o ) 184 : ReferenceToType( o.name, o.qualifiers, copy( o.attributes ) ), base(), kind( o.kind ) { 185 Pass< ForallSubstitutor > sub; 186 initWithSub( o, sub ); // initialize substitution 187 base = sub.pass( o.base ); // apply to base type 188 } 150 189 151 190 void TypeInstType::set_base( const TypeDecl * b ) { … … 159 198 160 199 TupleType::TupleType( std::vector<ptr<Type>> && ts, CV::Qualifiers q ) 161 : Type( q ), types( std::move(ts) ), members() {200 : Type( q ), types( move(ts) ), members() { 162 201 // This constructor is awkward. `TupleType` needs to contain objects so that members can be 163 202 // named, but members without initializer nodes end up getting constructors, which breaks -
src/AST/Type.hpp
r83b52f1 r96ac72c0 30 30 31 31 // Must be included in *all* AST classes; should be #undef'd at the end of the file 32 #define MUTATE_FRIEND template<typename node_t> friend node_t * mutate(const node_t * node); 32 #define MUTATE_FRIEND \ 33 template<typename node_t> friend node_t * mutate(const node_t * node); \ 34 template<typename node_t> friend node_t * shallowCopy(const node_t * node); 33 35 34 36 namespace ast { 37 38 template< typename T > class Pass; 39 40 struct ForallSubstitutor; 35 41 36 42 class Type : public Node { … … 164 170 static const char *typeNames[]; 165 171 166 BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 172 BasicType( Kind k, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 167 173 : Type(q, std::move(as)), kind(k) {} 168 174 … … 266 272 /// Base type for potentially forall-qualified types 267 273 class ParameterizedType : public Type { 274 protected: 275 /// initializes forall with substitutor 276 void initWithSub( const ParameterizedType & o, Pass< ForallSubstitutor > & sub ); 268 277 public: 269 278 using ForallList = std::vector<ptr<TypeDecl>>; … … 277 286 ParameterizedType( CV::Qualifiers q, std::vector<ptr<Attribute>> && as = {} ) 278 287 : Type(q, std::move(as)), forall() {} 288 289 // enforce use of ForallSubstitutor to copy parameterized type 290 ParameterizedType( const ParameterizedType & ) = delete; 291 292 ParameterizedType( ParameterizedType && ) = default; 293 294 // no need to change destructor, and operator= deleted in Node 279 295 280 296 private: … … 302 318 : ParameterizedType(q), returns(), params(), isVarArgs(va) {} 303 319 320 FunctionType( const FunctionType & o ); 321 304 322 /// true if either the parameters or return values contain a tttype 305 323 bool isTtype() const; … … 315 333 /// base class for types that refer to types declared elsewhere (aggregates and typedefs) 316 334 class ReferenceToType : public ParameterizedType { 335 protected: 336 /// Initializes forall and parameters based on substitutor 337 void initWithSub( const ReferenceToType & o, Pass< ForallSubstitutor > & sub ); 317 338 public: 318 339 std::vector<ptr<Expr>> params; … … 320 341 bool hoistType = false; 321 342 322 ReferenceToType( const std::string& n, CV::Qualifiers q = {},323 std::vector<ptr<Attribute>> && as = {} )343 ReferenceToType( 344 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 324 345 : ParameterizedType(q, std::move(as)), params(), name(n) {} 346 347 ReferenceToType( const ReferenceToType & o ); 325 348 326 349 /// Gets aggregate declaration this type refers to … … 339 362 readonly<StructDecl> base; 340 363 341 StructInstType( const std::string& n, CV::Qualifiers q = {},342 std::vector<ptr<Attribute>> && as = {} )364 StructInstType( 365 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 343 366 : ReferenceToType( n, q, std::move(as) ), base() {} 344 StructInstType( const StructDecl * b, CV::Qualifiers q = {}, 345 std::vector<ptr<Attribute>> && as = {} ); 367 368 StructInstType( 369 const StructDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 346 370 347 371 bool isComplete() const override; … … 360 384 readonly<UnionDecl> base; 361 385 362 UnionInstType( const std::string& n, CV::Qualifiers q = {},363 std::vector<ptr<Attribute>> && as = {} )386 UnionInstType( 387 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 364 388 : ReferenceToType( n, q, std::move(as) ), base() {} 365 UnionInstType( const UnionDecl * b, CV::Qualifiers q = {}, 366 std::vector<ptr<Attribute>> && as = {} ); 389 390 UnionInstType( 391 const UnionDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 367 392 368 393 bool isComplete() const override; … … 381 406 readonly<EnumDecl> base; 382 407 383 EnumInstType( const std::string& n, CV::Qualifiers q = {},384 std::vector<ptr<Attribute>> && as = {} )408 EnumInstType( 409 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 385 410 : ReferenceToType( n, q, std::move(as) ), base() {} 386 EnumInstType( const EnumDecl * b, CV::Qualifiers q = {}, 387 std::vector<ptr<Attribute>> && as = {} ); 411 412 EnumInstType( 413 const EnumDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 388 414 389 415 bool isComplete() const override; … … 402 428 readonly<TraitDecl> base; 403 429 404 TraitInstType( const std::string& n, CV::Qualifiers q = {},405 std::vector<ptr<Attribute>> && as = {} )430 TraitInstType( 431 const std::string& n, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 406 432 : ReferenceToType( n, q, std::move(as) ), base() {} 407 TraitInstType( const TraitDecl * b, CV::Qualifiers q = {}, 408 std::vector<ptr<Attribute>> && as = {} ); 433 434 TraitInstType( 435 const TraitDecl * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 409 436 410 437 // not meaningful for TraitInstType … … 425 452 TypeVar::Kind kind; 426 453 427 TypeInstType( const std::string& n, const TypeDecl * b, CV::Qualifiers q = {}, 454 TypeInstType( 455 const std::string& n, const TypeDecl * b, CV::Qualifiers q = {}, 428 456 std::vector<ptr<Attribute>> && as = {} ) 429 457 : ReferenceToType( n, q, std::move(as) ), base( b ), kind( b->kind ) {} 430 TypeInstType( const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {}, 458 459 TypeInstType( 460 const std::string& n, TypeVar::Kind k, CV::Qualifiers q = {}, 431 461 std::vector<ptr<Attribute>> && as = {} ) 432 462 : ReferenceToType( n, q, std::move(as) ), base(), kind( k ) {} 463 464 TypeInstType( const TypeInstType & o ); 433 465 434 466 /// sets `base`, updating `kind` correctly -
src/AST/TypeSubstitution.cpp
r83b52f1 r96ac72c0 92 92 namespace { 93 93 struct EnvTrimmer { 94 ptr<TypeSubstitution>env;94 const TypeSubstitution * env; 95 95 TypeSubstitution * newEnv; 96 96 EnvTrimmer( const TypeSubstitution * env, TypeSubstitution * newEnv ) : env( env ), newEnv( newEnv ){} … … 108 108 if ( env ) { 109 109 TypeSubstitution * newEnv = new TypeSubstitution(); 110 #if TIME_TO_CONVERT_PASSES111 110 Pass<EnvTrimmer> trimmer( env, newEnv ); 112 111 expr->accept( trimmer ); 113 #else114 (void)expr;115 (void)env;116 #endif117 112 return newEnv; 118 113 } … … 121 116 122 117 void TypeSubstitution::normalize() { 123 #if TIME_TO_CONVERT_PASSES 124 PassVisitor<Substituter> sub( *this, true ); 118 Pass<Substituter> sub( *this, true ); 125 119 do { 126 120 sub.pass.subCount = 0; 127 121 sub.pass.freeOnly = true; 128 122 for ( TypeEnvType::iterator i = typeEnv.begin(); i != typeEnv.end(); ++i ) { 129 i->second = i->second->accept Mutator( sub );123 i->second = i->second->accept( sub ); 130 124 } 131 125 } while ( sub.pass.subCount ); 132 #endif 133 } 134 135 #if TIME_TO_CONVERT_PASSES 136 137 Type * TypeSubstitution::Substituter::postmutate( TypeInstType *inst ) { 126 } 127 128 const Type * TypeSubstitution::Substituter::postvisit( const TypeInstType *inst ) { 138 129 BoundVarsType::const_iterator bound = boundVars.find( inst->name ); 139 130 if ( bound != boundVars.end() ) return inst; … … 146 137 // Note: this does not prevent cycles in the general case, so it may be necessary to do something more sophisticated here. 147 138 // TODO: investigate preventing type variables from being bound to themselves in the first place. 148 if ( TypeInstType * replacement = i->second.as<TypeInstType>() ) {139 if ( const TypeInstType * replacement = i->second.as<TypeInstType>() ) { 149 140 if ( inst->name == replacement->name ) { 150 141 return inst; … … 153 144 // std::cerr << "found " << inst->name << ", replacing with " << i->second << std::endl; 154 145 subCount++; 155 Type * newtype = i->second->clone(); 156 newtype->get_qualifiers() |= inst->get_qualifiers(); 157 delete inst; 158 // Note: need to recursively apply substitution to the new type because normalize does not substitute bound vars, but bound vars must be substituted when not in freeOnly mode. 159 return newtype->acceptMutator( *visitor ); 160 } // if 161 } 162 163 Expression * TypeSubstitution::Substituter::postmutate( NameExpr * nameExpr ) { 146 ptr<Type> newType = i->second; // force clone if needed 147 add_qualifiers( newType, inst->qualifiers ); 148 // Note: need to recursively apply substitution to the new type because normalize does not 149 // substitute bound vars, but bound vars must be substituted when not in freeOnly mode. 150 newType = newType->accept( *visitor ); 151 return newType.release(); 152 } // if 153 } 154 155 const Expr * TypeSubstitution::Substituter::postvisit( const NameExpr * nameExpr ) { 164 156 VarEnvType::const_iterator i = sub.varEnv.find( nameExpr->name ); 165 157 if ( i == sub.varEnv.end() ) { … … 168 160 subCount++; 169 161 delete nameExpr; 170 return i->second ->clone();171 } // if 172 } 173 174 void TypeSubstitution::Substituter::pre mutate( Type *type ) {162 return i->second; 163 } // if 164 } 165 166 void TypeSubstitution::Substituter::previsit( const ParameterizedType * ptype ) { 175 167 GuardValue( boundVars ); 176 168 // bind type variables from forall-qualifiers 177 169 if ( freeOnly ) { 178 for ( Type::ForallList::const_iterator tyvar = type->forall.begin(); tyvar != type->forall.end(); ++tyvar) {179 boundVars.insert( (*tyvar)->name );170 for ( const TypeDecl * tyvar : ptype->forall ) { 171 boundVars.insert( tyvar->name ); 180 172 } // for 181 173 } // if 182 174 } 183 175 184 template< typename TypeClass > 185 void TypeSubstitution::Substituter::handleAggregateType( TypeClass * type ) { 176 void TypeSubstitution::Substituter::handleAggregateType( const ReferenceToType * type ) { 186 177 GuardValue( boundVars ); 187 178 // bind type variables from forall-qualifiers 188 179 if ( freeOnly ) { 189 for ( Type::ForallList::const_iterator tyvar = type->forall.begin(); tyvar != type->forall.end(); ++tyvar) {190 boundVars.insert( (*tyvar)->name );180 for ( const TypeDecl * tyvar : type->forall ) { 181 boundVars.insert( tyvar->name ); 191 182 } // for 192 183 // bind type variables from generic type instantiations 193 std::list< TypeDecl* > *baseParameters = type->get_baseParameters(); 194 if ( baseParameters && ! type->parameters.empty() ) { 195 for ( std::list< TypeDecl* >::const_iterator tyvar = baseParameters->begin(); tyvar != baseParameters->end(); ++tyvar ) { 196 boundVars.insert( (*tyvar)->name ); 197 } // for 198 } // if 199 } // if 200 } 201 202 void TypeSubstitution::Substituter::premutate( StructInstType * aggregateUseType ) { 184 if ( auto decl = type->aggr() ) { 185 if ( ! type->params.empty() ) { 186 for ( const TypeDecl * tyvar : decl->params ) { 187 boundVars.insert( tyvar->name ); 188 } // for 189 } // if 190 } 191 } // if 192 } 193 194 void TypeSubstitution::Substituter::previsit( const StructInstType * aggregateUseType ) { 203 195 handleAggregateType( aggregateUseType ); 204 196 } 205 197 206 void TypeSubstitution::Substituter::pre mutate(UnionInstType *aggregateUseType ) {198 void TypeSubstitution::Substituter::previsit( const UnionInstType *aggregateUseType ) { 207 199 handleAggregateType( aggregateUseType ); 208 200 } 209 210 #endif211 201 212 202 } // namespace ast -
src/AST/TypeSubstitution.hpp
r83b52f1 r96ac72c0 155 155 Substituter( const TypeSubstitution & sub, bool freeOnly ) : sub( sub ), freeOnly( freeOnly ) {} 156 156 157 #if TIME_TO_CONVERT_PASSES 158 159 Type * postmutate( TypeInstType * aggregateUseType ); 160 Expression * postmutate( NameExpr * nameExpr ); 157 const Type * postvisit( const TypeInstType * aggregateUseType ); 158 const Expr * postvisit( const NameExpr * nameExpr ); 161 159 162 160 /// Records type variable bindings from forall-statements 163 void pre mutate(Type * type );161 void previsit( const ParameterizedType * type ); 164 162 /// Records type variable bindings from forall-statements and instantiations of generic types 165 template< typename TypeClass > void handleAggregateType( TypeClass * type ); 166 167 void premutate( StructInstType * aggregateUseType ); 168 void premutate( UnionInstType * aggregateUseType ); 169 170 #endif 163 void handleAggregateType( const ReferenceToType * type ); 164 165 void previsit( const StructInstType * aggregateUseType ); 166 void previsit( const UnionInstType * aggregateUseType ); 171 167 172 168 const TypeSubstitution & sub; -
src/AST/module.mk
r83b52f1 r96ac72c0 22 22 AST/DeclReplacer.cpp \ 23 23 AST/Expr.cpp \ 24 AST/ForallSubstitutionTable.cpp \ 24 25 AST/GenericSubstitution.cpp \ 25 26 AST/Init.cpp \ -
src/Common/ScopedMap.h
r83b52f1 r96ac72c0 249 249 250 250 /// Gets the note at the given scope 251 Note& getNote() { return scopes.back().note; } 252 const Note& getNote() const { return scopes.back().note; } 251 253 Note& getNote( size_type i ) { return scopes[i].note; } 252 254 const Note& getNote( size_type i ) const { return scopes[i].note; } -
src/Makefile.in
r83b52f1 r96ac72c0 168 168 AST/Convert.$(OBJEXT) AST/Decl.$(OBJEXT) \ 169 169 AST/DeclReplacer.$(OBJEXT) AST/Expr.$(OBJEXT) \ 170 AST/ForallSubstitutionTable.$(OBJEXT) \ 170 171 AST/GenericSubstitution.$(OBJEXT) AST/Init.$(OBJEXT) \ 171 172 AST/LinkageSpec.$(OBJEXT) AST/Node.$(OBJEXT) \ … … 585 586 AST/DeclReplacer.cpp \ 586 587 AST/Expr.cpp \ 588 AST/ForallSubstitutionTable.cpp \ 587 589 AST/GenericSubstitution.cpp \ 588 590 AST/Init.cpp \ … … 759 761 AST/$(DEPDIR)/$(am__dirstamp) 760 762 AST/Expr.$(OBJEXT): AST/$(am__dirstamp) AST/$(DEPDIR)/$(am__dirstamp) 763 AST/ForallSubstitutionTable.$(OBJEXT): AST/$(am__dirstamp) \ 764 AST/$(DEPDIR)/$(am__dirstamp) 761 765 AST/GenericSubstitution.$(OBJEXT): AST/$(am__dirstamp) \ 762 766 AST/$(DEPDIR)/$(am__dirstamp) … … 1212 1216 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/DeclReplacer.Po@am__quote@ 1213 1217 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Expr.Po@am__quote@ 1218 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/ForallSubstitutionTable.Po@am__quote@ 1214 1219 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/GenericSubstitution.Po@am__quote@ 1215 1220 @AMDEP_TRUE@@am__include@ @am__quote@AST/$(DEPDIR)/Init.Po@am__quote@ -
src/ResolvExpr/AdjustExprType.cc
r83b52f1 r96ac72c0 100 100 101 101 namespace { 102 struct AdjustExprType_new final : public ast::WithShortCircuiting { 102 class AdjustExprType_new final : public ast::WithShortCircuiting { 103 const ast::SymbolTable & symtab; 104 public: 103 105 const ast::TypeEnvironment & tenv; 104 const ast::SymbolTable & symtab;105 106 106 107 AdjustExprType_new( const ast::TypeEnvironment & e, const ast::SymbolTable & syms ) 107 : tenv( e ), symtab( syms) {}108 : symtab( syms ), tenv( e ) {} 108 109 109 void pre mutate( const ast::VoidType * ) { visit_children = false; }110 void pre mutate( const ast::BasicType * ) { visit_children = false; }111 void pre mutate( const ast::PointerType * ) { visit_children = false; }112 void pre mutate( const ast::ArrayType * ) { visit_children = false; }113 void pre mutate( const ast::FunctionType * ) { visit_children = false; }114 void pre mutate( const ast::StructInstType * ) { visit_children = false; }115 void pre mutate( const ast::UnionInstType * ) { visit_children = false; }116 void pre mutate( const ast::EnumInstType * ) { visit_children = false; }117 void pre mutate( const ast::TraitInstType * ) { visit_children = false; }118 void pre mutate( const ast::TypeInstType * ) { visit_children = false; }119 void pre mutate( const ast::TupleType * ) { visit_children = false; }120 void pre mutate( const ast::VarArgsType * ) { visit_children = false; }121 void pre mutate( const ast::ZeroType * ) { visit_children = false; }122 void pre mutate( const ast::OneType * ) { visit_children = false; }110 void previsit( const ast::VoidType * ) { visit_children = false; } 111 void previsit( const ast::BasicType * ) { visit_children = false; } 112 void previsit( const ast::PointerType * ) { visit_children = false; } 113 void previsit( const ast::ArrayType * ) { visit_children = false; } 114 void previsit( const ast::FunctionType * ) { visit_children = false; } 115 void previsit( const ast::StructInstType * ) { visit_children = false; } 116 void previsit( const ast::UnionInstType * ) { visit_children = false; } 117 void previsit( const ast::EnumInstType * ) { visit_children = false; } 118 void previsit( const ast::TraitInstType * ) { visit_children = false; } 119 void previsit( const ast::TypeInstType * ) { visit_children = false; } 120 void previsit( const ast::TupleType * ) { visit_children = false; } 121 void previsit( const ast::VarArgsType * ) { visit_children = false; } 122 void previsit( const ast::ZeroType * ) { visit_children = false; } 123 void previsit( const ast::OneType * ) { visit_children = false; } 123 124 124 const ast::Type * post mutate( const ast::ArrayType * at ) {125 const ast::Type * postvisit( const ast::ArrayType * at ) { 125 126 return new ast::PointerType{ at->base, at->qualifiers }; 126 127 } 127 128 128 const ast::Type * post mutate( const ast::FunctionType * ft ) {129 const ast::Type * postvisit( const ast::FunctionType * ft ) { 129 130 return new ast::PointerType{ ft }; 130 131 } 131 132 132 const ast::Type * post mutate( const ast::TypeInstType * inst ) {133 const ast::Type * postvisit( const ast::TypeInstType * inst ) { 133 134 // replace known function-type-variables with pointer-to-function 134 135 if ( const ast::EqvClass * eqvClass = tenv.lookup( inst->name ) ) { -
src/ResolvExpr/CandidateFinder.cpp
r83b52f1 r96ac72c0 370 370 // push empty tuple expression 371 371 newResult.parent = i; 372 std::vector< ast::ptr< ast::Expr > > emptyList; 373 newResult.expr = 374 new ast::TupleExpr{ CodeLocation{}, move( emptyList ) }; 372 newResult.expr = new ast::TupleExpr{ CodeLocation{}, {} }; 375 373 argType = newResult.expr->result; 376 374 } else { … … 548 546 genStart = genEnd; 549 547 550 return genEnd != results.size(); 548 return genEnd != results.size(); // were any new results added? 551 549 } 552 550 … … 594 592 595 593 /// Actually visits expressions to find their candidate interpretations 596 struct Finder final : public ast::WithShortCircuiting { 594 class Finder final : public ast::WithShortCircuiting { 595 const ast::SymbolTable & symtab; 596 public: 597 597 CandidateFinder & selfFinder; 598 const ast::SymbolTable & symtab;599 598 CandidateList & candidates; 600 599 const ast::TypeEnvironment & tenv; … … 602 601 603 602 Finder( CandidateFinder & f ) 604 : s elfFinder( f ), symtab( f.symtab), candidates( f.candidates ), tenv( f.env ),603 : symtab( f.localSyms ), selfFinder( f ), candidates( f.candidates ), tenv( f.env ), 605 604 targetType( f.targetType ) {} 606 605 … … 676 675 ast::TypeEnvironment funcEnv{ func->env }; 677 676 makeUnifiableVars( funcType, funcOpen, funcNeed ); 678 // add all type variables as open variables now so that those not used in the parameter679 // list are still considered open677 // add all type variables as open variables now so that those not used in the 678 // parameter list are still considered open 680 679 funcEnv.add( funcType->forall ); 681 680 … … 1558 1557 std::vector< std::string > errors; 1559 1558 for ( CandidateRef & candidate : candidates ) { 1560 satisfyAssertions( candidate, symtab, satisfied, errors );1559 satisfyAssertions( candidate, localSyms, satisfied, errors ); 1561 1560 } 1562 1561 … … 1613 1612 r->expr = ast::mutate_field( 1614 1613 r->expr.get(), &ast::Expr::result, 1615 adjustExprType( r->expr->result, r->env, symtab) );1614 adjustExprType( r->expr->result, r->env, localSyms ) ); 1616 1615 } 1617 1616 } … … 1631 1630 1632 1631 for ( const auto & x : xs ) { 1633 out.emplace_back( symtab, env );1632 out.emplace_back( localSyms, env ); 1634 1633 out.back().find( x, ResolvMode::withAdjustment() ); 1635 1634 -
src/ResolvExpr/CandidateFinder.hpp
r83b52f1 r96ac72c0 28 28 struct CandidateFinder { 29 29 CandidateList candidates; ///< List of candidate resolutions 30 const ast::SymbolTable & symtab; ///< Symbol table to lookup candidates30 const ast::SymbolTable & localSyms; ///< Symbol table to lookup candidates 31 31 const ast::TypeEnvironment & env; ///< Substitutions performed in this resolution 32 32 ast::ptr< ast::Type > targetType; ///< Target type for resolution 33 33 34 34 CandidateFinder( 35 const ast::SymbolTable & sym tab, const ast::TypeEnvironment & env,35 const ast::SymbolTable & syms, const ast::TypeEnvironment & env, 36 36 const ast::Type * tt = nullptr ) 37 : candidates(), symtab( symtab), env( env ), targetType( tt ) {}37 : candidates(), localSyms( syms ), env( env ), targetType( tt ) {} 38 38 39 39 /// Fill candidates with feasible resolutions for `expr` -
src/ResolvExpr/CommonType.cc
r83b52f1 r96ac72c0 939 939 ast::ptr< ast::Type > result; 940 940 const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >(); 941 const ast::ReferenceType * ref2 = type 1.as< ast::ReferenceType >();941 const ast::ReferenceType * ref2 = type2.as< ast::ReferenceType >(); 942 942 943 943 if ( depth1 > depth2 ) { -
src/ResolvExpr/ConversionCost.cc
r83b52f1 r96ac72c0 10 10 // Created On : Sun May 17 07:06:19 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Mon Jun 24 13:33:00 201913 // Update Count : 2 612 // Last Modified On : Thr Jul 4 10:56:00 2019 13 // Update Count : 27 14 14 // 15 15 … … 764 764 cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] ); 765 765 } 766 } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) { 767 cost = Cost::zero; 768 // +1 for zero_t ->, +1 for disambiguation 769 cost.incSafe( maxIntCost + 2 ); 766 770 } 767 771 } … … 781 785 cost.incSign( signMatrix[ ast::BasicType::SignedInt ][ dstAsBasic->kind ] ); 782 786 } 783 } else if ( dynamic_cast< const ast::PointerType * >( dst ) ) {784 cost = Cost::zero;785 cost.incSafe( maxIntCost + 2 );786 787 } 787 788 } -
src/ResolvExpr/PolyCost.cc
r83b52f1 r96ac72c0 58 58 59 59 // TODO: When the old PolyCost is torn out get rid of the _new suffix. 60 struct PolyCost_new { 60 class PolyCost_new { 61 const ast::SymbolTable &symtab; 62 public: 61 63 int result; 62 const ast::SymbolTable &symtab;63 64 const ast::TypeEnvironment &env_; 64 65 65 PolyCost_new( const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ) :66 result( 0 ), symtab( symtab), env_( env ) {}66 PolyCost_new( const ast::SymbolTable & symtab, const ast::TypeEnvironment & env ) 67 : symtab( symtab ), result( 0 ), env_( env ) {} 67 68 68 69 void previsit( const ast::TypeInstType * type ) { -
src/ResolvExpr/RenameVars.cc
r83b52f1 r96ac72c0 19 19 #include <utility> // for pair 20 20 21 #include "AST/ForallSubstitutionTable.hpp" 21 22 #include "AST/Pass.hpp" 22 23 #include "AST/Type.hpp" … … 30 31 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 31 32 33 #include "AST/Copy.hpp" 34 32 35 namespace ResolvExpr { 33 36 … … 37 40 int resetCount = 0; 38 41 ScopedMap< std::string, std::string > nameMap; 42 public: 43 ast::ForallSubstitutionTable subs; 39 44 40 public:41 45 void reset() { 42 46 level = 0; … … 44 48 } 45 49 46 using mapConstIterator = ScopedMap< std::string, std::string >::const_iterator;47 48 50 void rename( TypeInstType * type ) { 49 mapConstIteratorit = nameMap.find( type->name );51 auto it = nameMap.find( type->name ); 50 52 if ( it != nameMap.end() ) { 51 53 type->name = it->second; … … 65 67 // ditto for assertion names, the next level in 66 68 level++; 67 // acceptAll( td->assertions, *this ); 68 } // for 69 } // if 69 } 70 } 70 71 } 71 72 … … 77 78 78 79 const ast::TypeInstType * rename( const ast::TypeInstType * type ) { 79 mapConstIterator it = nameMap.find( type->name ); 80 // re-linking of base type handled by WithForallSubstitutor 81 82 // rename 83 auto it = nameMap.find( type->name ); 80 84 if ( it != nameMap.end() ) { 81 ast::TypeInstType * mutType = ast::mutate( type ); 82 mutType->name = it->second; 83 type = mutType; 85 // unconditionally mutate because map will *always* have different name, 86 // if this mutates, will *always* have been mutated by ForallSubstitutor above 87 ast::TypeInstType * mut = ast::mutate( type ); 88 mut->name = it->second; 89 type = mut; 84 90 } 91 85 92 return type; 86 93 } … … 88 95 template<typename NodeT> 89 96 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; 97 if ( type->forall.empty() ) return type; 98 99 nameMap.beginScope(); 100 100 101 ast::TypeDecl * decl = ast::mutate( td.get() ); 102 decl->name = newname; 103 td = decl; 104 } 101 // Load new names from this forall clause and perform renaming. 102 NodeT * mutType = ast::mutate( type ); 103 assert( type == mutType && "mutated type must be unique from ForallSubstitutor" ); 104 for ( ast::ptr< ast::TypeDecl > & td : mutType->forall ) { 105 std::ostringstream output; 106 output << "_" << resetCount << "_" << level << "_" << td->name; 107 std::string newname = output.str(); 108 nameMap[ td->name ] = newname; 109 ++level; 110 111 ast::TypeDecl * mutDecl = ast::mutate( td.get() ); 112 assert( td == mutDecl && "mutated decl must be unique from ForallSubstitutor" ); 113 mutDecl->name = newname; 114 // assertion above means `td = mutDecl;` is unnecessary 105 115 } 116 // assertion above means `type = mutType;` is unnecessary 117 106 118 return type; 107 119 } 108 120 109 template<typename NodeT> 110 const NodeT * closeLevel( const NodeT * type ) { 111 if ( !type->forall.empty() ) { 112 nameMap.endScope(); 113 } 114 return type; 121 void closeLevel( const ast::ParameterizedType * type ) { 122 if ( type->forall.empty() ) return; 123 124 nameMap.endScope(); 115 125 } 116 126 }; … … 119 129 RenamingData renaming; 120 130 121 struct RenameVars {131 struct RenameVars_old { 122 132 void previsit( TypeInstType * instType ) { 123 133 renaming.openLevel( (Type*)instType ); … … 130 140 renaming.closeLevel( type ); 131 141 } 142 }; 143 144 struct RenameVars_new /*: public ast::WithForallSubstitutor*/ { 145 #warning when old RenameVars goes away, replace hack below with global pass inheriting from WithForallSubstitutor 146 ast::ForallSubstitutionTable & subs = renaming.subs; 132 147 133 148 const ast::FunctionType * previsit( const ast::FunctionType * type ) { … … 146 161 return renaming.rename( renaming.openLevel( type ) ); 147 162 } 148 const ast::ParameterizedType *postvisit( const ast::ParameterizedType * type ) {149 re turn renaming.closeLevel( type );163 void postvisit( const ast::ParameterizedType * type ) { 164 renaming.closeLevel( type ); 150 165 } 151 166 }; … … 154 169 155 170 void renameTyVars( Type * t ) { 156 PassVisitor<RenameVars > renamer;171 PassVisitor<RenameVars_old> renamer; 157 172 t->accept( renamer ); 158 173 } 159 174 160 175 const ast::Type * renameTyVars( const ast::Type * t ) { 161 ast::Pass<RenameVars> renamer; 162 return t->accept( renamer ); 176 ast::Type *tc = ast::deepCopy(t); 177 ast::Pass<RenameVars_new> renamer; 178 // return t->accept( renamer ); 179 return tc->accept( renamer ); 163 180 } 164 181 -
src/ResolvExpr/ResolveTypeof.cc
r83b52f1 r96ac72c0 153 153 } 154 154 155 return newType ;155 return newType.release(); 156 156 } 157 157 }; -
src/ResolvExpr/Resolver.cc
r83b52f1 r96ac72c0 1108 1108 1109 1109 // set up and resolve expression cast to void 1110 ast:: CastExpr *untyped = new ast::CastExpr{ expr };1110 ast::ptr< ast::CastExpr > untyped = new ast::CastExpr{ expr }; 1111 1111 CandidateRef choice = findUnfinishedKindExpression( 1112 1112 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() ); … … 1247 1247 }; 1248 1248 1249 void resolve( std::list< ast::ptr< ast::Decl> >& translationUnit ) {1249 void resolve( std::list< ast::ptr< ast::Decl > >& translationUnit ) { 1250 1250 ast::Pass< Resolver_new > resolver; 1251 1251 accept_all( translationUnit, resolver ); … … 1281 1281 ast::ptr< ast::FunctionDecl > ret = functionDecl; 1282 1282 for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) { 1283 const ast::ptr< ast::DeclWithType> & d = functionDecl->type->params[i];1283 const ast::ptr< ast::DeclWithType > & d = functionDecl->type->params[i]; 1284 1284 1285 1285 if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) { … … 1298 1298 } 1299 1299 } 1300 return ret. get();1300 return ret.release(); 1301 1301 } 1302 1302 -
src/ResolvExpr/SpecCost.cc
r83b52f1 r96ac72c0 10 10 // Created On : Tue Oct 02 15:50:00 2018 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Jun 19 10:43:00 2019 13 // Update Count : 2 14 // 15 12 // Last Modified On : Wed Jul 3 11:07:00 2019 13 // Update Count : 3 14 // 15 16 #include <cassert> 16 17 #include <limits> 17 18 #include <list> … … 129 130 typename std::add_pointer<ast::Type const *(typename T::value_type const &)>::type; 130 131 132 #warning Should use a standard maybe_accept 133 void maybe_accept( ast::Type const * type ) { 134 if ( type ) { 135 auto node = type->accept( *visitor ); 136 assert( node == nullptr || node == type ); 137 } 138 } 139 131 140 // Update the minimum to the new lowest non-none value. 132 141 template<typename T> … … 134 143 for ( const auto & node : list ) { 135 144 count = -1; 136 ma pper( node )->accept( *visitor);145 maybe_accept( mapper( node ) ); 137 146 if ( count != -1 && count < minimum ) minimum = count; 138 147 } -
src/SymTab/Autogen.h
r83b52f1 r96ac72c0 21 21 22 22 #include "AST/Decl.hpp" 23 #include "AST/Eval.hpp" 23 24 #include "AST/Expr.hpp" 24 25 #include "AST/Init.hpp" … … 264 265 } 265 266 266 ast::ptr< ast::Expr > begin, end, cmp, update; 267 ast::ptr< ast::Expr > begin, end; 268 std::string cmp, update; 267 269 268 270 if ( forward ) { … … 270 272 begin = ast::ConstantExpr::from_int( loc, 0 ); 271 273 end = array->dimension; 272 cmp = new ast::NameExpr{ loc, "?<?" };273 update = new ast::NameExpr{ loc, "++?" };274 cmp = "?<?"; 275 update = "++?"; 274 276 } else { 275 277 // generate: for ( int i = N-1; i >= 0; --i ) 276 begin = new ast::UntypedExpr{ 277 loc, new ast::NameExpr{ loc, "?-?" }, 278 { array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } }; 278 begin = ast::call( 279 loc, "?-?", array->dimension, ast::ConstantExpr::from_int( loc, 1 ) ); 279 280 end = ast::ConstantExpr::from_int( loc, 0 ); 280 cmp = new ast::NameExpr{ loc, "?>=?" };281 update = new ast::NameExpr{ loc, "--?" };281 cmp = "?>=?"; 282 update = "--?"; 282 283 } 283 284 … … 285 286 loc, indexName.newName(), new ast::BasicType{ ast::BasicType::SignedInt }, 286 287 new ast::SingleInit{ loc, begin } }; 287 288 ast::ptr< ast::Expr > cond = new ast::UntypedExpr{ 289 loc, cmp, { new ast::VariableExpr{ loc, index }, end } }; 290 291 ast::ptr< ast::Expr > inc = new ast::UntypedExpr{ 292 loc, update, { new ast::VariableExpr{ loc, index } } }; 293 294 ast::ptr< ast::Expr > dstIndex = new ast::UntypedExpr{ 295 loc, new ast::NameExpr{ loc, "?[?]" }, 296 { dstParam, new ast::VariableExpr{ loc, index } } }; 288 ast::ptr< ast::Expr > indexVar = new ast::VariableExpr{ loc, index }; 289 290 ast::ptr< ast::Expr > cond = ast::call( loc, cmp, indexVar, end ); 291 292 ast::ptr< ast::Expr > inc = ast::call( loc, update, indexVar ); 293 294 ast::ptr< ast::Expr > dstIndex = ast::call( loc, "?[?]", dstParam, indexVar ); 297 295 298 296 // srcParam must keep track of the array indices to build the source parameter and/or 299 297 // array list initializer 300 srcParam.addArrayIndex( new ast::VariableExpr{ loc, index }, array->dimension );298 srcParam.addArrayIndex( indexVar, array->dimension ); 301 299 302 300 // for stmt's body, eventually containing call … … 384 382 if ( isUnnamedBitfield( obj ) ) return {}; 385 383 386 ast::ptr< ast::Type > addCast = nullptr;384 ast::ptr< ast::Type > addCast; 387 385 if ( (fname == "?{}" || fname == "^?{}") && ( ! obj || ( obj && ! obj->bitfieldWidth ) ) ) { 388 386 assert( dstParam->result ); -
src/Tuples/Explode.cc
r83b52f1 r96ac72c0 129 129 for ( const ast::Expr * expr : tupleExpr->exprs ) { 130 130 exprs.emplace_back( applyCast( expr, false ) ); 131 //exprs.emplace_back( ast::ptr< ast::Expr >( applyCast( expr, false ) ) );132 131 } 133 132 if ( first ) { -
src/Tuples/Explode.h
r83b52f1 r96ac72c0 210 210 } 211 211 // Cast a reference away to a value-type to allow further explosion. 212 if ( dynamic_cast< const ast::ReferenceType *>( local->result.get()) ) {212 if ( local->result.as< ast::ReferenceType >() ) { 213 213 local = new ast::CastExpr{ local, tupleType }; 214 214 } … … 220 220 // delete idx; 221 221 } 222 // delete local;223 222 } 224 223 } else { -
src/Tuples/TupleAssignment.cc
r83b52f1 r96ac72c0 465 465 // resolve ctor/dtor for the new object 466 466 ast::ptr< ast::Init > ctorInit = ResolvExpr::resolveCtorInit( 467 InitTweak::genCtorInit( location, ret ), spotter.crntFinder. symtab);467 InitTweak::genCtorInit( location, ret ), spotter.crntFinder.localSyms ); 468 468 // remove environments from subexpressions of stmtExpr 469 469 ast::Pass< EnvRemover > rm{ env }; … … 560 560 // resolve the cast expression so that rhsCand return type is bound by the cast 561 561 // type as needed, and transfer the resulting environment 562 ResolvExpr::CandidateFinder finder{ spotter.crntFinder. symtab, env };562 ResolvExpr::CandidateFinder finder{ spotter.crntFinder.localSyms, env }; 563 563 finder.find( rhsCand->expr, ResolvExpr::ResolvMode::withAdjustment() ); 564 564 assert( finder.candidates.size() == 1 ); … … 609 609 // explode the LHS so that each field of a tuple-valued expr is assigned 610 610 ResolvExpr::CandidateList lhs; 611 explode( *lhsCand, crntFinder. symtab, back_inserter(lhs), true );611 explode( *lhsCand, crntFinder.localSyms, back_inserter(lhs), true ); 612 612 for ( ResolvExpr::CandidateRef & cand : lhs ) { 613 613 // each LHS value must be a reference - some come in with a cast, if not … … 629 629 if ( isTuple( rhsCand->expr ) ) { 630 630 // multiple assignment 631 explode( *rhsCand, crntFinder. symtab, back_inserter(rhs), true );631 explode( *rhsCand, crntFinder.localSyms, back_inserter(rhs), true ); 632 632 matcher.reset( 633 633 new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } ); … … 648 648 // multiple assignment 649 649 ResolvExpr::CandidateList rhs; 650 explode( rhsCand, crntFinder. symtab, back_inserter(rhs), true );650 explode( rhsCand, crntFinder.localSyms, back_inserter(rhs), true ); 651 651 matcher.reset( 652 652 new MultipleAssignMatcher{ *this, expr->location, lhs, rhs } ); … … 678 678 ) 679 679 680 ResolvExpr::CandidateFinder finder{ crntFinder. symtab, matcher->env };680 ResolvExpr::CandidateFinder finder{ crntFinder.localSyms, matcher->env }; 681 681 682 682 try { -
src/main.cc
r83b52f1 r96ac72c0 29 29 #include <string> // for char_traits, operator<< 30 30 31 #include "AST/Convert.hpp" 31 32 #include "CompilationState.h" 32 33 #include "../config.h" // for CFA_LIBDIR … … 302 303 } // if 303 304 304 PASS( "Resolve", ResolvExpr::resolve( translationUnit ) ); 305 // PASS( "Resolve", ResolvExpr::resolve( translationUnit ) ); 306 { 307 auto transUnit = convert( move( translationUnit ) ); 308 PASS( "Resolve", ResolvExpr::resolve( transUnit ) ); 309 translationUnit = convert( move( transUnit ) ); 310 } 305 311 if ( exprp ) { 306 312 dump( translationUnit );
Note:
See TracChangeset
for help on using the changeset viewer.