Changes in / [c6a1e8a:67130fe]
- Location:
- src
- Files:
-
- 5 deleted
- 23 edited
-
AST/Bitfield.hpp (modified) (2 diffs)
-
AST/Chain.hpp (deleted)
-
AST/Convert.cpp (modified) (3 diffs)
-
AST/Decl.hpp (modified) (1 diff)
-
AST/Node.cpp (modified) (1 diff)
-
AST/Node.hpp (modified) (4 diffs)
-
AST/Pass.hpp (modified) (4 diffs)
-
AST/Pass.impl.hpp (modified) (61 diffs)
-
AST/Pass.proto.hpp (modified) (9 diffs)
-
AST/Print.hpp (modified) (1 diff)
-
AST/SymbolTable.hpp (modified) (2 diffs)
-
AST/porting.md (modified) (2 diffs)
-
Common/Indenter.h (modified) (1 diff)
-
InitTweak/FixInit.cc (modified) (1 diff)
-
Makefile.in (modified) (4 diffs)
-
ResolvExpr/AlternativeFinder.cc (modified) (1 diff)
-
ResolvExpr/Candidate.cpp (deleted)
-
ResolvExpr/Candidate.hpp (deleted)
-
ResolvExpr/CandidateFinder.cpp (deleted)
-
ResolvExpr/CandidateFinder.hpp (deleted)
-
ResolvExpr/ResolveAssertions.cc (modified) (2 diffs)
-
ResolvExpr/Resolver.cc (modified) (29 diffs)
-
ResolvExpr/module.mk (modified) (1 diff)
-
ResolvExpr/typeops.h (modified) (1 diff)
-
SynTree/BaseSyntaxNode.h (modified) (1 diff)
-
SynTree/DeclReplacer.cc (modified) (6 diffs)
-
SynTree/DeclReplacer.h (modified) (1 diff)
-
main.cc (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Bitfield.hpp
rc6a1e8a r67130fe 9 9 // Author : Aaron B. Moss 10 10 // Created On : Thu May 9 10:00:00 2019 11 // Last Modified By : A ndrew Beach12 // Last Modified On : Wed Jun 510:00:00 201913 // Update Count : 211 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Thu May 9 10:00:00 2019 13 // Update Count : 1 14 14 // 15 15 16 16 #pragma once 17 17 18 #include <strings.h> // for ffs 19 #include <type_traits> // for is_unsigned 18 #include <strings.h> // for ffs 20 19 21 20 /// Make a type a bitfield. … … 25 24 template<typename T> 26 25 struct bitfield : public T { 26 static_assert(sizeof(T) == sizeof(unsigned int), "Type has incorrect size"); 27 27 using T::val; 28 28 using val_t = decltype(val); 29 static_assert(sizeof(T) == sizeof(unsigned int), "Type has incorrect size");30 static_assert(std::is_unsigned<val_t>::value, "Bitfield val field is not unsigned.");31 29 32 30 constexpr bitfield() : T( 0 ) {} -
src/AST/Convert.cpp
rc6a1e8a r67130fe 749 749 break; 750 750 case ast::ConstantExpr::String: 751 rslt = new ConstantExpr{Constant{ 752 get<Type>().accept1( node->result ), 753 node->rep, 754 (long long unsigned int)0 755 }}; 751 rslt = new ConstantExpr{Constant::from_string( node->rep )}; 756 752 break; 757 753 } … … 2154 2150 GET_ACCEPT_1(result, Type), 2155 2151 old->constant.get_value(), 2156 (unsigned long long) old->intValue(), 2157 ast::ConstantExpr::Kind::Integer 2152 (unsigned long long) old->intValue() 2158 2153 ); 2159 2154 } else if (isFloatlikeConstantType(old->result)) { … … 2165 2160 ); 2166 2161 } else if (isStringlikeConstantType(old->result)) { 2167 rslt = new ast::ConstantExpr( 2168 old->location, 2169 GET_ACCEPT_1(result, Type), 2170 old->constant.get_value(), 2171 0, 2172 ast::ConstantExpr::Kind::String 2162 rslt = ast::ConstantExpr::from_string( 2163 old->location, 2164 old->constant.get_value() 2173 2165 ); 2174 2166 } -
src/AST/Decl.hpp
rc6a1e8a r67130fe 103 103 104 104 ObjectDecl( const CodeLocation & loc, const std::string & name, const Type * type, 105 const Init * init = nullptr, Storage::Classes storage = {},106 Linkage::Spec linkage = Linkage::C, const Expr * bitWd = nullptr,107 std::vector< ptr<Attribute> > && attrs = {},Function::Specs fs = {} )105 Init * init = nullptr, Storage::Classes storage = {}, Linkage::Spec linkage = Linkage::C, 106 Expr * bitWd = nullptr, std::vector< ptr<Attribute> > && attrs = {}, 107 Function::Specs fs = {} ) 108 108 : DeclWithType( loc, name, storage, linkage, std::move(attrs), fs ), type( type ), 109 109 init( init ), bitfieldWidth( bitWd ) {} -
src/AST/Node.cpp
rc6a1e8a r67130fe 34 34 template< typename node_t, enum ast::Node::ref_type ref_t > 35 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); }39 36 40 37 template< typename node_t, enum ast::Node::ref_type ref_t > -
src/AST/Node.hpp
rc6a1e8a r67130fe 46 46 }; 47 47 48 bool unique() const { return strong_count == 1; }49 50 48 private: 51 49 /// Make a copy of this node; should be overridden in subclass with more precise return type … … 58 56 mutable size_t strong_count = 0; 59 57 mutable size_t weak_count = 0; 60 mutable bool was_ever_strong = false;61 58 62 59 void increment(ref_type ref) const { 63 60 switch (ref) { 64 case ref_type::strong: strong_count++; was_ever_strong = true;break;61 case ref_type::strong: strong_count++; break; 65 62 case ref_type::weak : weak_count ++; break; 66 63 } … … 179 176 } 180 177 181 const node_t * get() const { _check();return node; }182 const node_t * operator->() const { _check();return node; }183 const node_t & operator* () const { _check();return *node; }184 explicit operator bool() const { _check();return node; }185 operator const node_t * () const { _check();return node; }178 const node_t * get() const { return node; } 179 const node_t * operator->() const { return node; } 180 const node_t & operator* () const { return *node; } 181 explicit operator bool() const { return node; } 182 operator const node_t * () const { return node; } 186 183 187 184 /// wrapper for convenient access to dynamic_cast 188 185 template<typename o_node_t> 189 const o_node_t * as() const { _check();return dynamic_cast<const o_node_t *>(node); }186 const o_node_t * as() const { return dynamic_cast<const o_node_t *>(node); } 190 187 191 188 /// wrapper for convenient access to strict_dynamic_cast … … 211 208 void _inc( const node_t * other ); 212 209 void _dec( const node_t * other ); 213 void _check() const;214 210 215 211 protected: -
src/AST/Pass.hpp
rc6a1e8a r67130fe 33 33 #include "AST/Visitor.hpp" 34 34 35 #include " AST/SymbolTable.hpp"35 #include "SymTab/Indexer.h" 36 36 37 37 // Private prelude header, needed for some of the magic tricks this class pulls off … … 61 61 // postvisit/postmutate teminates. 62 62 // | WithVisitorRef - provides an pointer to the templated visitor wrapper 63 // | With SymbolTable - provides symbol table functionality63 // | WithIndexer - provides indexer functionality (i.e. up-to-date symbol table) 64 64 //------------------------------------------------------------------------------------------------- 65 65 template< typename pass_t > … … 206 206 207 207 private: 208 /// Internal RAII guard for symbol tablefeatures209 struct guard_ symtab{210 guard_ symtab( Pass<pass_t> & pass ): pass( pass ) { __pass::symtab::enter(pass, 0); }211 ~guard_ symtab() { __pass::symtab::leave(pass, 0); }208 /// Internal RAII guard for indexer features 209 struct guard_indexer { 210 guard_indexer( Pass<pass_t> & pass ): pass( pass ) { __pass::indexer::enter(pass, 0); } 211 ~guard_indexer() { __pass::indexer::leave(pass, 0); } 212 212 Pass<pass_t> & pass; 213 213 }; … … 294 294 }; 295 295 296 /// Use when the templated visitor should update the symbol table297 struct With SymbolTable{298 Sym bolTable symtab;296 /// Use when the templated visitor should update the indexer 297 struct WithIndexer { 298 SymTab::Indexer indexer; 299 299 }; 300 300 } -
src/AST/Pass.impl.hpp
rc6a1e8a r67130fe 398 398 VISIT( 399 399 { 400 guard_ symtabguard { *this };400 guard_indexer guard { *this }; 401 401 maybe_accept( node, &ObjectDecl::type ); 402 402 } … … 406 406 ) 407 407 408 __pass:: symtab::addId( pass, 0, node );408 __pass::indexer::addId( pass, 0, node ); 409 409 410 410 VISIT_END( DeclWithType, node ); … … 417 417 VISIT_START( node ); 418 418 419 __pass:: symtab::addId( pass, 0, node );419 __pass::indexer::addId( pass, 0, node ); 420 420 421 421 VISIT(maybe_accept( node, &FunctionDecl::withExprs );) 422 422 { 423 423 // with clause introduces a level of scope (for the with expression members). 424 // with clause exprs are added to the symbol tablebefore parameters so that parameters424 // with clause exprs are added to the indexer before parameters so that parameters 425 425 // shadow with exprs and not the other way around. 426 guard_ symtabguard { *this };427 __pass:: symtab::addWith( pass, 0, node->withExprs, node );426 guard_indexer guard { *this }; 427 __pass::indexer::addWith( pass, 0, node->withExprs, node ); 428 428 { 429 guard_ symtabguard { *this };429 guard_indexer guard { *this }; 430 430 // implicit add __func__ identifier as specified in the C manual 6.4.2.2 431 431 static ast::ObjectDecl func( … … 436 436 ) 437 437 ); 438 __pass:: symtab::addId( pass, 0, &func );438 __pass::indexer::addId( pass, 0, &func ); 439 439 VISIT( 440 440 maybe_accept( node, &FunctionDecl::type ); … … 460 460 // make up a forward declaration and add it before processing the members 461 461 // needs to be on the heap because addStruct saves the pointer 462 __pass:: symtab::addStructFwd( pass, 0, node );463 464 VISIT({ 465 guard_ symtabguard { * this };462 __pass::indexer::addStructFwd( pass, 0, node ); 463 464 VISIT({ 465 guard_indexer guard { * this }; 466 466 maybe_accept( node, &StructDecl::params ); 467 467 maybe_accept( node, &StructDecl::members ); … … 469 469 470 470 // this addition replaces the forward declaration 471 __pass:: symtab::addStruct( pass, 0, node );471 __pass::indexer::addStruct( pass, 0, node ); 472 472 473 473 VISIT_END( Decl, node ); … … 481 481 482 482 // make up a forward declaration and add it before processing the members 483 __pass:: symtab::addUnionFwd( pass, 0, node );484 485 VISIT({ 486 guard_ symtabguard { * this };483 __pass::indexer::addUnionFwd( pass, 0, node ); 484 485 VISIT({ 486 guard_indexer guard { * this }; 487 487 maybe_accept( node, &UnionDecl::params ); 488 488 maybe_accept( node, &UnionDecl::members ); 489 489 }) 490 490 491 __pass:: symtab::addUnion( pass, 0, node );491 __pass::indexer::addUnion( pass, 0, node ); 492 492 493 493 VISIT_END( Decl, node ); … … 500 500 VISIT_START( node ); 501 501 502 __pass:: symtab::addEnum( pass, 0, node );502 __pass::indexer::addEnum( pass, 0, node ); 503 503 504 504 VISIT( … … 518 518 519 519 VISIT({ 520 guard_ symtabguard { *this };520 guard_indexer guard { *this }; 521 521 maybe_accept( node, &TraitDecl::params ); 522 522 maybe_accept( node, &TraitDecl::members ); 523 523 }) 524 524 525 __pass:: symtab::addTrait( pass, 0, node );525 __pass::indexer::addTrait( pass, 0, node ); 526 526 527 527 VISIT_END( Decl, node ); … … 535 535 536 536 VISIT({ 537 guard_ symtabguard { *this };537 guard_indexer guard { *this }; 538 538 maybe_accept( node, &TypeDecl::params ); 539 539 maybe_accept( node, &TypeDecl::base ); … … 543 543 // note that assertions come after the type is added to the symtab, since they are not part of the type proper 544 544 // and may depend on the type itself 545 __pass:: symtab::addType( pass, 0, node );545 __pass::indexer::addType( pass, 0, node ); 546 546 547 547 VISIT( … … 549 549 550 550 { 551 guard_ symtabguard { *this };551 guard_indexer guard { *this }; 552 552 maybe_accept( node, &TypeDecl::init ); 553 553 } … … 564 564 565 565 VISIT({ 566 guard_ symtabguard { *this };566 guard_indexer guard { *this }; 567 567 maybe_accept( node, &TypedefDecl::params ); 568 568 maybe_accept( node, &TypedefDecl::base ); 569 569 }) 570 570 571 __pass:: symtab::addType( pass, 0, node );571 __pass::indexer::addType( pass, 0, node ); 572 572 573 573 VISIT( maybe_accept( node, &TypedefDecl::assertions ); ) … … 611 611 // do not enter a new scope if inFunction is true - needs to check old state before the assignment 612 612 auto guard1 = makeFuncGuard( [this, inFunction = this->inFunction]() { 613 if ( ! inFunction ) __pass:: symtab::enter(pass, 0);613 if ( ! inFunction ) __pass::indexer::enter(pass, 0); 614 614 }, [this, inFunction = this->inFunction]() { 615 if ( ! inFunction ) __pass:: symtab::leave(pass, 0);615 if ( ! inFunction ) __pass::indexer::leave(pass, 0); 616 616 }); 617 617 ValueGuard< bool > guard2( inFunction ); … … 669 669 VISIT({ 670 670 // if statements introduce a level of scope (for the initialization) 671 guard_ symtabguard { *this };671 guard_indexer guard { *this }; 672 672 maybe_accept( node, &IfStmt::inits ); 673 673 maybe_accept( node, &IfStmt::cond ); … … 687 687 VISIT({ 688 688 // while statements introduce a level of scope (for the initialization) 689 guard_ symtabguard { *this };689 guard_indexer guard { *this }; 690 690 maybe_accept( node, &WhileStmt::inits ); 691 691 maybe_accept( node, &WhileStmt::cond ); … … 704 704 VISIT({ 705 705 // for statements introduce a level of scope (for the initialization) 706 guard_ symtabguard { *this };706 guard_indexer guard { *this }; 707 707 maybe_accept( node, &ForStmt::inits ); 708 708 maybe_accept( node, &ForStmt::cond ); … … 800 800 VISIT({ 801 801 // catch statements introduce a level of scope (for the caught exception) 802 guard_ symtabguard { *this };802 guard_indexer guard { *this }; 803 803 maybe_accept( node, &CatchStmt::decl ); 804 804 maybe_accept( node, &CatchStmt::cond ); … … 901 901 { 902 902 // catch statements introduce a level of scope (for the caught exception) 903 guard_ symtabguard { *this };904 __pass:: symtab::addWith( pass, 0, node->exprs, node );903 guard_indexer guard { *this }; 904 __pass::indexer::addWith( pass, 0, node->exprs, node ); 905 905 maybe_accept( node, &WithStmt::stmt ); 906 906 } … … 953 953 VISIT( 954 954 { 955 guard_ symtabguard { *this };955 guard_indexer guard { *this }; 956 956 maybe_accept( node, &ApplicationExpr::result ); 957 957 } … … 971 971 VISIT( 972 972 { 973 guard_ symtabguard { *this };973 guard_indexer guard { *this }; 974 974 maybe_accept( node, &UntypedExpr::result ); 975 975 } … … 988 988 989 989 VISIT({ 990 guard_ symtabguard { *this };990 guard_indexer guard { *this }; 991 991 maybe_accept( node, &NameExpr::result ); 992 992 }) … … 1002 1002 1003 1003 VISIT({ 1004 guard_ symtabguard { *this };1004 guard_indexer guard { *this }; 1005 1005 maybe_accept( node, &CastExpr::result ); 1006 1006 } … … 1018 1018 1019 1019 VISIT({ 1020 guard_ symtabguard { *this };1020 guard_indexer guard { *this }; 1021 1021 maybe_accept( node, &KeywordCastExpr::result ); 1022 1022 } … … 1034 1034 1035 1035 VISIT({ 1036 guard_ symtabguard { *this };1036 guard_indexer guard { *this }; 1037 1037 maybe_accept( node, &VirtualCastExpr::result ); 1038 1038 } … … 1050 1050 1051 1051 VISIT({ 1052 guard_ symtabguard { *this };1052 guard_indexer guard { *this }; 1053 1053 maybe_accept( node, &AddressExpr::result ); 1054 1054 } … … 1066 1066 1067 1067 VISIT({ 1068 guard_ symtabguard { *this };1068 guard_indexer guard { *this }; 1069 1069 maybe_accept( node, &LabelAddressExpr::result ); 1070 1070 }) … … 1080 1080 1081 1081 VISIT({ 1082 guard_ symtabguard { *this };1082 guard_indexer guard { *this }; 1083 1083 maybe_accept( node, &UntypedMemberExpr::result ); 1084 1084 } … … 1097 1097 1098 1098 VISIT({ 1099 guard_ symtabguard { *this };1099 guard_indexer guard { *this }; 1100 1100 maybe_accept( node, &MemberExpr::result ); 1101 1101 } … … 1113 1113 1114 1114 VISIT({ 1115 guard_ symtabguard { *this };1115 guard_indexer guard { *this }; 1116 1116 maybe_accept( node, &VariableExpr::result ); 1117 1117 }) … … 1127 1127 1128 1128 VISIT({ 1129 guard_ symtabguard { *this };1129 guard_indexer guard { *this }; 1130 1130 maybe_accept( node, &ConstantExpr::result ); 1131 1131 }) … … 1141 1141 1142 1142 VISIT({ 1143 guard_ symtabguard { *this };1143 guard_indexer guard { *this }; 1144 1144 maybe_accept( node, &SizeofExpr::result ); 1145 1145 } … … 1161 1161 1162 1162 VISIT({ 1163 guard_ symtabguard { *this };1163 guard_indexer guard { *this }; 1164 1164 maybe_accept( node, &AlignofExpr::result ); 1165 1165 } … … 1181 1181 1182 1182 VISIT({ 1183 guard_ symtabguard { *this };1183 guard_indexer guard { *this }; 1184 1184 maybe_accept( node, &UntypedOffsetofExpr::result ); 1185 1185 } … … 1197 1197 1198 1198 VISIT({ 1199 guard_ symtabguard { *this };1199 guard_indexer guard { *this }; 1200 1200 maybe_accept( node, &OffsetofExpr::result ); 1201 1201 } … … 1213 1213 1214 1214 VISIT({ 1215 guard_ symtabguard { *this };1215 guard_indexer guard { *this }; 1216 1216 maybe_accept( node, &OffsetPackExpr::result ); 1217 1217 } … … 1229 1229 1230 1230 VISIT({ 1231 guard_ symtabguard { *this };1231 guard_indexer guard { *this }; 1232 1232 maybe_accept( node, &LogicalExpr::result ); 1233 1233 } … … 1246 1246 1247 1247 VISIT({ 1248 guard_ symtabguard { *this };1248 guard_indexer guard { *this }; 1249 1249 maybe_accept( node, &ConditionalExpr::result ); 1250 1250 } … … 1264 1264 1265 1265 VISIT({ 1266 guard_ symtabguard { *this };1266 guard_indexer guard { *this }; 1267 1267 maybe_accept( node, &CommaExpr::result ); 1268 1268 } … … 1281 1281 1282 1282 VISIT({ 1283 guard_ symtabguard { *this };1283 guard_indexer guard { *this }; 1284 1284 maybe_accept( node, &TypeExpr::result ); 1285 1285 } … … 1297 1297 1298 1298 VISIT({ 1299 guard_ symtabguard { *this };1299 guard_indexer guard { *this }; 1300 1300 maybe_accept( node, &AsmExpr::result ); 1301 1301 } … … 1315 1315 1316 1316 VISIT({ 1317 guard_ symtabguard { *this };1317 guard_indexer guard { *this }; 1318 1318 maybe_accept( node, &ImplicitCopyCtorExpr::result ); 1319 1319 } … … 1331 1331 1332 1332 VISIT({ 1333 guard_ symtabguard { *this };1333 guard_indexer guard { *this }; 1334 1334 maybe_accept( node, &ConstructorExpr::result ); 1335 1335 } … … 1347 1347 1348 1348 VISIT({ 1349 guard_ symtabguard { *this };1349 guard_indexer guard { *this }; 1350 1350 maybe_accept( node, &CompoundLiteralExpr::result ); 1351 1351 } … … 1363 1363 1364 1364 VISIT({ 1365 guard_ symtabguard { *this };1365 guard_indexer guard { *this }; 1366 1366 maybe_accept( node, &RangeExpr::result ); 1367 1367 } … … 1380 1380 1381 1381 VISIT({ 1382 guard_ symtabguard { *this };1382 guard_indexer guard { *this }; 1383 1383 maybe_accept( node, &UntypedTupleExpr::result ); 1384 1384 } … … 1396 1396 1397 1397 VISIT({ 1398 guard_ symtabguard { *this };1398 guard_indexer guard { *this }; 1399 1399 maybe_accept( node, &TupleExpr::result ); 1400 1400 } … … 1412 1412 1413 1413 VISIT({ 1414 guard_ symtabguard { *this };1414 guard_indexer guard { *this }; 1415 1415 maybe_accept( node, &TupleIndexExpr::result ); 1416 1416 } … … 1428 1428 1429 1429 VISIT({ 1430 guard_ symtabguard { *this };1430 guard_indexer guard { *this }; 1431 1431 maybe_accept( node, &TupleAssignExpr::result ); 1432 1432 } … … 1454 1454 1455 1455 { 1456 guard_ symtabguard { *this };1456 guard_indexer guard { *this }; 1457 1457 maybe_accept( node, &StmtExpr::result ); 1458 1458 } … … 1472 1472 1473 1473 VISIT({ 1474 guard_ symtabguard { *this };1474 guard_indexer guard { *this }; 1475 1475 maybe_accept( node, &UniqueExpr::result ); 1476 1476 } … … 1488 1488 1489 1489 VISIT({ 1490 guard_ symtabguard { *this };1490 guard_indexer guard { *this }; 1491 1491 maybe_accept( node, &UntypedInitExpr::result ); 1492 1492 } … … 1505 1505 1506 1506 VISIT({ 1507 guard_ symtabguard { *this };1507 guard_indexer guard { *this }; 1508 1508 maybe_accept( node, &InitExpr::result ); 1509 1509 } … … 1522 1522 1523 1523 VISIT({ 1524 guard_ symtabguard { *this };1524 guard_indexer guard { *this }; 1525 1525 maybe_accept( node, &DeletedExpr::result ); 1526 1526 } … … 1539 1539 1540 1540 VISIT({ 1541 guard_ symtabguard { *this };1541 guard_indexer guard { *this }; 1542 1542 maybe_accept( node, &DefaultArgExpr::result ); 1543 1543 } … … 1555 1555 1556 1556 VISIT({ 1557 guard_ symtabguard { *this };1557 guard_indexer guard { *this }; 1558 1558 maybe_accept( node, &GenericExpr::result ); 1559 1559 } … … 1566 1566 const Type * type = nullptr; 1567 1567 if( assoc.type ) { 1568 guard_ symtabguard { *this };1568 guard_indexer guard { *this }; 1569 1569 type = assoc.type->accept( *this ); 1570 1570 if( type != assoc.type ) mutated = true; … … 1682 1682 VISIT_START( node ); 1683 1683 1684 __pass:: symtab::addStruct( pass, 0, node->name );1685 1686 VISIT({ 1687 guard_ symtabguard { *this };1684 __pass::indexer::addStruct( pass, 0, node->name ); 1685 1686 VISIT({ 1687 guard_indexer guard { *this }; 1688 1688 maybe_accept( node, &StructInstType::forall ); 1689 1689 maybe_accept( node, &StructInstType::params ); … … 1699 1699 VISIT_START( node ); 1700 1700 1701 __pass:: symtab::addStruct( pass, 0, node->name );1701 __pass::indexer::addStruct( pass, 0, node->name ); 1702 1702 1703 1703 { 1704 guard_ symtabguard { *this };1704 guard_indexer guard { *this }; 1705 1705 maybe_accept( node, &UnionInstType::forall ); 1706 1706 maybe_accept( node, &UnionInstType::params ); … … 1893 1893 std::unordered_map< std::string, ast::ptr< ast::Type > > new_map; 1894 1894 for ( const auto & p : node->typeEnv ) { 1895 guard_ symtabguard { *this };1895 guard_indexer guard { *this }; 1896 1896 auto new_node = p.second->accept( *this ); 1897 1897 if (new_node != p.second) mutated = false; … … 1909 1909 std::unordered_map< std::string, ast::ptr< ast::Expr > > new_map; 1910 1910 for ( const auto & p : node->varEnv ) { 1911 guard_ symtabguard { *this };1911 guard_indexer guard { *this }; 1912 1912 auto new_node = p.second->accept( *this ); 1913 1913 if (new_node != p.second) mutated = false; -
src/AST/Pass.proto.hpp
rc6a1e8a r67130fe 265 265 }; 266 266 267 // Finally certain pass desire an up to date symbol tableautomatically268 // detect the presence of a member name `symtab`and call all the members appropriately269 namespace symtab{267 // Finally certain pass desire an up to date indexer automatically 268 // detect the presence of a member name indexer and call all the members appropriately 269 namespace indexer { 270 270 // Some simple scoping rules 271 271 template<typename pass_t> 272 static inline auto enter( pass_t & pass, int ) -> decltype( pass. symtab.enterScope(), void() ) {273 pass. symtab.enterScope();272 static inline auto enter( pass_t & pass, int ) -> decltype( pass.indexer.enterScope(), void() ) { 273 pass.indexer.enterScope(); 274 274 } 275 275 … … 278 278 279 279 template<typename pass_t> 280 static inline auto leave( pass_t & pass, int ) -> decltype( pass. symtab.leaveScope(), void() ) {281 pass. symtab.leaveScope();280 static inline auto leave( pass_t & pass, int ) -> decltype( pass.indexer.leaveScope(), void() ) { 281 pass.indexer.leaveScope(); 282 282 } 283 283 … … 285 285 static inline auto leave( pass_t &, long ) {} 286 286 287 // The symbol tablehas 2 kind of functions mostly, 1 argument and 2 arguments287 // The indexer has 2 kind of functions mostly, 1 argument and 2 arguments 288 288 // Create macro to condense these common patterns 289 #define SYMTAB_FUNC1( func, type ) \289 #define INDEXER_FUNC1( func, type ) \ 290 290 template<typename pass_t> \ 291 static inline auto func( pass_t & pass, int, type arg ) -> decltype( pass. symtab.func( arg ), void() ) {\292 pass. symtab.func( arg ); \291 static inline auto func( pass_t & pass, int, type arg ) -> decltype( pass.indexer.func( arg ), void() ) {\ 292 pass.indexer.func( arg ); \ 293 293 } \ 294 294 \ … … 296 296 static inline void func( pass_t &, long, type ) {} 297 297 298 #define SYMTAB_FUNC2( func, type1, type2 ) \298 #define INDEXER_FUNC2( func, type1, type2 ) \ 299 299 template<typename pass_t> \ 300 static inline auto func( pass_t & pass, int, type1 arg1, type2 arg2 ) -> decltype( pass. symtab.func( arg1, arg2 ), void () ) {\301 pass. symtab.func( arg1, arg2 ); \300 static inline auto func( pass_t & pass, int, type1 arg1, type2 arg2 ) -> decltype( pass.indexer.func( arg1, arg2 ), void () ) {\ 301 pass.indexer.func( arg1, arg2 ); \ 302 302 } \ 303 303 \ … … 305 305 static inline void func( pass_t &, long, type1, type2 ) {} 306 306 307 SYMTAB_FUNC1( addId , const DeclWithType * );308 SYMTAB_FUNC1( addType , const NamedTypeDecl * );309 SYMTAB_FUNC1( addStruct , const StructDecl * );310 SYMTAB_FUNC1( addEnum , const EnumDecl * );311 SYMTAB_FUNC1( addUnion , const UnionDecl * );312 SYMTAB_FUNC1( addTrait , const TraitDecl * );313 SYMTAB_FUNC2( addWith , const std::vector< ptr<Expr> > &, const Node * );307 INDEXER_FUNC1( addId , const DeclWithType * ); 308 INDEXER_FUNC1( addType , const NamedTypeDecl * ); 309 INDEXER_FUNC1( addStruct , const StructDecl * ); 310 INDEXER_FUNC1( addEnum , const EnumDecl * ); 311 INDEXER_FUNC1( addUnion , const UnionDecl * ); 312 INDEXER_FUNC1( addTrait , const TraitDecl * ); 313 INDEXER_FUNC2( addWith , const std::vector< ptr<Expr> > &, const Node * ); 314 314 315 315 // A few extra functions have more complicated behaviour, they are hand written 316 316 template<typename pass_t> 317 static inline auto addStructFwd( pass_t & pass, int, const ast::StructDecl * decl ) -> decltype( pass. symtab.addStruct( decl ), void() ) {317 static inline auto addStructFwd( pass_t & pass, int, const ast::StructDecl * decl ) -> decltype( pass.indexer.addStruct( decl ), void() ) { 318 318 ast::StructDecl * fwd = new ast::StructDecl( decl->location, decl->name ); 319 319 fwd->params = decl->params; 320 pass. symtab.addStruct( fwd );320 pass.indexer.addStruct( fwd ); 321 321 } 322 322 … … 325 325 326 326 template<typename pass_t> 327 static inline auto addUnionFwd( pass_t & pass, int, const ast::UnionDecl * decl ) -> decltype( pass. symtab.addUnion( decl ), void() ) {327 static inline auto addUnionFwd( pass_t & pass, int, const ast::UnionDecl * decl ) -> decltype( pass.indexer.addUnion( decl ), void() ) { 328 328 UnionDecl * fwd = new UnionDecl( decl->location, decl->name ); 329 329 fwd->params = decl->params; 330 pass. symtab.addUnion( fwd );330 pass.indexer.addUnion( fwd ); 331 331 } 332 332 … … 335 335 336 336 template<typename pass_t> 337 static inline auto addStruct( pass_t & pass, int, const std::string & str ) -> decltype( pass. symtab.addStruct( str ), void() ) {338 if ( ! pass. symtab.lookupStruct( str ) ) {339 pass. symtab.addStruct( str );337 static inline auto addStruct( pass_t & pass, int, const std::string & str ) -> decltype( pass.indexer.addStruct( str ), void() ) { 338 if ( ! pass.indexer.lookupStruct( str ) ) { 339 pass.indexer.addStruct( str ); 340 340 } 341 341 } … … 345 345 346 346 template<typename pass_t> 347 static inline auto addUnion( pass_t & pass, int, const std::string & str ) -> decltype( pass. symtab.addUnion( str ), void() ) {348 if ( ! pass. symtab.lookupUnion( str ) ) {349 pass. symtab.addUnion( str );347 static inline auto addUnion( pass_t & pass, int, const std::string & str ) -> decltype( pass.indexer.addUnion( str ), void() ) { 348 if ( ! pass.indexer.lookupUnion( str ) ) { 349 pass.indexer.addUnion( str ); 350 350 } 351 351 } … … 354 354 static inline void addUnion( pass_t &, long, const std::string & ) {} 355 355 356 #undef SYMTAB_FUNC1357 #undef SYMTAB_FUNC2356 #undef INDEXER_FUNC1 357 #undef INDEXER_FUNC2 358 358 }; 359 359 }; -
src/AST/Print.hpp
rc6a1e8a r67130fe 29 29 void print( std::ostream & os, const ast::Node * node, Indenter indent = {} ); 30 30 31 /// Wrap any standard format printer (matching above) with integer Indenter constructor 32 template<typename T> 33 inline void print( std::ostream & os, T && x, unsigned int indent ) { 34 print( os, std::forward<T>(x), Indenter{ Indenter::tabsize, indent }); 35 } 36 31 37 /// Print a declaration in its short form 32 38 void printShort( std::ostream & os, const ast::Decl * node, Indenter indent = {} ); 33 39 34 40 inline void printShort( std::ostream & os, const ast::Decl * node, unsigned int indent ) { 35 printShort( os, node, Indenter{ indent } );41 printShort( os, node, Indenter{ Indenter::tabsize, indent } ); 36 42 } 37 43 -
src/AST/SymbolTable.hpp
rc6a1e8a r67130fe 85 85 86 86 public: 87 SymbolTable();87 explicit SymbolTable(); 88 88 ~SymbolTable(); 89 89 … … 123 123 void addType( const NamedTypeDecl * decl ); 124 124 /// Adds a struct declaration to the symbol table by name 125 void addStruct( const std::string & id );125 void addStruct( const std::string &id ); 126 126 /// Adds a struct declaration to the symbol table 127 127 void addStruct( const StructDecl * decl ); 128 128 /// Adds an enum declaration to the symbol table 129 void addEnum( const EnumDecl * decl );129 void addEnum( const EnumDecl *decl ); 130 130 /// Adds a union declaration to the symbol table by name 131 void addUnion( const std::string & id );131 void addUnion( const std::string &id ); 132 132 /// Adds a union declaration to the symbol table 133 133 void addUnion( const UnionDecl * decl ); -
src/AST/porting.md
rc6a1e8a r67130fe 109 109 * `SymTab::Indexer` => `ast::SymbolTable` 110 110 * `SymTab/Indexer.{h,cc}` => `AST/SymbolTable.{hpp,cpp}` 111 * `WithIndexer` => `WithSymbolTable`111 * **TODO** `WithIndexer` => `WithSymbolTable` 112 112 * `indexer` => `symTab` 113 113 * `IdData::deleteStmt` => `IdData::deleter` 114 114 * `lookupId()` now returns a vector rather than an out-param list 115 * To avoid name collisions:116 * `SymTab::Mangler` => `Mangle`115 * To avoid name collisions: 116 * `SymTab::Mangler` => `Mangle` 117 117 * `ResolvExpr::TypeEnvironment` => `ast::TypeEnvironment` 118 118 * in `AST/TypeEnvironment.hpp` … … 295 295 * changed `WidenMode widenMode` => `WidenMode widen` 296 296 297 `Alternative` => `Candidate`298 * `openVars` => `open`299 300 297 [1] https://gcc.gnu.org/onlinedocs/gcc-9.1.0/gcc/Type-Attributes.html#Type-Attributes 301 298 -
src/Common/Indenter.h
rc6a1e8a r67130fe 18 18 19 19 struct Indenter { 20 static unsigned tabsize; ///< default number of spaces in one level of indentation20 static unsigned tabsize; 21 21 22 unsigned int indent; ///< number of spaces to indent 23 unsigned int amt; ///< spaces in one level of indentation 22 Indenter( unsigned int amt = tabsize, unsigned int indent = 0 ) : amt( amt ), indent( indent ) {} 23 unsigned int amt; // amount 1 level increases indent by (i.e. how much to increase by in operator++) 24 unsigned int indent; 24 25 25 Indenter( unsigned int indent = 0, unsigned int amt = tabsize )26 : indent( indent*amt ), amt( amt ) {}27 28 26 Indenter & operator+=(int nlevels) { indent += amt*nlevels; return *this; } 29 27 Indenter & operator-=(int nlevels) { indent -= amt*nlevels; return *this; } -
src/InitTweak/FixInit.cc
rc6a1e8a r67130fe 715 715 stmtsToAddBefore.push_back( new DeclStmt( ret ) ); 716 716 717 assertf( 718 stmtExpr->resultExpr, 719 "Statement-Expression should have a resulting expression at %s:%d", 720 stmtExpr->location.filename.c_str(), 721 stmtExpr->location.first_line 722 ); 723 717 if(!stmtExpr->resultExpr) { 718 SemanticError(stmtExpr, "Statment-Expression should have a resulting expression"); 719 } 724 720 ExprStmt * last = stmtExpr->resultExpr; 725 721 try { 726 722 last->expr = makeCtorDtor( "?{}", ret, last->expr ); 727 723 } catch(...) { 728 std::cerr << "*CFA internal error: "; 729 std::cerr << "can't resolve implicit constructor"; 730 std::cerr << " at " << stmtExpr->location.filename; 731 std::cerr << ":" << stmtExpr->location.first_line << std::endl; 724 std::cerr << "=======================" << std::endl; 725 std::cerr << "ERROR, can't resolve" << std::endl; 726 ret->print(std::cerr); 727 std::cerr << std::endl << "---" << std::endl; 728 last->expr->print(std::cerr); 732 729 733 730 abort(); -
src/Makefile.in
rc6a1e8a r67130fe 189 189 ResolvExpr/Alternative.$(OBJEXT) \ 190 190 ResolvExpr/AlternativeFinder.$(OBJEXT) \ 191 ResolvExpr/Candidate.$(OBJEXT) \192 ResolvExpr/CandidateFinder.$(OBJEXT) \193 191 ResolvExpr/CastCost.$(OBJEXT) ResolvExpr/CommonType.$(OBJEXT) \ 194 192 ResolvExpr/ConversionCost.$(OBJEXT) \ … … 624 622 ResolvExpr/Alternative.cc \ 625 623 ResolvExpr/AlternativeFinder.cc \ 626 ResolvExpr/Candidate.cpp \627 ResolvExpr/CandidateFinder.cpp \628 624 ResolvExpr/CastCost.cc \ 629 625 ResolvExpr/CommonType.cc \ … … 876 872 ResolvExpr/AlternativeFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 877 873 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 878 ResolvExpr/Candidate.$(OBJEXT): ResolvExpr/$(am__dirstamp) \879 ResolvExpr/$(DEPDIR)/$(am__dirstamp)880 ResolvExpr/CandidateFinder.$(OBJEXT): ResolvExpr/$(am__dirstamp) \881 ResolvExpr/$(DEPDIR)/$(am__dirstamp)882 874 ResolvExpr/CastCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 883 875 ResolvExpr/$(DEPDIR)/$(am__dirstamp) … … 1262 1254 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AlternativeFinder.Po@am__quote@ 1263 1255 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/AlternativePrinter.Po@am__quote@ 1264 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Candidate.Po@am__quote@1265 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CandidateFinder.Po@am__quote@1266 1256 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CastCost.Po@am__quote@ 1267 1257 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/CommonType.Po@am__quote@ -
src/ResolvExpr/AlternativeFinder.cc
rc6a1e8a r67130fe 136 136 137 137 void printAlts( const AltList &list, std::ostream &os, unsigned int indentAmt ) { 138 Indenter indent = { indentAmt };138 Indenter indent = { Indenter::tabsize, indentAmt }; 139 139 for ( AltList::const_iterator i = list.begin(); i != list.end(); ++i ) { 140 140 i->print( os, indent ); -
src/ResolvExpr/ResolveAssertions.cc
rc6a1e8a r67130fe 365 365 // fail early if any assertion is not resolvable 366 366 if ( ! resolveAssertion( assn, resn ) ) { 367 Indenter tabs{ 3 };367 Indenter tabs{ Indenter::tabsize, 3 }; 368 368 std::ostringstream ss; 369 369 ss << tabs << "Unsatisfiable alternative:\n"; … … 391 391 // fail early if no mutually-compatible assertion satisfaction 392 392 if ( compatible.empty() ) { 393 Indenter tabs{ 3 };393 Indenter tabs{ Indenter::tabsize, 3 }; 394 394 std::ostringstream ss; 395 395 ss << tabs << "Unsatisfiable alternative:\n"; -
src/ResolvExpr/Resolver.cc
rc6a1e8a r67130fe 21 21 #include "Alternative.h" // for Alternative, AltList 22 22 #include "AlternativeFinder.h" // for AlternativeFinder, resolveIn... 23 #include "Candidate.hpp"24 #include "CandidateFinder.hpp"25 23 #include "CurrentObject.h" // for CurrentObject 26 24 #include "RenameVars.h" // for RenameVars, global_renamer … … 29 27 #include "typeops.h" // for extractResultType 30 28 #include "Unify.h" // for unify 31 #include "AST/Chain.hpp"32 #include "AST/Decl.hpp"33 #include "AST/Init.hpp"34 29 #include "AST/Pass.hpp" 35 #include "AST/Print.hpp"36 30 #include "AST/SymbolTable.hpp" 37 31 #include "Common/PassVisitor.h" // for PassVisitor … … 119 113 120 114 namespace { 121 struct DeleteFinder _old: public WithShortCircuiting {115 struct DeleteFinder : public WithShortCircuiting { 122 116 DeletedExpr * delExpr = nullptr; 123 117 void previsit( DeletedExpr * expr ) { … … 133 127 134 128 DeletedExpr * findDeletedExpr( Expression * expr ) { 135 PassVisitor<DeleteFinder _old> finder;129 PassVisitor<DeleteFinder> finder; 136 130 expr->accept( finder ); 137 131 return finder.pass.delExpr; … … 139 133 140 134 namespace { 141 struct StripCasts _old{135 struct StripCasts { 142 136 Expression * postmutate( CastExpr * castExpr ) { 143 137 if ( castExpr->isGenerated && ResolvExpr::typesCompatible( castExpr->arg->result, castExpr->result, SymTab::Indexer() ) ) { … … 152 146 153 147 static void strip( Expression *& expr ) { 154 PassVisitor<StripCasts _old> stripper;148 PassVisitor<StripCasts> stripper; 155 149 expr = expr->acceptMutator( stripper ); 156 150 } … … 160 154 expr->env = oldenv ? oldenv->clone() : new TypeSubstitution; 161 155 env.makeSubstitution( *expr->env ); 162 StripCasts _old::strip( expr ); // remove unnecessary casts that may be buried in an expression156 StripCasts::strip( expr ); // remove unnecessary casts that may be buried in an expression 163 157 } 164 158 … … 411 405 412 406 void Resolver_old::previsit( ObjectDecl * objectDecl ) { 413 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that 414 // class-variable initContext is changed multiple time because the LHS is analysed twice. 415 // The second analysis changes initContext because of a function type can contain object 416 // declarations in the return and parameter types. So each value of initContext is 407 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that 408 // class-variable initContext is changed multiple time because the LHS is analysed twice. 409 // The second analysis changes initContext because of a function type can contain object 410 // declarations in the return and parameter types. So each value of initContext is 417 411 // retained, so the type on the first analysis is preserved and used for selecting the RHS. 418 412 GuardValue( currentObject ); … … 451 445 452 446 void Resolver_old::postvisit( FunctionDecl * functionDecl ) { 453 // default value expressions have an environment which shouldn't be there and trips up 447 // default value expressions have an environment which shouldn't be there and trips up 454 448 // later passes. 455 449 // xxx - it might be necessary to somehow keep the information from this environment, but I … … 943 937 /////////////////////////////////////////////////////////////////////////// 944 938 945 namespace { 946 /// Finds deleted expressions in an expression tree 947 struct DeleteFinder_new final : public ast::WithShortCircuiting { 948 const ast::DeletedExpr * delExpr = nullptr; 949 950 void previsit( const ast::DeletedExpr * expr ) { 951 if ( delExpr ) { visit_children = false; } 952 else { delExpr = expr; } 953 } 954 955 void previsit( const ast::Expr * ) { 956 if ( delExpr ) { visit_children = false; } 957 } 958 }; 959 960 /// Check if this expression is or includes a deleted expression 961 const ast::DeletedExpr * findDeletedExpr( const ast::Expr * expr ) { 962 ast::Pass<DeleteFinder_new> finder; 963 expr->accept( finder ); 964 return finder.pass.delExpr; 965 } 966 967 /// Calls the CandidateFinder and finds the single best candidate 968 CandidateRef findUnfinishedKindExpression( 969 const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 970 std::function<bool(const Candidate &)> pred, ResolvMode mode = {} 971 ) { 972 if ( ! untyped ) return nullptr; 973 974 // xxx - this isn't thread-safe, but should work until we parallelize the resolver 975 static unsigned recursion_level = 0; 976 977 ++recursion_level; 978 ast::TypeEnvironment env; 979 CandidateFinder finder{ symtab, env }; 980 finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode ); 981 --recursion_level; 982 983 // produce a filtered list of candidates 984 CandidateList candidates; 985 for ( auto & cand : finder.candidates ) { 986 if ( pred( *cand ) ) { candidates.emplace_back( cand ); } 987 } 988 989 // produce invalid error if no candidates 990 if ( candidates.empty() ) { 991 SemanticError( untyped, 992 toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""), 993 "expression: ") ); 994 } 995 996 // search for cheapest candidate 997 CandidateList winners; 998 bool seen_undeleted = false; 999 for ( CandidateRef & cand : candidates ) { 1000 int c = winners.empty() ? -1 : cand->cost.compare( winners.front()->cost ); 1001 1002 if ( c > 0 ) continue; // skip more expensive than winner 1003 1004 if ( c < 0 ) { 1005 // reset on new cheapest 1006 seen_undeleted = ! findDeletedExpr( cand->expr ); 1007 winners.clear(); 1008 } else /* if ( c == 0 ) */ { 1009 if ( findDeletedExpr( cand->expr ) ) { 1010 // skip deleted expression if already seen one equivalent-cost not 1011 if ( seen_undeleted ) continue; 1012 } else if ( ! seen_undeleted ) { 1013 // replace list of equivalent-cost deleted expressions with one non-deleted 1014 winners.clear(); 1015 seen_undeleted = true; 1016 } 1017 } 1018 1019 winners.emplace_back( std::move( cand ) ); 1020 } 1021 1022 // promote candidate.cvtCost to .cost 1023 for ( CandidateRef & cand : winners ) { 1024 cand->cost = cand->cvtCost; 1025 } 1026 1027 // produce ambiguous errors, if applicable 1028 if ( winners.size() != 1 ) { 1029 std::ostringstream stream; 1030 stream << "Cannot choose between " << winners.size() << " alternatives for " 1031 << kind << (kind != "" ? " " : "") << "expression\n"; 1032 ast::print( stream, untyped ); 1033 stream << " Alternatives are:\n"; 1034 print( stream, winners, 1 ); 1035 SemanticError( untyped->location, stream.str() ); 1036 } 1037 1038 // single selected choice 1039 CandidateRef & choice = winners.front(); 1040 1041 // fail on only expression deleted 1042 if ( ! seen_undeleted ) { 1043 SemanticError( untyped->location, choice->expr.get(), "Unique best alternative " 1044 "includes deleted identifier in " ); 1045 } 1046 1047 return std::move( choice ); 1048 } 1049 1050 /// Strips extraneous casts out of an expression 1051 struct StripCasts_new final { 1052 const ast::Expr * postmutate( const ast::CastExpr * castExpr ) { 1053 if ( 1054 castExpr->isGenerated 1055 && typesCompatible( castExpr->arg->result, castExpr->result ) 1056 ) { 1057 // generated cast is the same type as its argument, remove it after keeping env 1058 ast::ptr<ast::Expr> arg = castExpr->arg; 1059 arg.get_and_mutate()->env = castExpr->env; 1060 return arg; 1061 } 1062 return castExpr; 1063 } 1064 1065 static void strip( ast::ptr< ast::Expr > & expr ) { 1066 ast::Pass< StripCasts_new > stripper; 1067 expr = expr->accept( stripper ); 1068 } 1069 }; 1070 1071 /// Establish post-resolver invariants for expressions 1072 void finishExpr( 1073 ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, 1074 const ast::TypeSubstitution * oldenv = nullptr 1075 ) { 1076 // set up new type substitution for expression 1077 ast::ptr< ast::TypeSubstitution > newenv = 1078 oldenv ? oldenv : new ast::TypeSubstitution{}; 1079 env.writeToSubstitution( *newenv.get_and_mutate() ); 1080 expr.get_and_mutate()->env = std::move( newenv ); 1081 // remove unncecessary casts 1082 StripCasts_new::strip( expr ); 1083 } 1084 1085 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 1086 /// lowest cost, returning the resolved version 1087 ast::ptr< ast::Expr > findKindExpression( 1088 const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 1089 std::function<bool(const Candidate &)> pred, ResolvMode mode = {} 1090 ) { 1091 if ( ! untyped ) return {}; 1092 CandidateRef choice = 1093 findUnfinishedKindExpression( untyped, symtab, kind, pred, mode ); 1094 finishExpr( choice->expr, choice->env, untyped->env ); 1095 return std::move( choice->expr ); 1096 } 1097 1098 /// Predicate for "Candidate has integral type" 1099 bool hasIntegralType( const Candidate & i ) { 1100 const ast::Type * type = i.expr->result; 1101 1102 if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) { 1103 return bt->isInteger(); 1104 } else if ( 1105 dynamic_cast< const ast::EnumInstType * >( type ) 1106 || dynamic_cast< const ast::ZeroType * >( type ) 1107 || dynamic_cast< const ast::OneType * >( type ) 1108 ) { 1109 return true; 1110 } else return false; 1111 } 1112 1113 /// Resolve `untyped` as an integral expression, returning the resolved version 1114 ast::ptr< ast::Expr > findIntegralExpression( 1115 const ast::Expr * untyped, const ast::SymbolTable & symtab 1116 ) { 1117 return findKindExpression( untyped, symtab, "condition", hasIntegralType ); 1118 } 1119 } 1120 1121 class Resolver_new final 1122 : public ast::WithSymbolTable, public ast::WithGuards, 1123 public ast::WithVisitorRef<Resolver_new>, public ast::WithShortCircuiting, 1124 public ast::WithStmtsToAdd<> { 1125 1126 ast::ptr< ast::Type > functionReturn = nullptr; 1127 // ast::CurrentObject currentObject = nullptr; 1128 bool inEnumDecl = false; 1129 1130 public: 939 class Resolver_new final 940 : public ast::WithIndexer, public ast::WithGuards, public ast::WithVisitorRef<Resolver_new>, 941 public ast::WithShortCircuiting, public ast::WithStmtsToAdd<> { 942 943 public: 1131 944 Resolver_new() = default; 1132 Resolver_new( const ast::SymbolTable & syms ) { symtab = syms;}1133 1134 void previsit( const ast::FunctionDecl *);1135 const ast::FunctionDecl * postvisit( const ast::FunctionDecl *);1136 void previsit( const ast::ObjectDecl *);1137 void previsit( const ast::EnumDecl *);1138 const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl *);1139 1140 void previsit( const ast::ArrayType *);1141 void previsit( const ast::PointerType *);1142 1143 void previsit( const ast::ExprStmt *);1144 void previsit( const ast::AsmExpr *);1145 void previsit( const ast::AsmStmt *);1146 void previsit( const ast::IfStmt *);1147 void previsit( const ast::WhileStmt *);1148 void previsit( const ast::ForStmt *);1149 void previsit( const ast::SwitchStmt *);1150 void previsit( const ast::CaseStmt *);1151 void previsit( const ast::BranchStmt *);1152 void previsit( const ast::ReturnStmt *);1153 void previsit( const ast::ThrowStmt *);1154 void previsit( const ast::CatchStmt *);1155 void previsit( const ast::WaitForStmt *);1156 1157 void previsit( const ast::SingleInit *);1158 void previsit( const ast::ListInit *);1159 void previsit( const ast::ConstructorInit *);945 Resolver_new( const ast::SymbolTable & syms ) { /*symtab = syms;*/ } 946 947 void previsit( ast::FunctionDecl * functionDecl ); 948 ast::DeclWithType * postvisit( ast::FunctionDecl * functionDecl ); 949 void previsit( ast::ObjectDecl * objectDecl ); 950 void previsit( ast::EnumDecl * enumDecl ); 951 void previsit( ast::StaticAssertDecl * assertDecl ); 952 953 void previsit( ast::ArrayType * at ); 954 void previsit( ast::PointerType * pt ); 955 956 void previsit( ast::ExprStmt * exprStmt ); 957 void previsit( ast::AsmExpr * asmExpr ); 958 void previsit( ast::AsmStmt * asmStmt ); 959 void previsit( ast::IfStmt * ifStmt ); 960 void previsit( ast::WhileStmt * whileStmt ); 961 void previsit( ast::ForStmt * forStmt ); 962 void previsit( ast::SwitchStmt * switchStmt ); 963 void previsit( ast::CaseStmt * caseStmt ); 964 void previsit( ast::BranchStmt * branchStmt ); 965 void previsit( ast::ReturnStmt * returnStmt ); 966 void previsit( ast::ThrowStmt * throwStmt ); 967 void previsit( ast::CatchStmt * catchStmt ); 968 void previsit( ast::WaitForStmt * stmt ); 969 970 void previsit( ast::SingleInit * singleInit ); 971 void previsit( ast::ListInit * listInit ); 972 void previsit( ast::ConstructorInit * ctorInit ); 1160 973 }; 1161 974 … … 1165 978 } 1166 979 1167 void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) { 1168 GuardValue( functionReturn ); 1169 functionReturn = extractResultType( functionDecl->type ); 1170 } 1171 1172 const ast::FunctionDecl * Resolver_new::postvisit( const ast::FunctionDecl * functionDecl ) { 1173 // default value expressions have an environment which shouldn't be there and trips up 1174 // later passes. 1175 ast::ptr< ast::FunctionDecl > ret = functionDecl; 1176 for ( unsigned i = 0; i < functionDecl->type->params.size(); ++i ) { 1177 const ast::ptr<ast::DeclWithType> & d = functionDecl->type->params[i]; 1178 1179 if ( const ast::ObjectDecl * obj = d.as< ast::ObjectDecl >() ) { 1180 if ( const ast::SingleInit * init = obj->init.as< ast::SingleInit >() ) { 1181 if ( init->value->env == nullptr ) continue; 1182 // clone initializer minus the initializer environment 1183 ast::chain_mutate( ret ) 1184 ( &ast::FunctionDecl::type ) 1185 ( &ast::FunctionType::params )[i] 1186 ( &ast::ObjectDecl::init ) 1187 ( &ast::SingleInit::value )->env = nullptr; 1188 1189 assert( functionDecl != ret.get() || functionDecl->unique() ); 1190 assert( ! ret->type->params[i].strict_as< ast::ObjectDecl >()->init.strict_as< ast::SingleInit >()->value->env ); 1191 } 1192 } 1193 } 1194 return ret.get(); 1195 } 1196 1197 void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 980 void previsit( ast::FunctionDecl * functionDecl ) { 981 #warning unimplemented; Resolver port in progress 982 (void)functionDecl; 983 assert(false); 984 } 985 986 ast::DeclWithType * postvisit( ast::FunctionDecl * functionDecl ) { 987 #warning unimplemented; Resolver port in progress 988 (void)functionDecl; 989 assert(false); 990 return nullptr; 991 } 992 993 void previsit( ast::ObjectDecl * objectDecl ) { 1198 994 #warning unimplemented; Resolver port in progress 1199 995 (void)objectDecl; … … 1201 997 } 1202 998 1203 void Resolver_new::previsit( const ast::EnumDecl * ) { 1204 // in case we decide to allow nested enums 1205 GuardValue( inEnumDecl ); 1206 inEnumDecl = false; 1207 } 1208 1209 const ast::StaticAssertDecl * Resolver_new::previsit( 1210 const ast::StaticAssertDecl * assertDecl 1211 ) { 1212 ast::ptr< ast::Expr > cond = findIntegralExpression( assertDecl->cond, symtab ); 1213 if ( cond == assertDecl->cond ) return assertDecl; 1214 1215 ast::StaticAssertDecl * ret = mutate( assertDecl ); 1216 ret->cond = cond; 1217 return ret; 1218 } 1219 1220 void Resolver_new::previsit( const ast::ArrayType * at ) { 999 void previsit( ast::EnumDecl * enumDecl ) { 1000 #warning unimplemented; Resolver port in progress 1001 (void)enumDecl; 1002 assert(false); 1003 } 1004 1005 void previsit( ast::StaticAssertDecl * assertDecl ) { 1006 #warning unimplemented; Resolver port in progress 1007 (void)assertDecl; 1008 assert(false); 1009 } 1010 1011 void previsit( ast::ArrayType * at ) { 1221 1012 #warning unimplemented; Resolver port in progress 1222 1013 (void)at; … … 1224 1015 } 1225 1016 1226 void Resolver_new::previsit( constast::PointerType * pt ) {1017 void previsit( ast::PointerType * pt ) { 1227 1018 #warning unimplemented; Resolver port in progress 1228 1019 (void)pt; … … 1230 1021 } 1231 1022 1232 void Resolver_new::previsit( constast::ExprStmt * exprStmt ) {1023 void previsit( ast::ExprStmt * exprStmt ) { 1233 1024 #warning unimplemented; Resolver port in progress 1234 1025 (void)exprStmt; … … 1236 1027 } 1237 1028 1238 void Resolver_new::previsit( constast::AsmExpr * asmExpr ) {1029 void previsit( ast::AsmExpr * asmExpr ) { 1239 1030 #warning unimplemented; Resolver port in progress 1240 1031 (void)asmExpr; … … 1242 1033 } 1243 1034 1244 void Resolver_new::previsit( constast::AsmStmt * asmStmt ) {1035 void previsit( ast::AsmStmt * asmStmt ) { 1245 1036 #warning unimplemented; Resolver port in progress 1246 1037 (void)asmStmt; … … 1248 1039 } 1249 1040 1250 void Resolver_new::previsit( constast::IfStmt * ifStmt ) {1041 void previsit( ast::IfStmt * ifStmt ) { 1251 1042 #warning unimplemented; Resolver port in progress 1252 1043 (void)ifStmt; … … 1254 1045 } 1255 1046 1256 void Resolver_new::previsit( constast::WhileStmt * whileStmt ) {1047 void previsit( ast::WhileStmt * whileStmt ) { 1257 1048 #warning unimplemented; Resolver port in progress 1258 1049 (void)whileStmt; … … 1260 1051 } 1261 1052 1262 void Resolver_new::previsit( constast::ForStmt * forStmt ) {1053 void previsit( ast::ForStmt * forStmt ) { 1263 1054 #warning unimplemented; Resolver port in progress 1264 1055 (void)forStmt; … … 1266 1057 } 1267 1058 1268 void Resolver_new::previsit( constast::SwitchStmt * switchStmt ) {1059 void previsit( ast::SwitchStmt * switchStmt ) { 1269 1060 #warning unimplemented; Resolver port in progress 1270 1061 (void)switchStmt; … … 1272 1063 } 1273 1064 1274 void Resolver_new::previsit( constast::CaseStmt * caseStmt ) {1065 void previsit( ast::CaseStmt * caseStmt ) { 1275 1066 #warning unimplemented; Resolver port in progress 1276 1067 (void)caseStmt; … … 1278 1069 } 1279 1070 1280 void Resolver_new::previsit( constast::BranchStmt * branchStmt ) {1071 void previsit( ast::BranchStmt * branchStmt ) { 1281 1072 #warning unimplemented; Resolver port in progress 1282 1073 (void)branchStmt; … … 1284 1075 } 1285 1076 1286 void Resolver_new::previsit( constast::ReturnStmt * returnStmt ) {1077 void previsit( ast::ReturnStmt * returnStmt ) { 1287 1078 #warning unimplemented; Resolver port in progress 1288 1079 (void)returnStmt; … … 1290 1081 } 1291 1082 1292 void Resolver_new::previsit( constast::ThrowStmt * throwStmt ) {1083 void previsit( ast::ThrowStmt * throwStmt ) { 1293 1084 #warning unimplemented; Resolver port in progress 1294 1085 (void)throwStmt; … … 1296 1087 } 1297 1088 1298 void Resolver_new::previsit( constast::CatchStmt * catchStmt ) {1089 void previsit( ast::CatchStmt * catchStmt ) { 1299 1090 #warning unimplemented; Resolver port in progress 1300 1091 (void)catchStmt; … … 1302 1093 } 1303 1094 1304 void Resolver_new::previsit( constast::WaitForStmt * stmt ) {1095 void previsit( ast::WaitForStmt * stmt ) { 1305 1096 #warning unimplemented; Resolver port in progress 1306 1097 (void)stmt; … … 1308 1099 } 1309 1100 1310 void Resolver_new::previsit( constast::SingleInit * singleInit ) {1101 void previsit( ast::SingleInit * singleInit ) { 1311 1102 #warning unimplemented; Resolver port in progress 1312 1103 (void)singleInit; … … 1314 1105 } 1315 1106 1316 void Resolver_new::previsit( constast::ListInit * listInit ) {1107 void previsit( ast::ListInit * listInit ) { 1317 1108 #warning unimplemented; Resolver port in progress 1318 1109 (void)listInit; … … 1320 1111 } 1321 1112 1322 void Resolver_new::previsit( constast::ConstructorInit * ctorInit ) {1113 void previsit( ast::ConstructorInit * ctorInit ) { 1323 1114 #warning unimplemented; Resolver port in progress 1324 1115 (void)ctorInit; -
src/ResolvExpr/module.mk
rc6a1e8a r67130fe 19 19 ResolvExpr/Alternative.cc \ 20 20 ResolvExpr/AlternativeFinder.cc \ 21 ResolvExpr/Candidate.cpp \22 ResolvExpr/CandidateFinder.cpp \23 21 ResolvExpr/CastCost.cc \ 24 22 ResolvExpr/CommonType.cc \ -
src/ResolvExpr/typeops.h
rc6a1e8a r67130fe 103 103 104 104 bool typesCompatible( 105 const ast::Type *, const ast::Type *, const ast::SymbolTable & symtab = {},105 const ast::Type *, const ast::Type *, const ast::SymbolTable &, 106 106 const ast::TypeEnvironment & env = {} ); 107 107 -
src/SynTree/BaseSyntaxNode.h
rc6a1e8a r67130fe 41 41 /// * Expressions should not finish with a newline, since the expression's parent has better information. 42 42 virtual void print( std::ostream & os, Indenter indent = {} ) const = 0; 43 void print( std::ostream & os, unsigned int indent ) { 44 print( os, Indenter{ Indenter::tabsize, indent }); 45 } 43 46 }; 44 47 -
src/SynTree/DeclReplacer.cc
rc6a1e8a r67130fe 30 30 bool debug; 31 31 public: 32 size_t replaced;33 34 public:35 32 DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug = false ); 36 33 … … 48 45 bool debug; 49 46 public: 50 size_t replaced;51 52 public:53 47 ExprDeclReplacer( const ExprMap & exprMap, bool debug = false ); 54 48 … … 58 52 } 59 53 60 size_treplace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug ) {54 void replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug ) { 61 55 PassVisitor<DeclReplacer> replacer( declMap, typeMap, debug ); 62 56 maybeAccept( node, replacer ); 63 return replacer.pass.replaced;64 57 } 65 58 66 size_treplace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug ) {59 void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug ) { 67 60 TypeMap typeMap; 68 re turn replace( node, declMap, typeMap, debug );61 replace( node, declMap, typeMap, debug ); 69 62 } 70 63 71 size_treplace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug ) {64 void replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug ) { 72 65 DeclMap declMap; 73 re turn replace( node, declMap, typeMap, debug );66 replace( node, declMap, typeMap, debug ); 74 67 } 75 68 76 size_treplace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug ) {69 void replace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug ) { 77 70 PassVisitor<ExprDeclReplacer> replacer( exprMap, debug ); 78 71 node = maybeMutate( node, replacer ); 79 return replacer.pass.replaced;80 72 } 81 73 82 74 namespace { 83 DeclReplacer::DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug ) : declMap( declMap ), typeMap( typeMap ) , debug( debug ) , replaced( 0 ){}75 DeclReplacer::DeclReplacer( const DeclMap & declMap, const TypeMap & typeMap, bool debug ) : declMap( declMap ), typeMap( typeMap ) , debug( debug ) {} 84 76 85 77 // replace variable with new node from decl map … … 87 79 // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are) 88 80 if ( declMap.count( varExpr->var ) ) { 89 replaced++;90 81 auto replacement = declMap.at( varExpr->var ); 91 82 if ( debug ) { … … 98 89 void DeclReplacer::previsit( TypeInstType * inst ) { 99 90 if ( typeMap.count( inst->baseType ) ) { 100 replaced++;101 91 auto replacement = typeMap.at( inst->baseType ); 102 92 if ( debug ) { … … 107 97 } 108 98 109 ExprDeclReplacer::ExprDeclReplacer( const ExprMap & exprMap, bool debug ) : exprMap( exprMap ), debug( debug ) , replaced( 0 ){}99 ExprDeclReplacer::ExprDeclReplacer( const ExprMap & exprMap, bool debug ) : exprMap( exprMap ), debug( debug ) {} 110 100 111 101 Expression * ExprDeclReplacer::postmutate( VariableExpr * varExpr ) { 112 102 if ( exprMap.count( varExpr->var ) ) { 113 replaced++;114 103 Expression * replacement = exprMap.at( varExpr->var )->clone(); 115 104 if ( debug ) { -
src/SynTree/DeclReplacer.h
rc6a1e8a r67130fe 28 28 typedef std::map< DeclarationWithType *, Expression * > ExprMap; 29 29 30 size_treplace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false );31 size_treplace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug = false );32 size_treplace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false );30 void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false ); 31 void replace( BaseSyntaxNode * node, const TypeMap & typeMap, bool debug = false ); 32 void replace( BaseSyntaxNode * node, const DeclMap & declMap, const TypeMap & typeMap, bool debug = false ); 33 33 34 size_treplace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug = false);34 void replace( BaseSyntaxNode *& node, const ExprMap & exprMap, bool debug = false); 35 35 template<typename T> 36 36 void replace( T *& node, const ExprMap & exprMap, bool debug = false ) { -
src/main.cc
rc6a1e8a r67130fe 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 5 20:35:13201913 // Update Count : 60 112 // Last Modified On : Mon Jun 3 17:35:59 2019 13 // Update Count : 600 14 14 // 15 15 … … 406 406 407 407 408 static const char optstring[] = ":hlLmNn pP:S:twW:D:F:";408 static const char optstring[] = ":hlLmNn:pP:S:twW:D:F:"; 409 409 410 410 enum { PreludeDir = 128 };
Note:
See TracChangeset
for help on using the changeset viewer.