- Timestamp:
- Nov 4, 2020, 2:56:30 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- eeb5023
- Parents:
- 4b30e8cc (diff), a3f5208a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)links above to see all the changes relative to each parent. - Location:
- src/AST
- Files:
-
- 1 added
- 18 edited
-
Convert.cpp (modified) (22 diffs)
-
Convert.hpp (modified) (1 diff)
-
Decl.cpp (modified) (1 diff)
-
Decl.hpp (modified) (1 diff)
-
DeclReplacer.cpp (modified) (3 diffs)
-
DeclReplacer.hpp (modified) (1 diff)
-
Expr.cpp (modified) (4 diffs)
-
Expr.hpp (modified) (6 diffs)
-
Fwd.hpp (modified) (1 diff)
-
Node.hpp (modified) (1 diff)
-
Pass.hpp (modified) (8 diffs)
-
Pass.impl.hpp (modified) (10 diffs)
-
Pass.proto.hpp (modified) (1 diff)
-
SymbolTable.cpp (modified) (1 diff)
-
SymbolTable.hpp (modified) (1 diff)
-
TranslationUnit.hpp (added)
-
Type.cpp (modified) (1 diff)
-
Type.hpp (modified) (3 diffs)
-
porting.md (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Convert.cpp
r4b30e8cc rc28ea4e 25 25 #include "AST/Init.hpp" 26 26 #include "AST/Stmt.hpp" 27 #include "AST/TranslationUnit.hpp" 27 28 #include "AST/TypeSubstitution.hpp" 28 29 … … 47 48 48 49 //================================================================================================ 49 namespace {50 namespace ast { 50 51 51 52 // This is to preserve the FindSpecialDecls hack. It does not (and perhaps should not) 52 53 // allow us to use the same stratagy in the new ast. 54 // xxx - since convert back pass works, this concern seems to be unnecessary. 55 56 // these need to be accessed in new FixInit now 53 57 ast::Type * sizeType = nullptr; 54 58 ast::FunctionDecl * dereferenceOperator = nullptr; … … 63 67 using Cache = std::unordered_map< const ast::Node *, BaseSyntaxNode * >; 64 68 Cache cache; 69 70 // Statements can no longer be shared. 71 // however, since StmtExprResult is now implemented, need to still maintain 72 // readonly references. 73 Cache readonlyCache; 65 74 66 75 template<typename T> … … 154 163 } 155 164 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 const ast::DeclWithType * visit( const ast::ObjectDecl * node ) override final { 161 166 if ( inCache( node ) ) { 162 167 return nullptr; 163 168 } 169 auto bfwd = get<Expression>().accept1( node->bitfieldWidth ); 170 auto type = get<Type>().accept1( node->type ); 171 auto attr = get<Attribute>().acceptL( node->attributes ); 172 164 173 auto decl = new ObjectDecl( 165 174 node->name, … … 168 177 bfwd, 169 178 type->clone(), 170 init,179 nullptr, // prevent infinite loop 171 180 attr, 172 181 Type::FuncSpecifiers( node->funcSpec.val ) 173 182 ); 174 return declWithTypePostamble( decl, node ); 183 184 // handles the case where node->init references itself 185 // xxx - does it really happen? 186 declWithTypePostamble(decl, node); 187 auto init = get<Initializer>().accept1( node->init ); 188 decl->init = init; 189 190 this->node = decl; 191 return nullptr; 175 192 } 176 193 … … 205 222 decl->statements = get<CompoundStmt>().accept1( node->stmts ); 206 223 decl->withExprs = get<Expression>().acceptL( node->withExprs ); 207 if ( dereferenceOperator == node ) {224 if ( ast::dereferenceOperator == node ) { 208 225 Validate::dereferenceOperator = decl; 209 226 } 210 if ( dtorStructDestroy == node ) {227 if ( ast::dtorStructDestroy == node ) { 211 228 Validate::dtorStructDestroy = decl; 212 229 } … … 267 284 ); 268 285 269 if ( dtorStruct == node ) {286 if ( ast::dtorStruct == node ) { 270 287 Validate::dtorStruct = decl; 271 288 } … … 320 337 321 338 const ast::Stmt * stmtPostamble( Statement * stmt, const ast::Stmt * node ) { 322 cache.emplace( node, stmt ); 339 // force statements in old tree to be unique. 340 // cache.emplace( node, stmt ); 341 readonlyCache.emplace( node, stmt ); 323 342 stmt->location = node->location; 324 343 stmt->labels = makeLabelL( stmt, node->labels ); … … 337 356 if ( inCache( node ) ) return nullptr; 338 357 auto stmt = new ExprStmt( nullptr ); 339 cache.emplace( node, stmt );340 358 stmt->expr = get<Expression>().accept1( node->expr ); 341 359 return stmtPostamble( stmt, node ); … … 1011 1029 auto stmts = node->stmts; 1012 1030 // disable sharing between multiple StmtExprs explicitly. 1013 if (inCache(stmts)) { 1014 stmts = ast::deepCopy(stmts.get()); 1015 } 1031 // this should no longer be true. 1032 1016 1033 auto rslt = new StmtExpr( 1017 1034 get<CompoundStmt>().accept1(stmts) … … 1020 1037 rslt->returnDecls = get<ObjectDecl>().acceptL(node->returnDecls); 1021 1038 rslt->dtors = get<Expression>().acceptL(node->dtors); 1039 if (node->resultExpr) { 1040 // this MUST be found by children visit 1041 rslt->resultExpr = strict_dynamic_cast<ExprStmt *>(readonlyCache.at(node->resultExpr)); 1042 } 1022 1043 1023 1044 auto expr = visitBaseExpr( node, rslt ); … … 1036 1057 1037 1058 auto expr = visitBaseExpr( node, rslt ); 1038 this->node = expr ;1059 this->node = expr->clone(); 1039 1060 return nullptr; 1040 1061 } … … 1126 1147 auto type = new BasicType{ cv( node ), (BasicType::Kind)(unsigned)node->kind }; 1127 1148 // I believe this should always be a BasicType. 1128 if ( sizeType == node ) {1149 if ( ast::sizeType == node ) { 1129 1150 Validate::SizeType = type; 1130 1151 } … … 1384 1405 }; 1385 1406 1386 std::list< Declaration * > convert( const std::list< ast::ptr< ast::Decl > >&& translationUnit ) {1407 std::list< Declaration * > convert( const ast::TranslationUnit && translationUnit ) { 1387 1408 ConverterNewToOld c; 1388 1409 std::list< Declaration * > decls; 1389 for(auto d : translationUnit ) {1410 for(auto d : translationUnit.decls) { 1390 1411 decls.emplace_back( c.decl( d ) ); 1391 1412 } … … 1529 1550 1530 1551 // function type is now derived from parameter decls instead of storing them 1552 1553 /* 1531 1554 auto ftype = new ast::FunctionType((ast::ArgumentFlag)old->type->isVarArgs, cv(old->type)); 1532 1555 ftype->params.reserve(paramVars.size()); … … 1540 1563 } 1541 1564 ftype->forall = std::move(forall); 1542 visitType(old->type, ftype); 1565 */ 1566 1567 // can function type have attributes? seems not to be the case. 1568 // visitType(old->type, ftype); 1543 1569 1544 1570 auto decl = new ast::FunctionDecl{ … … 1546 1572 old->name, 1547 1573 // GET_ACCEPT_1(type, FunctionType), 1574 std::move(forall), 1548 1575 std::move(paramVars), 1549 1576 std::move(returnVars), … … 1552 1579 { old->linkage.val }, 1553 1580 GET_ACCEPT_V(attributes, Attribute), 1554 { old->get_funcSpec().val } 1581 { old->get_funcSpec().val }, 1582 old->type->isVarArgs 1555 1583 }; 1556 1584 1557 decl->type = ftype;1585 // decl->type = ftype; 1558 1586 cache.emplace( old, decl ); 1559 1587 … … 1570 1598 1571 1599 if ( Validate::dereferenceOperator == old ) { 1572 dereferenceOperator = decl;1600 ast::dereferenceOperator = decl; 1573 1601 } 1574 1602 1575 1603 if ( Validate::dtorStructDestroy == old ) { 1576 dtorStructDestroy = decl;1604 ast::dtorStructDestroy = decl; 1577 1605 } 1578 1606 } … … 1599 1627 1600 1628 if ( Validate::dtorStruct == old ) { 1601 dtorStruct = decl;1629 ast::dtorStruct = decl; 1602 1630 } 1603 1631 } … … 2531 2559 // I believe this should always be a BasicType. 2532 2560 if ( Validate::SizeType == old ) { 2533 sizeType = type;2561 ast::sizeType = type; 2534 2562 } 2535 2563 visitType( old, type ); … … 2776 2804 #undef GET_ACCEPT_1 2777 2805 2778 std::list< ast::ptr< ast::Decl > >convert( const std::list< Declaration * > && translationUnit ) {2806 ast::TranslationUnit convert( const std::list< Declaration * > && translationUnit ) { 2779 2807 ConverterOldToNew c; 2780 std::list< ast::ptr< ast::Decl > > decls;2808 ast::TranslationUnit unit; 2781 2809 for(auto d : translationUnit) { 2782 2810 d->accept( c ); 2783 decls.emplace_back( c.decl() );2811 unit.decls.emplace_back( c.decl() ); 2784 2812 } 2785 2813 deleteAll(translationUnit); 2786 return decls;2814 return unit; 2787 2815 } -
src/AST/Convert.hpp
r4b30e8cc rc28ea4e 18 18 #include <list> 19 19 20 #include "AST/Node.hpp"21 22 20 class Declaration; 23 21 namespace ast { 24 class Decl;22 class TranslationUnit; 25 23 }; 26 24 27 std::list< Declaration * > convert( const std::list< ast::ptr< ast::Decl > >&& translationUnit );28 std::list< ast::ptr< ast::Decl > >convert( const std::list< Declaration * > && translationUnit );25 std::list< Declaration * > convert( const ast::TranslationUnit && translationUnit ); 26 ast::TranslationUnit convert( const std::list< Declaration * > && translationUnit ); -
src/AST/Decl.cpp
r4b30e8cc rc28ea4e 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 50 69 51 70 const Type * FunctionDecl::get_type() const { return type.get(); } -
src/AST/Decl.hpp
r4b30e8cc rc28ea4e 131 131 std::vector< ptr<Expr> > withExprs; 132 132 133 FunctionDecl( const CodeLocation & loc, const std::string & name, 133 FunctionDecl( const CodeLocation & loc, const std::string & name, std::vector<ptr<TypeDecl>>&& forall, 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 = {} )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 = {}, bool isVarArgs = false); 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
r4b30e8cc rc28ea4e 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 }; 40 50 } 41 51 … … 54 64 DeclMap declMap; 55 65 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 ); 56 71 } 57 72 … … 88 103 return ninst; 89 104 } 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 90 112 } 91 113 } -
src/AST/DeclReplacer.hpp
r4b30e8cc rc28ea4e 23 23 class DeclWithType; 24 24 class TypeDecl; 25 class Expr; 25 26 26 27 namespace DeclReplacer { 27 28 using DeclMap = std::unordered_map< const DeclWithType *, const DeclWithType * >; 28 29 using TypeMap = std::unordered_map< const TypeDecl *, const TypeDecl * >; 30 using ExprMap = std::unordered_map< const DeclWithType *, const Expr * >; 29 31 30 32 const Node * replace( const Node * node, const DeclMap & declMap, bool debug = false ); 31 33 const Node * replace( const Node * node, const TypeMap & typeMap, bool debug = false ); 32 34 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); 33 36 } 34 37 } -
src/AST/Expr.cpp
r4b30e8cc rc28ea4e 67 67 // --- UntypedExpr 68 68 69 UntypedExpr * UntypedExpr::createDeref( const CodeLocation & loc, Expr * arg ) {69 UntypedExpr * UntypedExpr::createDeref( const CodeLocation & loc, const Expr * arg ) { 70 70 assert( arg ); 71 71 … … 92 92 } 93 93 94 UntypedExpr * UntypedExpr::createAssign( const CodeLocation & loc, Expr * lhs,Expr * rhs ) {94 UntypedExpr * UntypedExpr::createAssign( const CodeLocation & loc, const Expr * lhs, const Expr * rhs ) { 95 95 assert( lhs && rhs ); 96 96 … … 102 102 } 103 103 return ret; 104 } 105 106 // --- VariableExpr 107 108 VariableExpr::VariableExpr( const CodeLocation & loc ) 109 : Expr( loc ), var( nullptr ) {} 110 111 VariableExpr::VariableExpr( const CodeLocation & loc, const DeclWithType * v ) 112 : Expr( loc ), var( v ) { 113 assert( var ); 114 assert( var->get_type() ); 115 result = shallowCopy( var->get_type() ); 116 } 117 118 bool VariableExpr::get_lvalue() const { 119 // It isn't always an lvalue, but it is never an rvalue. 120 return true; 121 } 122 123 VariableExpr * VariableExpr::functionPointer( 124 const CodeLocation & loc, const FunctionDecl * decl ) { 125 // wrap usually-determined result type in a pointer 126 VariableExpr * funcExpr = new VariableExpr{ loc, decl }; 127 funcExpr->result = new PointerType{ funcExpr->result }; 128 return funcExpr; 104 129 } 105 130 … … 238 263 } 239 264 240 // --- VariableExpr241 242 VariableExpr::VariableExpr( const CodeLocation & loc )243 : Expr( loc ), var( nullptr ) {}244 245 VariableExpr::VariableExpr( const CodeLocation & loc, const DeclWithType * v )246 : Expr( loc ), var( v ) {247 assert( var );248 assert( var->get_type() );249 result = shallowCopy( var->get_type() );250 }251 252 bool VariableExpr::get_lvalue() const {253 // It isn't always an lvalue, but it is never an rvalue.254 return true;255 }256 257 VariableExpr * VariableExpr::functionPointer(258 const CodeLocation & loc, const FunctionDecl * decl ) {259 // wrap usually-determined result type in a pointer260 VariableExpr * funcExpr = new VariableExpr{ loc, decl };261 funcExpr->result = new PointerType{ funcExpr->result };262 return funcExpr;263 }264 265 265 // --- ConstantExpr 266 266 -
src/AST/Expr.hpp
r4b30e8cc rc28ea4e 226 226 227 227 /// Creates a new dereference expression 228 static UntypedExpr * createDeref( const CodeLocation & loc, Expr * arg );228 static UntypedExpr * createDeref( const CodeLocation & loc, const Expr * arg ); 229 229 /// Creates a new assignment expression 230 static UntypedExpr * createAssign( const CodeLocation & loc, Expr * lhs,Expr * rhs );230 static UntypedExpr * createAssign( const CodeLocation & loc, const Expr * lhs, const Expr * rhs ); 231 231 232 232 const Expr * accept( Visitor & v ) const override { return v.visit( this ); } … … 247 247 private: 248 248 NameExpr * clone() const override { return new NameExpr{ *this }; } 249 MUTATE_FRIEND 250 }; 251 252 /// A reference to a named variable. 253 class VariableExpr final : public Expr { 254 public: 255 readonly<DeclWithType> var; 256 257 VariableExpr( const CodeLocation & loc ); 258 VariableExpr( const CodeLocation & loc, const DeclWithType * v ); 259 260 bool get_lvalue() const final; 261 262 /// generates a function pointer for a given function 263 static VariableExpr * functionPointer( const CodeLocation & loc, const FunctionDecl * decl ); 264 265 const Expr * accept( Visitor & v ) const override { return v.visit( this ); } 266 private: 267 VariableExpr * clone() const override { return new VariableExpr{ *this }; } 249 268 MUTATE_FRIEND 250 269 }; … … 392 411 }; 393 412 394 /// A reference to a named variable.395 class VariableExpr final : public Expr {396 public:397 readonly<DeclWithType> var;398 399 VariableExpr( const CodeLocation & loc );400 VariableExpr( const CodeLocation & loc, const DeclWithType * v );401 402 bool get_lvalue() const final;403 404 /// generates a function pointer for a given function405 static VariableExpr * functionPointer( const CodeLocation & loc, const FunctionDecl * decl );406 407 const Expr * accept( Visitor & v ) const override { return v.visit( this ); }408 private:409 VariableExpr * clone() const override { return new VariableExpr{ *this }; }410 MUTATE_FRIEND411 };412 413 413 /// A compile-time constant. 414 414 /// Mostly carries C-source text from parse to code-gen, without interpretation. E.g. strings keep their outer quotes and never have backslashes interpreted. … … 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 ) {}424 : Expr( loc, ty ), rep( r ), ival( i ), underlyer(ty) {} 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 ) { assert( call); }619 : Expr( loc, call->result ), callExpr(call) { assert( call ); assert(call->result); } 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 744 746 StmtExpr( const CodeLocation & loc, const CompoundStmt * ss ); 745 747 -
src/AST/Fwd.hpp
r4b30e8cc rc28ea4e 137 137 typedef unsigned int UniqueId; 138 138 139 class TranslationUnit; 140 // TODO: Get from the TranslationUnit: 141 extern Type * sizeType; 142 extern FunctionDecl * dereferenceOperator; 143 extern StructDecl * dtorStruct; 144 extern FunctionDecl * dtorStructDestroy; 145 139 146 } -
src/AST/Node.hpp
r4b30e8cc rc28ea4e 49 49 50 50 bool unique() const { return strong_count == 1; } 51 bool isManaged() const {return strong_count > 0; } 51 52 52 53 private: -
src/AST/Pass.hpp
r4b30e8cc rc28ea4e 103 103 /// Construct and run a pass on a translation unit. 104 104 template< typename... Args > 105 static void run( std::list< ptr<Decl> >& decls, Args &&... args ) {105 static void run( TranslationUnit & decls, Args &&... args ) { 106 106 Pass<core_t> visitor( std::forward<Args>( args )... ); 107 107 accept_all( decls, visitor ); … … 119 119 // Versions of the above for older compilers. 120 120 template< typename... Args > 121 static void run( std::list< ptr<Decl> >& decls ) {121 static void run( TranslationUnit & decls ) { 122 122 Pass<core_t> visitor; 123 123 accept_all( decls, visitor ); … … 228 228 template<typename core_type> 229 229 friend void accept_all( std::list< ptr<Decl> > & decls, Pass<core_type>& visitor ); 230 231 bool isInFunction() const { 232 return inFunction; 233 } 234 230 235 private: 231 236 … … 235 240 const ast::Stmt * call_accept( const ast::Stmt * ); 236 241 const ast::Expr * call_accept( const ast::Expr * ); 242 243 // requests WithStmtsToAdd directly add to this statement, as if it is a compound. 244 245 const ast::Stmt * call_accept_as_compound(const ast::Stmt *); 237 246 238 247 template< typename node_t > … … 257 266 template<typename node_t, typename parent_t, typename child_t> 258 267 void maybe_accept(const node_t * &, child_t parent_t::* child); 268 269 template<typename node_t, typename parent_t, typename child_t> 270 void maybe_accept_as_compound(const node_t * &, child_t parent_t::* child); 259 271 260 272 private: … … 284 296 private: 285 297 bool inFunction = false; 298 bool atFunctionTop = false; 286 299 }; 287 300 … … 289 302 template<typename core_t> 290 303 void accept_all( std::list< ast::ptr<ast::Decl> > &, ast::Pass<core_t> & visitor ); 304 305 template<typename core_t> 306 void accept_all( ast::TranslationUnit &, ast::Pass<core_t> & visitor ); 291 307 292 308 //------------------------------------------------------------------------------------------------- … … 371 387 struct WithVisitorRef { 372 388 Pass<core_t> * const visitor = nullptr; 389 390 bool isInFunction() const { 391 return visitor->isInFunction(); 392 } 373 393 }; 374 394 -
src/AST/Pass.impl.hpp
r4b30e8cc rc28ea4e 20 20 #include <unordered_map> 21 21 22 #include "AST/TranslationUnit.hpp" 22 23 #include "AST/TypeSubstitution.hpp" 23 24 … … 167 168 __pedantic_pass_assert( stmt ); 168 169 170 return stmt->accept( *this ); 171 } 172 173 template< typename core_t > 174 const ast::Stmt * ast::Pass< core_t >::call_accept_as_compound( const ast::Stmt * stmt ) { 175 __pedantic_pass_assert( __visit_children() ); 176 __pedantic_pass_assert( stmt ); 177 169 178 // add a few useful symbols to the scope 170 179 using __pass::empty; … … 334 343 } 335 344 345 template< typename core_t > 346 template<typename node_t, typename parent_t, typename child_t> 347 void ast::Pass< core_t >::maybe_accept_as_compound( 348 const node_t * & parent, 349 child_t parent_t::*child 350 ) { 351 static_assert( std::is_base_of<parent_t, node_t>::value, "Error deducing member object" ); 352 353 if(__pass::skip(parent->*child)) return; 354 const auto & old_val = __pass::get(parent->*child, 0); 355 356 static_assert( !std::is_same<const ast::Node * &, decltype(old_val)>::value, "ERROR"); 357 358 auto new_val = call_accept_as_compound( old_val ); 359 360 static_assert( !std::is_same<const ast::Node *, decltype(new_val)>::value || std::is_same<int, decltype(old_val)>::value, "ERROR"); 361 362 if( __pass::differs(old_val, new_val) ) { 363 auto new_parent = __pass::mutate<core_t>(parent); 364 new_parent->*child = new_val; 365 parent = new_parent; 366 } 367 } 368 336 369 337 370 template< typename core_t > … … 398 431 pass_visitor_stats.depth--; 399 432 if ( !errors.isEmpty() ) { throw errors; } 433 } 434 435 template< typename core_t > 436 inline void ast::accept_all( ast::TranslationUnit & unit, ast::Pass< core_t > & visitor ) { 437 return ast::accept_all( unit.decls, visitor ); 400 438 } 401 439 … … 470 508 // foralls are still in function type 471 509 maybe_accept( node, &FunctionDecl::type ); 472 // function body needs to have the same scope as parameters - CompoundStmt will not enter 473 // a new scope if inFunction is true 510 // First remember that we are now within a function. 474 511 ValueGuard< bool > oldInFunction( inFunction ); 475 512 inFunction = true; 513 // The function body needs to have the same scope as parameters. 514 // A CompoundStmt will not enter a new scope if atFunctionTop is true. 515 ValueGuard< bool > oldAtFunctionTop( atFunctionTop ); 516 atFunctionTop = true; 476 517 maybe_accept( node, &FunctionDecl::stmts ); 477 518 maybe_accept( node, &FunctionDecl::attributes ); … … 639 680 const ast::CompoundStmt * ast::Pass< core_t >::visit( const ast::CompoundStmt * node ) { 640 681 VISIT_START( node ); 641 VISIT( {642 // do not enter a new scope if inFunction is true - needs to check old state before the assignment643 auto guard1 = makeFuncGuard( [this, inFunctionCpy = this->inFunction]() {644 if ( ! inFunctionCpy) __pass::symtab::enter(core, 0);645 }, [this, inFunctionCpy = this->inFunction]() {646 if ( ! inFunctionCpy) __pass::symtab::leave(core, 0);682 VISIT( 683 // Do not enter (or leave) a new scope if atFunctionTop. Remember to save the result. 684 auto guard1 = makeFuncGuard( [this, enterScope = !this->atFunctionTop]() { 685 if ( enterScope ) __pass::symtab::enter(core, 0); 686 }, [this, leaveScope = !this->atFunctionTop]() { 687 if ( leaveScope ) __pass::symtab::leave(core, 0); 647 688 }); 648 ValueGuard< bool > guard2( inFunction ); 689 ValueGuard< bool > guard2( atFunctionTop ); 690 atFunctionTop = false; 649 691 guard_scope guard3 { *this }; 650 inFunction = false;651 692 maybe_accept( node, &CompoundStmt::kids ); 652 })693 ) 653 694 VISIT_END( CompoundStmt, node ); 654 695 } … … 703 744 maybe_accept( node, &IfStmt::inits ); 704 745 maybe_accept( node, &IfStmt::cond ); 705 maybe_accept ( node, &IfStmt::thenPart );706 maybe_accept ( node, &IfStmt::elsePart );746 maybe_accept_as_compound( node, &IfStmt::thenPart ); 747 maybe_accept_as_compound( node, &IfStmt::elsePart ); 707 748 }) 708 749 … … 721 762 maybe_accept( node, &WhileStmt::inits ); 722 763 maybe_accept( node, &WhileStmt::cond ); 723 maybe_accept ( node, &WhileStmt::body );764 maybe_accept_as_compound( node, &WhileStmt::body ); 724 765 }) 725 766 … … 736 777 // for statements introduce a level of scope (for the initialization) 737 778 guard_symtab guard { *this }; 779 // xxx - old ast does not create WithStmtsToAdd scope for loop inits. should revisit this later. 738 780 maybe_accept( node, &ForStmt::inits ); 739 781 maybe_accept( node, &ForStmt::cond ); 740 782 maybe_accept( node, &ForStmt::inc ); 741 maybe_accept ( node, &ForStmt::body );783 maybe_accept_as_compound( node, &ForStmt::body ); 742 784 }) 743 785 … … 834 876 maybe_accept( node, &CatchStmt::decl ); 835 877 maybe_accept( node, &CatchStmt::cond ); 836 maybe_accept ( node, &CatchStmt::body );878 maybe_accept_as_compound( node, &CatchStmt::body ); 837 879 }) 838 880 -
src/AST/Pass.proto.hpp
r4b30e8cc rc28ea4e 22 22 template<typename core_t> 23 23 class Pass; 24 25 class TranslationUnit; 24 26 25 27 struct PureVisitor; -
src/AST/SymbolTable.cpp
r4b30e8cc rc28ea4e 335 335 } 336 336 337 /* 338 void SymbolTable::addFunction Type( const FunctionType * ftype) {339 addTypes( f type->forall );340 addIds( f type->returns );341 addIds( f type->params );342 } 343 */ 337 338 void SymbolTable::addFunction( const FunctionDecl * func ) { 339 addTypes( func->type->forall ); 340 addIds( func->returns ); 341 addIds( func->params ); 342 } 343 344 344 345 345 void SymbolTable::lazyInitScope() { -
src/AST/SymbolTable.hpp
r4b30e8cc rc28ea4e 145 145 146 146 /// convenience function for adding all of the declarations in a function type to the indexer 147 // void addFunctionType( const FunctionType * ftype);147 void addFunction( const FunctionDecl * ); 148 148 149 149 private: -
src/AST/Type.cpp
r4b30e8cc rc28ea4e 157 157 158 158 template<typename decl_t> 159 SueInstType<decl_t>::SueInstType( 160 const base_type * b, std::vector<ptr<Expr>> && params, 161 CV::Qualifiers q, std::vector<ptr<Attribute>> && as ) 162 : BaseInstType( b->name, std::move(params), q, std::move(as) ), base( b ) {} 163 164 template<typename decl_t> 159 165 bool SueInstType<decl_t>::isComplete() const { 160 166 return base ? base->body : false; -
src/AST/Type.hpp
r4b30e8cc rc28ea4e 302 302 class FunctionType final : public ParameterizedType { 303 303 public: 304 // std::vector<ptr<DeclWithType>> returns;305 // std::vector<ptr<DeclWithType>> params;306 307 304 std::vector<ptr<Type>> returns; 308 305 std::vector<ptr<Type>> params; … … 345 342 : ParameterizedType(q, std::move(as)), params(), name(n) {} 346 343 344 BaseInstType( 345 const std::string& n, std::vector<ptr<Expr>> && params, 346 CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ) 347 : ParameterizedType(q, std::move(as)), params(std::move(params)), name(n) {} 348 347 349 BaseInstType( const BaseInstType & o ); 348 350 … … 369 371 370 372 SueInstType( 371 const decl_t * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 373 const base_type * b, CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 374 375 SueInstType( 376 const base_type * b, std::vector<ptr<Expr>> && params, 377 CV::Qualifiers q = {}, std::vector<ptr<Attribute>> && as = {} ); 372 378 373 379 bool isComplete() const override; -
src/AST/porting.md
r4b30e8cc rc28ea4e 30 30 * Base nodes now override `const Node * accept( Visitor & v ) const = 0` with, e.g. `const Stmt * accept( Visitor & v ) const override = 0` 31 31 * `PassVisitor` is replaced with `ast::Pass` 32 * Most one shot uses can use `ast::Pass::run` and `ast::Pass::read`. 33 34 `WithConstTypeSubstitution` 35 * `env` => `typeSubs` 32 36 33 37 ## Structural Changes ## … … 146 150 * allows `newObject` as just default settings 147 151 152 `FunctionDecl` 153 * `params` and `returns` added. 154 * Contain the declarations of the parameters and return variables. 155 * Types should match (even be shared with) the fields of `type`. 156 148 157 `NamedTypeDecl` 149 158 * `parameters` => `params` … … 154 163 `AggregateDecl` 155 164 * `parameters` => `params` 165 166 `StructDecl` 167 * `makeInst` replaced by better constructor on `StructInstType`. 156 168 157 169 `Expr` … … 245 257 * **TODO** move `kind`, `typeNames` into code generator 246 258 247 `ReferenceToType` 259 `ReferenceToType` => `BaseInstType` 248 260 * deleted `get_baseParameters()` from children 249 261 * replace with `aggr() ? aggr()->params : nullptr` … … 261 273 * `returnVals` => `returns` 262 274 * `parameters` => `params` 275 * Both now just point at types. 263 276 * `bool isVarArgs;` => `enum ArgumentFlag { FixedArgs, VariableArgs }; ArgumentFlag isVarArgs;` 277 278 `SueInstType` 279 * Template class, with specializations and using to implement some other types: 280 * `StructInstType`, `UnionInstType` & `EnumInstType` 264 281 265 282 `TypeInstType`
Note:
See TracChangeset
for help on using the changeset viewer.