Changes in / [c532847:76d73fc]
- Location:
- src
- Files:
-
- 1 deleted
- 30 edited
-
AST/Convert.cpp (modified) (19 diffs)
-
AST/Decl.cpp (modified) (1 diff)
-
AST/Decl.hpp (modified) (1 diff)
-
AST/DeclReplacer.cpp (modified) (3 diffs)
-
AST/DeclReplacer.hpp (modified) (1 diff)
-
AST/Expr.cpp (modified) (2 diffs)
-
AST/Expr.hpp (modified) (4 diffs)
-
AST/Fwd.hpp (modified) (1 diff)
-
AST/Node.hpp (modified) (1 diff)
-
AST/Pass.hpp (modified) (2 diffs)
-
AST/Pass.impl.hpp (modified) (6 diffs)
-
AST/SymbolTable.cpp (modified) (1 diff)
-
AST/SymbolTable.hpp (modified) (1 diff)
-
Common/utility.h (modified) (1 diff)
-
GenPoly/GenPoly.cc (modified) (9 diffs)
-
GenPoly/GenPoly.h (modified) (4 diffs)
-
InitTweak/FixGlobalInit.cc (modified) (4 diffs)
-
InitTweak/FixGlobalInit.h (modified) (2 diffs)
-
InitTweak/FixInit.cc (modified) (1 diff)
-
InitTweak/FixInit.h (modified) (2 diffs)
-
InitTweak/FixInitNew.cpp (deleted)
-
InitTweak/GenInit.cc (modified) (1 diff)
-
InitTweak/GenInit.h (modified) (1 diff)
-
InitTweak/InitTweak.cc (modified) (6 diffs)
-
InitTweak/InitTweak.h (modified) (3 diffs)
-
InitTweak/module.mk (modified) (1 diff)
-
ResolvExpr/Resolver.cc (modified) (5 diffs)
-
ResolvExpr/Resolver.h (modified) (1 diff)
-
SymTab/Autogen.cc (modified) (2 diffs)
-
SymTab/Autogen.h (modified) (1 diff)
-
main.cc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
rc532847 r76d73fc 47 47 48 48 //================================================================================================ 49 namespace ast{49 namespace { 50 50 51 51 // This is to preserve the FindSpecialDecls hack. It does not (and perhaps should not) 52 52 // allow us to use the same stratagy in the new ast. 53 // xxx - since convert back pass works, this concern seems to be unnecessary.54 55 // these need to be accessed in new FixInit now56 53 ast::Type * sizeType = nullptr; 57 54 ast::FunctionDecl * dereferenceOperator = nullptr; … … 66 63 using Cache = std::unordered_map< const ast::Node *, BaseSyntaxNode * >; 67 64 Cache cache; 68 69 // Statements can no longer be shared.70 // however, since StmtExprResult is now implemented, need to still maintain71 // readonly references.72 Cache readonlyCache;73 65 74 66 template<typename T> … … 162 154 } 163 155 164 const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final { 156 const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final { 157 auto&& bfwd = get<Expression>().accept1( node->bitfieldWidth ); 158 auto&& type = get<Type>().accept1( node->type ); 159 auto&& init = get<Initializer>().accept1( node->init ); 160 auto&& attr = get<Attribute>().acceptL( node->attributes ); 165 161 if ( inCache( node ) ) { 166 162 return nullptr; 167 163 } 168 auto bfwd = get<Expression>().accept1( node->bitfieldWidth );169 auto type = get<Type>().accept1( node->type );170 auto attr = get<Attribute>().acceptL( node->attributes );171 172 164 auto decl = new ObjectDecl( 173 165 node->name, … … 176 168 bfwd, 177 169 type->clone(), 178 nullptr, // prevent infinite loop170 init, 179 171 attr, 180 172 Type::FuncSpecifiers( node->funcSpec.val ) 181 173 ); 182 183 // handles the case where node->init references itself 184 // xxx - does it really happen? 185 declWithTypePostamble(decl, node); 186 auto init = get<Initializer>().accept1( node->init ); 187 decl->init = init; 188 189 this->node = decl; 190 return nullptr; 174 return declWithTypePostamble( decl, node ); 191 175 } 192 176 … … 221 205 decl->statements = get<CompoundStmt>().accept1( node->stmts ); 222 206 decl->withExprs = get<Expression>().acceptL( node->withExprs ); 223 if ( ast::dereferenceOperator == node ) {207 if ( dereferenceOperator == node ) { 224 208 Validate::dereferenceOperator = decl; 225 209 } 226 if ( ast::dtorStructDestroy == node ) {210 if ( dtorStructDestroy == node ) { 227 211 Validate::dtorStructDestroy = decl; 228 212 } … … 283 267 ); 284 268 285 if ( ast::dtorStruct == node ) {269 if ( dtorStruct == node ) { 286 270 Validate::dtorStruct = decl; 287 271 } … … 336 320 337 321 const ast::Stmt * stmtPostamble( Statement * stmt, const ast::Stmt * node ) { 338 // force statements in old tree to be unique. 339 // cache.emplace( node, stmt ); 340 readonlyCache.emplace( node, stmt ); 322 cache.emplace( node, stmt ); 341 323 stmt->location = node->location; 342 324 stmt->labels = makeLabelL( stmt, node->labels ); … … 355 337 if ( inCache( node ) ) return nullptr; 356 338 auto stmt = new ExprStmt( nullptr ); 339 cache.emplace( node, stmt ); 357 340 stmt->expr = get<Expression>().accept1( node->expr ); 358 341 return stmtPostamble( stmt, node ); … … 1028 1011 auto stmts = node->stmts; 1029 1012 // disable sharing between multiple StmtExprs explicitly. 1030 // this should no longer be true. 1031 1013 if (inCache(stmts)) { 1014 stmts = ast::deepCopy(stmts.get()); 1015 } 1032 1016 auto rslt = new StmtExpr( 1033 1017 get<CompoundStmt>().accept1(stmts) … … 1036 1020 rslt->returnDecls = get<ObjectDecl>().acceptL(node->returnDecls); 1037 1021 rslt->dtors = get<Expression>().acceptL(node->dtors); 1038 if (node->resultExpr) {1039 // this MUST be found by children visit1040 rslt->resultExpr = strict_dynamic_cast<ExprStmt *>(readonlyCache.at(node->resultExpr));1041 }1042 1022 1043 1023 auto expr = visitBaseExpr( node, rslt ); … … 1056 1036 1057 1037 auto expr = visitBaseExpr( node, rslt ); 1058 this->node = expr ->clone();1038 this->node = expr; 1059 1039 return nullptr; 1060 1040 } … … 1146 1126 auto type = new BasicType{ cv( node ), (BasicType::Kind)(unsigned)node->kind }; 1147 1127 // I believe this should always be a BasicType. 1148 if ( ast::sizeType == node ) {1128 if ( sizeType == node ) { 1149 1129 Validate::SizeType = type; 1150 1130 } … … 1549 1529 1550 1530 // function type is now derived from parameter decls instead of storing them 1551 1552 /*1553 1531 auto ftype = new ast::FunctionType((ast::ArgumentFlag)old->type->isVarArgs, cv(old->type)); 1554 1532 ftype->params.reserve(paramVars.size()); … … 1562 1540 } 1563 1541 ftype->forall = std::move(forall); 1564 */ 1565 1566 // can function type have attributes? seems not to be the case. 1567 // visitType(old->type, ftype); 1542 visitType(old->type, ftype); 1568 1543 1569 1544 auto decl = new ast::FunctionDecl{ … … 1571 1546 old->name, 1572 1547 // GET_ACCEPT_1(type, FunctionType), 1573 std::move(forall),1574 1548 std::move(paramVars), 1575 1549 std::move(returnVars), … … 1578 1552 { old->linkage.val }, 1579 1553 GET_ACCEPT_V(attributes, Attribute), 1580 { old->get_funcSpec().val }, 1581 old->type->isVarArgs 1554 { old->get_funcSpec().val } 1582 1555 }; 1583 1556 1584 //decl->type = ftype;1557 decl->type = ftype; 1585 1558 cache.emplace( old, decl ); 1586 1559 … … 1597 1570 1598 1571 if ( Validate::dereferenceOperator == old ) { 1599 ast::dereferenceOperator = decl;1572 dereferenceOperator = decl; 1600 1573 } 1601 1574 1602 1575 if ( Validate::dtorStructDestroy == old ) { 1603 ast::dtorStructDestroy = decl;1576 dtorStructDestroy = decl; 1604 1577 } 1605 1578 } … … 1626 1599 1627 1600 if ( Validate::dtorStruct == old ) { 1628 ast::dtorStruct = decl;1601 dtorStruct = decl; 1629 1602 } 1630 1603 } … … 2558 2531 // I believe this should always be a BasicType. 2559 2532 if ( Validate::SizeType == old ) { 2560 ast::sizeType = type;2533 sizeType = type; 2561 2534 } 2562 2535 visitType( old, type ); -
src/AST/Decl.cpp
rc532847 r76d73fc 48 48 49 49 // --- FunctionDecl 50 51 FunctionDecl::FunctionDecl( const CodeLocation & loc, const std::string & name,52 std::vector<ptr<TypeDecl>>&& forall,53 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns,54 CompoundStmt * stmts, Storage::Classes storage, Linkage::Spec linkage,55 std::vector<ptr<Attribute>>&& attrs, Function::Specs fs, bool isVarArgs)56 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)),57 stmts( stmts ) {58 FunctionType * ftype = new FunctionType(static_cast<ArgumentFlag>(isVarArgs));59 for (auto & param : this->params) {60 ftype->params.emplace_back(param->get_type());61 }62 for (auto & ret : this->returns) {63 ftype->returns.emplace_back(ret->get_type());64 }65 ftype->forall = std::move(forall);66 this->type = ftype;67 }68 69 50 70 51 const Type * FunctionDecl::get_type() const { return type.get(); } -
src/AST/Decl.hpp
rc532847 r76d73fc 131 131 std::vector< ptr<Expr> > withExprs; 132 132 133 FunctionDecl( const CodeLocation & loc, const std::string & name, std::vector<ptr<TypeDecl>>&& forall,133 FunctionDecl( const CodeLocation & loc, const std::string & name, 134 134 std::vector<ptr<DeclWithType>>&& params, std::vector<ptr<DeclWithType>>&& returns, 135 135 CompoundStmt * stmts, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C, 136 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {} , bool isVarArgs = false);137 //: DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)),138 //stmts( stmts ) {}136 std::vector<ptr<Attribute>>&& attrs = {}, Function::Specs fs = {}) 137 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), params(std::move(params)), returns(std::move(returns)), 138 stmts( stmts ) {} 139 139 140 140 const Type * get_type() const override; -
src/AST/DeclReplacer.cpp
rc532847 r76d73fc 38 38 const ast::TypeInstType * previsit( const ast::TypeInstType * ); 39 39 }; 40 41 struct VarExprReplacer {42 private:43 const ExprMap & exprMap;44 45 public:46 VarExprReplacer(const ExprMap & exprMap): exprMap (exprMap) {}47 48 const Expr * postvisit (const VariableExpr *);49 };50 40 } 51 41 … … 64 54 DeclMap declMap; 65 55 return replace( node, declMap, typeMap, debug ); 66 }67 68 const ast::Node * replace( const ast::Node * node, const ExprMap & exprMap) {69 Pass<VarExprReplacer> replacer = {exprMap};70 return node->accept( replacer );71 56 } 72 57 … … 103 88 return ninst; 104 89 } 105 106 const Expr * VarExprReplacer::postvisit( const VariableExpr * expr ) {107 if (!exprMap.count(expr->var)) return expr;108 109 return exprMap.at(expr->var);110 }111 112 90 } 113 91 } -
src/AST/DeclReplacer.hpp
rc532847 r76d73fc 23 23 class DeclWithType; 24 24 class TypeDecl; 25 class Expr;26 25 27 26 namespace DeclReplacer { 28 27 using DeclMap = std::unordered_map< const DeclWithType *, const DeclWithType * >; 29 28 using TypeMap = std::unordered_map< const TypeDecl *, const TypeDecl * >; 30 using ExprMap = std::unordered_map< const DeclWithType *, const Expr * >;31 29 32 30 const Node * replace( const Node * node, const DeclMap & declMap, bool debug = false ); 33 31 const Node * replace( const Node * node, const TypeMap & typeMap, bool debug = false ); 34 32 const Node * replace( const Node * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false ); 35 const Node * replace( const Node * node, const ExprMap & exprMap);36 33 } 37 34 } -
src/AST/Expr.cpp
rc532847 r76d73fc 67 67 // --- UntypedExpr 68 68 69 UntypedExpr * UntypedExpr::createDeref( const CodeLocation & loc, constExpr * arg ) {69 UntypedExpr * UntypedExpr::createDeref( const CodeLocation & loc, Expr * arg ) { 70 70 assert( arg ); 71 71 … … 92 92 } 93 93 94 UntypedExpr * UntypedExpr::createAssign( const CodeLocation & loc, const Expr * lhs, constExpr * rhs ) {94 UntypedExpr * UntypedExpr::createAssign( const CodeLocation & loc, Expr * lhs, Expr * rhs ) { 95 95 assert( lhs && rhs ); 96 96 -
src/AST/Expr.hpp
rc532847 r76d73fc 226 226 227 227 /// Creates a new dereference expression 228 static UntypedExpr * createDeref( const CodeLocation & loc, constExpr * arg );228 static UntypedExpr * createDeref( const CodeLocation & loc, Expr * arg ); 229 229 /// Creates a new assignment expression 230 static UntypedExpr * createAssign( const CodeLocation & loc, const Expr * lhs, constExpr * rhs );230 static UntypedExpr * createAssign( const CodeLocation & loc, Expr * lhs, Expr * rhs ); 231 231 232 232 const Expr * accept( Visitor & v ) const override { return v.visit( this ); } … … 422 422 const CodeLocation & loc, const Type * ty, const std::string & r, 423 423 std::optional<unsigned long long> i ) 424 : Expr( loc, ty ), rep( r ), ival( i ) , underlyer(ty){}424 : Expr( loc, ty ), rep( r ), ival( i ) {} 425 425 426 426 /// Gets the integer value of this constant, if one is appropriate to its type. … … 617 617 618 618 ImplicitCopyCtorExpr( const CodeLocation& loc, const ApplicationExpr * call ) 619 : Expr( loc, call->result ) , callExpr(call) { assert( call ); assert(call->result); }619 : Expr( loc, call->result ) { assert( call ); } 620 620 621 621 const Expr * accept( Visitor & v ) const override { return v.visit( this ); } … … 742 742 std::vector<ptr<Expr>> dtors; ///< destructor(s) for return variable(s) 743 743 744 readonly<ExprStmt> resultExpr;745 746 744 StmtExpr( const CodeLocation & loc, const CompoundStmt * ss ); 747 745 -
src/AST/Fwd.hpp
rc532847 r76d73fc 137 137 typedef unsigned int UniqueId; 138 138 139 extern Type * sizeType;140 extern FunctionDecl * dereferenceOperator;141 extern StructDecl * dtorStruct;142 extern FunctionDecl * dtorStructDestroy;143 144 139 } -
src/AST/Node.hpp
rc532847 r76d73fc 49 49 50 50 bool unique() const { return strong_count == 1; } 51 bool isManaged() const {return strong_count > 0; }52 51 53 52 private: -
src/AST/Pass.hpp
rc532847 r76d73fc 236 236 const ast::Expr * call_accept( const ast::Expr * ); 237 237 238 // requests WithStmtsToAdd directly add to this statement, as if it is a compound.239 240 const ast::Stmt * call_accept_as_compound(const ast::Stmt *);241 242 238 template< typename node_t > 243 239 auto call_accept( const node_t * node ) -> typename std::enable_if< … … 261 257 template<typename node_t, typename parent_t, typename child_t> 262 258 void maybe_accept(const node_t * &, child_t parent_t::* child); 263 264 template<typename node_t, typename parent_t, typename child_t>265 void maybe_accept_as_compound(const node_t * &, child_t parent_t::* child);266 259 267 260 private: -
src/AST/Pass.impl.hpp
rc532847 r76d73fc 167 167 __pedantic_pass_assert( stmt ); 168 168 169 return stmt->accept( *this );170 }171 172 template< typename core_t >173 const ast::Stmt * ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) {174 __pedantic_pass_assert( __visit_children() );175 __pedantic_pass_assert( stmt );176 177 169 // add a few useful symbols to the scope 178 170 using __pass::empty; … … 332 324 333 325 auto new_val = call_accept( old_val ); 334 335 static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR");336 337 if( __pass::differs(old_val, new_val) ) {338 auto new_parent = __pass::mutate<core_t>(parent);339 new_parent->*child = new_val;340 parent = new_parent;341 }342 }343 344 template< typename core_t >345 template<typename node_t, typename parent_t, typename child_t>346 void ast::Pass< core_t >::maybe_accept_as_compound(347 const node_t * & parent,348 child_t parent_t::*child349 ) {350 static_assert( std::is_base_of<parent_t, node_t>::value, "Error deducing member object" );351 352 if(__pass::skip(parent->*child)) return;353 const auto & old_val = __pass::get(parent->*child, 0);354 355 static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR");356 357 auto new_val = call_accept_as_compound( old_val );358 326 359 327 static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR"); … … 735 703 maybe_accept( node, &IfStmt::inits ); 736 704 maybe_accept( node, &IfStmt::cond ); 737 maybe_accept _as_compound( node, &IfStmt::thenPart );738 maybe_accept _as_compound( node, &IfStmt::elsePart );705 maybe_accept( node, &IfStmt::thenPart ); 706 maybe_accept( node, &IfStmt::elsePart ); 739 707 }) 740 708 … … 753 721 maybe_accept( node, &WhileStmt::inits ); 754 722 maybe_accept( node, &WhileStmt::cond ); 755 maybe_accept _as_compound( node, &WhileStmt::body );723 maybe_accept( node, &WhileStmt::body ); 756 724 }) 757 725 … … 768 736 // for statements introduce a level of scope (for the initialization) 769 737 guard_symtab guard { *this }; 770 // xxx - old ast does not create WithStmtsToAdd scope for loop inits. should revisit this later.771 738 maybe_accept( node, &ForStmt::inits ); 772 739 maybe_accept( node, &ForStmt::cond ); 773 740 maybe_accept( node, &ForStmt::inc ); 774 maybe_accept _as_compound( node, &ForStmt::body );741 maybe_accept( node, &ForStmt::body ); 775 742 }) 776 743 … … 867 834 maybe_accept( node, &CatchStmt::decl ); 868 835 maybe_accept( node, &CatchStmt::cond ); 869 maybe_accept _as_compound( node, &CatchStmt::body );836 maybe_accept( node, &CatchStmt::body ); 870 837 }) 871 838 -
src/AST/SymbolTable.cpp
rc532847 r76d73fc 335 335 } 336 336 337 338 void SymbolTable::addFunction ( const FunctionDecl * func) {339 addTypes( f unc->type->forall );340 addIds( f unc->returns );341 addIds( f unc->params );342 } 343 337 /* 338 void SymbolTable::addFunctionType( const FunctionType * ftype ) { 339 addTypes( ftype->forall ); 340 addIds( ftype->returns ); 341 addIds( ftype->params ); 342 } 343 */ 344 344 345 345 void SymbolTable::lazyInitScope() { -
src/AST/SymbolTable.hpp
rc532847 r76d73fc 145 145 146 146 /// convenience function for adding all of the declarations in a function type to the indexer 147 void addFunction( const FunctionDecl *);147 // void addFunctionType( const FunctionType * ftype ); 148 148 149 149 private: -
src/Common/utility.h
rc532847 r76d73fc 360 360 reverse_iterate_t( T & ref ) : ref(ref) {} 361 361 362 // this does NOT work on const T!!! 363 // typedef typename T::reverse_iterator iterator; 364 auto begin() { return ref.rbegin(); } 365 auto end() { return ref.rend(); } 362 typedef typename T::reverse_iterator iterator; 363 iterator begin() { return ref.rbegin(); } 364 iterator end() { return ref.rend(); } 366 365 }; 367 366 -
src/GenPoly/GenPoly.cc
rc532847 r76d73fc 46 46 } 47 47 48 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const ast::TypeSubstitution * env) {49 for (auto ¶m : params) {50 auto paramType = param.strict_as<ast::TypeExpr>();51 if (isPolyType(paramType->type, env)) return true;52 }53 return false;54 }55 56 48 /// Checks a parameter list for polymorphic parameters from tyVars; will substitute according to env if present 57 49 bool hasPolyParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) { … … 64 56 } 65 57 66 bool hasPolyParams( const std::vector<ast::ptr<ast::Expr>> & params, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {67 for (auto ¶m : params) {68 auto paramType = param.strict_as<ast::TypeExpr>();69 if (isPolyType(paramType->type, tyVars, env)) return true;70 }71 return false;72 }73 74 58 /// Checks a parameter list for dynamic-layout parameters from tyVars; will substitute according to env if present 75 59 bool hasDynParams( std::list< Expression* >& params, const TyVarMap &tyVars, const TypeSubstitution *env ) { … … 108 92 Type *newType = env->lookup( typeInst->get_name() ); 109 93 if ( newType ) return newType; 110 }111 return type;112 }113 114 const ast::Type * replaceTypeInst(const ast::Type * type, const ast::TypeSubstitution * env) {115 if (!env) return type;116 if (auto typeInst = dynamic_cast<const ast::TypeInstType*> (type)) {117 auto newType = env->lookup(typeInst->name);118 if (newType) return newType;119 94 } 120 95 return type; … … 136 111 } 137 112 138 const ast::Type * isPolyType(const ast::Type * type, const ast::TypeSubstitution * env) {139 type = replaceTypeInst( type, env );140 141 if ( dynamic_cast< const ast::TypeInstType * >( type ) ) {142 return type;143 } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {144 return isPolyType( arrayType->base, env );145 } else if ( auto structType = dynamic_cast< const ast::StructInstType* >( type ) ) {146 if ( hasPolyParams( structType->params, env ) ) return type;147 } else if ( auto unionType = dynamic_cast< const ast::UnionInstType* >( type ) ) {148 if ( hasPolyParams( unionType->params, env ) ) return type;149 }150 return 0;151 }152 153 113 Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env ) { 154 114 type = replaceTypeInst( type, env ); … … 166 126 } 167 127 return 0; 168 }169 170 const ast::Type * isPolyType(const ast::Type * type, const TyVarMap & tyVars, const ast::TypeSubstitution * env) {171 type = replaceTypeInst( type, env );172 173 if ( auto typeInst = dynamic_cast< const ast::TypeInstType * >( type ) ) {174 return tyVars.find(typeInst->name) != tyVars.end() ? type : nullptr;175 } else if ( auto arrayType = dynamic_cast< const ast::ArrayType * >( type ) ) {176 return isPolyType( arrayType->base, env );177 } else if ( auto structType = dynamic_cast< const ast::StructInstType* >( type ) ) {178 if ( hasPolyParams( structType->params, env ) ) return type;179 } else if ( auto unionType = dynamic_cast< const ast::UnionInstType* >( type ) ) {180 if ( hasPolyParams( unionType->params, env ) ) return type;181 }182 return nullptr;183 128 } 184 129 … … 504 449 } 505 450 506 namespace {507 // temporary hack to avoid re-implementing anything related to TyVarMap508 // does this work? these two structs have identical definitions.509 inline TypeDecl::Data convData(const ast::TypeDecl::Data & data) {510 return *reinterpret_cast<const TypeDecl::Data *>(&data);511 }512 }513 514 451 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ) { 515 452 // is parameter is not polymorphic, don't need to box … … 522 459 } 523 460 524 bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TyVarMap &exprTyVars, const ast::TypeSubstitution * env) {525 // is parameter is not polymorphic, don't need to box526 if ( ! isPolyType( param, exprTyVars ) ) return false;527 ast::ptr<ast::Type> newType = arg;528 if ( env ) env->apply( newType );529 // if the argument's type is polymorphic, we don't need to box again!530 return ! isPolyType( newType );531 }532 533 461 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ) { 534 462 FunctionType * function = getFunctionType( appExpr->function->result ); … … 539 467 } 540 468 541 bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * appExpr, const ast::TypeSubstitution * env) {542 const ast::FunctionType * function = getFunctionType(appExpr->func->result);543 assertf( function, "ApplicationExpr has non-function type: %s", toString( appExpr->func->result ).c_str() );544 TyVarMap exprTyVars(TypeDecl::Data{});545 makeTyVarMap(function, exprTyVars);546 return needsBoxing(param, arg, exprTyVars, env);547 548 }549 550 469 void addToTyVarMap( TypeDecl * tyVar, TyVarMap &tyVarMap ) { 551 470 tyVarMap.insert( tyVar->name, TypeDecl::Data{ tyVar } ); 552 }553 554 void addToTyVarMap( const ast::TypeDecl * tyVar, TyVarMap & tyVarMap) {555 tyVarMap.insert(tyVar->name, convData(ast::TypeDecl::Data{tyVar}));556 471 } 557 472 … … 563 478 if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) { 564 479 makeTyVarMap( pointer->get_base(), tyVarMap ); 565 }566 }567 568 void makeTyVarMap(const ast::Type * type, TyVarMap & tyVarMap) {569 if (auto ptype = dynamic_cast<const ast::ParameterizedType *>(type)) {570 for (auto & tyVar : ptype->forall) {571 assert (tyVar);572 addToTyVarMap(tyVar, tyVarMap);573 }574 }575 if (auto pointer = dynamic_cast<const ast::PointerType *>(type)) {576 makeTyVarMap(pointer->base, tyVarMap);577 480 } 578 481 } -
src/GenPoly/GenPoly.h
rc532847 r76d73fc 26 26 27 27 namespace GenPoly { 28 typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap; 28 29 29 typedef ErasableScopedMap< std::string, TypeDecl::Data > TyVarMap;30 30 /// Replaces a TypeInstType by its referrent in the environment, if applicable 31 31 Type* replaceTypeInst( Type* type, const TypeSubstitution* env ); … … 33 33 /// returns polymorphic type if is polymorphic type, NULL otherwise; will look up substitution in env if provided 34 34 Type *isPolyType( Type *type, const TypeSubstitution *env = 0 ); 35 const ast::Type * isPolyType(const ast::Type * type, const ast::TypeSubstitution * env = nullptr);36 35 37 36 /// returns polymorphic type if is polymorphic type in tyVars, NULL otherwise; will look up substitution in env if provided 38 37 Type *isPolyType( Type *type, const TyVarMap &tyVars, const TypeSubstitution *env = 0 ); 39 const ast::Type * isPolyType(const ast::Type * type, const TyVarMap & tyVars, const ast::TypeSubstitution * env = nullptr);40 38 41 39 /// returns dynamic-layout type if is dynamic-layout type in tyVars, NULL otherwise; will look up substitution in env if provided … … 86 84 /// true if arg requires boxing given exprTyVars 87 85 bool needsBoxing( Type * param, Type * arg, const TyVarMap &exprTyVars, const TypeSubstitution * env ); 88 bool needsBoxing( const ast::Type * param, const ast::Type * arg, const TyVarMap &exprTyVars, const ast::TypeSubstitution * env);89 86 90 87 /// true if arg requires boxing in the call to appExpr 91 88 bool needsBoxing( Type * param, Type * arg, ApplicationExpr * appExpr, const TypeSubstitution * env ); 92 bool needsBoxing( const ast::Type * param, const ast::Type * arg, const ast::ApplicationExpr * appExpr, const ast::TypeSubstitution * env);93 89 94 90 /// Adds the type variable `tyVar` to `tyVarMap` … … 97 93 /// Adds the declarations in the forall list of type (and its pointed-to type if it's a pointer type) to `tyVarMap` 98 94 void makeTyVarMap( Type *type, TyVarMap &tyVarMap ); 99 void makeTyVarMap(const ast::Type * type, TyVarMap & tyVarMap);100 95 101 96 /// Prints type variable map -
src/InitTweak/FixGlobalInit.cc
rc532847 r76d73fc 34 34 #include "SynTree/Visitor.h" // for acceptAll, Visitor 35 35 36 #include "AST/Expr.hpp"37 #include "AST/Node.hpp"38 #include "AST/Pass.hpp"39 40 36 namespace InitTweak { 41 37 class GlobalFixer : public WithShortCircuiting { … … 54 50 FunctionDecl * initFunction; 55 51 FunctionDecl * destroyFunction; 56 };57 58 class GlobalFixer_new : public ast::WithShortCircuiting {59 public:60 void previsit (const ast::ObjectDecl *);61 void previsit (const ast::FunctionDecl *) { visit_children = false; }62 void previsit (const ast::StructDecl *) { visit_children = false; }63 void previsit (const ast::UnionDecl *) { visit_children = false; }64 void previsit (const ast::EnumDecl *) { visit_children = false; }65 void previsit (const ast::TraitDecl *) { visit_children = false; }66 void previsit (const ast::TypeDecl *) { visit_children = false; }67 68 std::list< ast::ptr<ast::Stmt> > initStmts;69 std::list< ast::ptr<ast::Stmt> > destroyStmts;70 52 }; 71 53 … … 109 91 } 110 92 111 void fixGlobalInit(std::list<ast::ptr<ast::Decl>> & translationUnit, bool inLibrary) {112 ast::Pass<GlobalFixer_new> fixer;113 accept_all(translationUnit, fixer);114 115 if ( !fixer.core.initStmts.empty() ) {116 std::vector<ast::ptr<ast::Expr>> ctorParams;117 if (inLibrary) ctorParams.emplace_back(ast::ConstantExpr::from_int({}, 200));118 auto initFunction = new ast::FunctionDecl({}, "__global_init__", {}, {}, {}, new ast::CompoundStmt({}, std::move(fixer.core.initStmts)),119 ast::Storage::Static, ast::Linkage::C, {new ast::Attribute("constructor", std::move(ctorParams))});120 121 translationUnit.emplace_back( initFunction );122 } // if123 124 if ( !fixer.core.destroyStmts.empty() ) {125 std::vector<ast::ptr<ast::Expr>> dtorParams;126 if (inLibrary) dtorParams.emplace_back(ast::ConstantExpr::from_int({}, 200));127 auto destroyFunction = new ast::FunctionDecl({}, "__global_destroy__", {}, {}, {}, new ast::CompoundStmt({}, std::move(fixer.core.destroyStmts)),128 ast::Storage::Static, ast::Linkage::C, {new ast::Attribute("destructor", std::move(dtorParams))});129 130 translationUnit.emplace_back(destroyFunction);131 } // if132 }133 134 93 void GlobalFixer::previsit( ObjectDecl *objDecl ) { 135 94 std::list< Statement * > & initStatements = initFunction->get_statements()->get_kids(); … … 168 127 } 169 128 170 void GlobalFixer_new::previsit(const ast::ObjectDecl * objDecl) {171 auto mutDecl = mutate(objDecl);172 assertf(mutDecl == objDecl, "Global object decl must be unique");173 if ( auto ctorInit = objDecl->init.as<ast::ConstructorInit>() ) {174 // a decision should have been made by the resolver, so ctor and init are not both non-NULL175 assert( ! ctorInit->ctor || ! ctorInit->init );176 177 const ast::Stmt * dtor = ctorInit->dtor;178 if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) {179 // don't need to call intrinsic dtor, because it does nothing, but180 // non-intrinsic dtors must be called181 destroyStmts.push_front( dtor );182 // ctorInit->dtor = nullptr;183 } // if184 if ( const ast::Stmt * ctor = ctorInit->ctor ) {185 initStmts.push_back( ctor );186 mutDecl->init = nullptr;187 // ctorInit->ctor = nullptr;188 } else if ( const ast::Init * init = ctorInit->init ) {189 mutDecl->init = init;190 // ctorInit->init = nullptr;191 } else {192 // no constructor and no initializer, which is okay193 mutDecl->init = nullptr;194 } // if195 // delete ctorInit;196 } // if197 }198 199 129 // only modify global variables 200 130 void GlobalFixer::previsit( FunctionDecl * ) { visit_children = false; } -
src/InitTweak/FixGlobalInit.h
rc532847 r76d73fc 19 19 #include <string> // for string 20 20 21 #include <AST/Fwd.hpp>22 23 24 21 class Declaration; 25 22 … … 29 26 /// function is for library code. 30 27 void fixGlobalInit( std::list< Declaration * > & translationUnit, bool inLibrary ); 31 void fixGlobalInit( std::list< ast::ptr<ast::Decl> > & translationUnit, bool inLibrary );32 28 } // namespace 33 29 -
src/InitTweak/FixInit.cc
rc532847 r76d73fc 219 219 }; 220 220 221 struct SplitExpressions : public WithShortCircuiting, /*public WithTypeSubstitution, */public WithStmtsToAdd {221 struct SplitExpressions : public WithShortCircuiting, public WithTypeSubstitution, public WithStmtsToAdd { 222 222 /// add CompoundStmts around top-level expressions so that temporaries are destroyed in the correct places. 223 223 static void split( std::list< Declaration * > &translationUnit ); -
src/InitTweak/FixInit.h
rc532847 r76d73fc 19 19 #include <string> // for string 20 20 21 #include <AST/Fwd.hpp>22 23 21 class Declaration; 24 22 … … 26 24 /// replace constructor initializers with expression statements and unwrap basic C-style initializers 27 25 void fix( std::list< Declaration * > & translationUnit, bool inLibrary ); 28 29 void fix( std::list<ast::ptr<ast::Decl>> & translationUnit, bool inLibrary);30 26 } // namespace 31 27 -
src/InitTweak/GenInit.cc
rc532847 r76d73fc 283 283 assert( stmts.size() <= 1 ); 284 284 return stmts.size() == 1 ? strict_dynamic_cast< ImplicitCtorDtorStmt * >( stmts.front() ) : nullptr; 285 286 }287 288 ast::ptr<ast::Stmt> genCtorDtor (const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * objDecl, const ast::Expr * arg) {289 assertf(objDecl, "genCtorDtor passed null objDecl");290 InitExpander_new srcParam(arg);291 return SymTab::genImplicitCall(srcParam, new ast::VariableExpr(loc, objDecl), loc, fname, objDecl);292 285 } 293 286 -
src/InitTweak/GenInit.h
rc532847 r76d73fc 33 33 /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument 34 34 ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr ); 35 ast::ptr<ast::Stmt> genCtorDtor (const CodeLocation & loc, const std::string & fname, const ast::ObjectDecl * objDecl, const ast::Expr * arg = nullptr);36 35 37 36 /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer -
src/InitTweak/InitTweak.cc
rc532847 r76d73fc 498 498 } 499 499 500 const ast::ObjectDecl * getParamThis(const ast::FunctionDecl * func) {501 assertf( func, "getParamThis: nullptr ftype" );502 auto & params = func->params;503 assertf( ! params.empty(), "getParamThis: ftype with 0 parameters: %s", toString( func ).c_str());504 return params.front().strict_as<ast::ObjectDecl>();505 }506 507 500 bool tryConstruct( DeclarationWithType * dwt ) { 508 501 ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt ); … … 518 511 } 519 512 520 bool tryConstruct( const ast::DeclWithType * dwt ) {521 auto objDecl = dynamic_cast< const ast::ObjectDecl * >( dwt );522 if ( ! objDecl ) return false;523 return (objDecl->init == nullptr ||524 ( objDecl->init != nullptr && objDecl->init->maybeConstructed ))525 && ! objDecl->storage.is_extern526 && isConstructable( objDecl->type );527 }528 529 bool isConstructable( const ast::Type * type ) {530 return ! dynamic_cast< const ast::VarArgsType * >( type ) && ! dynamic_cast< const ast::ReferenceType * >( type )531 && ! dynamic_cast< const ast::FunctionType * >( type ) && ! Tuples::isTtype( type );532 }533 534 513 struct CallFinder_old { 535 514 CallFinder_old( const std::list< std::string > & names ) : names( names ) {} … … 557 536 558 537 struct CallFinder_new final { 559 std::vector< const ast::Expr *> matches;538 std::vector< ast::ptr< ast::Expr > > matches; 560 539 const std::vector< std::string > names; 561 540 … … 579 558 } 580 559 581 std::vector< const ast::Expr *> collectCtorDtorCalls( const ast::Stmt * stmt ) {560 std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt ) { 582 561 ast::Pass< CallFinder_new > finder{ std::vector< std::string >{ "?{}", "^?{}" } }; 583 562 maybe_accept( stmt, finder ); … … 717 696 template <typename Predicate> 718 697 bool allofCtorDtor( const ast::Stmt * stmt, const Predicate & pred ) { 719 std::vector< const ast::Expr *> callExprs = collectCtorDtorCalls( stmt );698 std::vector< ast::ptr< ast::Expr > > callExprs = collectCtorDtorCalls( stmt ); 720 699 return std::all_of( callExprs.begin(), callExprs.end(), pred ); 721 700 } … … 960 939 } 961 940 962 // looks like some other such codegen uses UntypedExpr and does not create fake function. should revisit afterwards963 // following passes may accidentally resolve this expression if returned as untyped...964 ast::Expr * createBitwiseAssignment (const ast::Expr * dst, const ast::Expr * src) {965 static ast::ptr<ast::FunctionDecl> assign = nullptr;966 if (!assign) {967 auto td = new ast::TypeDecl({}, "T", {}, nullptr, ast::TypeDecl::Dtype, true);968 assign = new ast::FunctionDecl({}, "?=?", {},969 { new ast::ObjectDecl({}, "_dst", new ast::ReferenceType(new ast::TypeInstType("T", td))),970 new ast::ObjectDecl({}, "_src", new ast::TypeInstType("T", td))},971 { new ast::ObjectDecl({}, "_ret", new ast::TypeInstType("T", td))}, nullptr, {}, ast::Linkage::Intrinsic);972 }973 if (dst->result.as<ast::ReferenceType>()) {974 for (int depth = dst->result->referenceDepth(); depth > 0; depth--) {975 dst = new ast::AddressExpr(dst);976 }977 }978 else {979 dst = new ast::CastExpr(dst, new ast::ReferenceType(dst->result, {}));980 }981 if (src->result.as<ast::ReferenceType>()) {982 for (int depth = src->result->referenceDepth(); depth > 0; depth--) {983 src = new ast::AddressExpr(src);984 }985 }986 return new ast::ApplicationExpr(dst->location, ast::VariableExpr::functionPointer(dst->location, assign), {dst, src});987 }988 989 941 struct ConstExprChecker : public WithShortCircuiting { 990 942 // most expressions are not const expr -
src/InitTweak/InitTweak.h
rc532847 r76d73fc 38 38 /// returns the first parameter of a constructor/destructor/assignment function 39 39 ObjectDecl * getParamThis( FunctionType * ftype ); 40 const ast::ObjectDecl * getParamThis(const ast::FunctionDecl * func);41 40 42 41 /// generate a bitwise assignment operation. 43 42 ApplicationExpr * createBitwiseAssignment( Expression * dst, Expression * src ); 44 45 ast::Expr * createBitwiseAssignment( const ast::Expr * dst, const ast::Expr * src);46 43 47 44 /// transform Initializer into an argument list that can be passed to a call expression … … 51 48 /// True if the resolver should try to construct dwt 52 49 bool tryConstruct( DeclarationWithType * dwt ); 53 bool tryConstruct( const ast::DeclWithType * dwt );54 50 55 51 /// True if the type can have a user-defined constructor 56 52 bool isConstructable( Type * t ); 57 bool isConstructable( const ast::Type * t );58 53 59 54 /// True if the Initializer contains designations … … 84 79 /// get all Ctor/Dtor call expressions from a Statement 85 80 void collectCtorDtorCalls( Statement * stmt, std::list< Expression * > & matches ); 86 std::vector< const ast::Expr *> collectCtorDtorCalls( const ast::Stmt * stmt );81 std::vector< ast::ptr< ast::Expr > > collectCtorDtorCalls( const ast::Stmt * stmt ); 87 82 88 83 /// get the Ctor/Dtor call expression from a Statement that looks like a generated ctor/dtor call -
src/InitTweak/module.mk
rc532847 r76d73fc 23 23 InitTweak/GenInit.h \ 24 24 InitTweak/InitTweak.cc \ 25 InitTweak/InitTweak.h \ 26 InitTweak/FixInitNew.cpp 25 InitTweak/InitTweak.h 27 26 28 27 SRCDEMANGLE += \ -
src/ResolvExpr/Resolver.cc
rc532847 r76d73fc 1105 1105 } 1106 1106 1107 1108 } // anonymous namespace 1109 /// Establish post-resolver invariants for expressions 1107 /// Establish post-resolver invariants for expressions 1110 1108 void finishExpr( 1111 1109 ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, … … 1120 1118 StripCasts_new::strip( expr ); 1121 1119 } 1120 } // anonymous namespace 1121 1122 1122 1123 1123 ast::ptr< ast::Expr > resolveInVoidContext( … … 1139 1139 } 1140 1140 1141 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1141 namespace { 1142 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1142 1143 /// context. 1143 1144 ast::ptr< ast::Expr > findVoidExpression( … … 1150 1151 return newExpr; 1151 1152 } 1152 1153 namespace {1154 1155 1153 1156 1154 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the … … 1164 1162 CandidateRef choice = 1165 1163 findUnfinishedKindExpression( untyped, symtab, kind, pred, mode ); 1166 ResolvExpr::finishExpr( choice->expr, choice->env, untyped->env );1164 finishExpr( choice->expr, choice->env, untyped->env ); 1167 1165 return std::move( choice->expr ); 1168 1166 } -
src/ResolvExpr/Resolver.h
rc532847 r76d73fc 66 66 ast::ptr< ast::Expr > findSingleExpression( 67 67 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab ); 68 ast::ptr< ast::Expr > findVoidExpression(69 const ast::Expr * untyped, const ast::SymbolTable & symtab);70 68 /// Resolves a constructor init expression 71 69 ast::ptr< ast::Init > resolveCtorInit( -
src/SymTab/Autogen.cc
rc532847 r76d73fc 233 233 } 234 234 235 // shallow copy the pointer list for return236 std::vector<ast::ptr<ast::TypeDecl>> getGenericParams (const ast::Type * t) {237 if (auto structInst = dynamic_cast<const ast::StructInstType*>(t)) {238 return structInst->base->params;239 }240 if (auto unionInst = dynamic_cast<const ast::UnionInstType*>(t)) {241 return unionInst->base->params;242 }243 return {};244 }245 246 235 /// given type T, generate type of default ctor/dtor, i.e. function type void (*) (T *) 247 236 FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic ) { … … 255 244 ftype->parameters.push_back( dstParam ); 256 245 return ftype; 257 }258 259 ///260 ast::FunctionDecl * genDefaultFunc(const CodeLocation loc, const std::string fname, const ast::Type * paramType, bool maybePolymorphic) {261 std::vector<ast::ptr<ast::TypeDecl>> typeParams;262 if (maybePolymorphic) typeParams = getGenericParams(paramType);263 auto dstParam = new ast::ObjectDecl(loc, "_dst", new ast::ReferenceType(paramType), nullptr, {}, ast::Linkage::Cforall);264 return new ast::FunctionDecl(loc, fname, std::move(typeParams), {dstParam}, {}, new ast::CompoundStmt(loc));265 246 } 266 247 -
src/SymTab/Autogen.h
rc532847 r76d73fc 55 55 /// maybePolymorphic is true if the resulting FunctionType is allowed to be polymorphic 56 56 FunctionType * genDefaultType( Type * paramType, bool maybePolymorphic = true ); 57 58 ast::FunctionDecl * genDefaultFunc(const CodeLocation loc, const std::string fname, const ast::Type * paramType, bool maybePolymorphic = true);59 57 60 58 /// generate the type of a copy constructor for paramType. -
src/main.cc
rc532847 r76d73fc 343 343 auto transUnit = convert( move( translationUnit ) ); 344 344 PASS( "Resolve", ResolvExpr::resolve( transUnit ) ); 345 if ( exprp ) {346 translationUnit = convert( move( transUnit ) );347 dump( translationUnit );348 return EXIT_SUCCESS;349 } // if350 351 PASS( "Fix Init", InitTweak::fix(transUnit, buildingLibrary()));352 345 translationUnit = convert( move( transUnit ) ); 353 346 } else { 354 347 PASS( "Resolve", ResolvExpr::resolve( translationUnit ) ); 355 if ( exprp ) {356 dump( translationUnit );357 return EXIT_SUCCESS;358 }359 360 PASS( "Fix Init", InitTweak::fix( translationUnit, buildingLibrary() ) );361 348 } 362 349 350 if ( exprp ) { 351 dump( translationUnit ); 352 return EXIT_SUCCESS; 353 } // if 354 363 355 // fix ObjectDecl - replaces ConstructorInit nodes 356 PASS( "Fix Init", InitTweak::fix( translationUnit, buildingLibrary() ) ); 364 357 if ( ctorinitp ) { 365 358 dump ( translationUnit );
Note:
See TracChangeset
for help on using the changeset viewer.