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