Changeset 0ac366b
- Timestamp:
- Feb 15, 2018, 11:39:12 AM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 4a161be
- Parents:
- f5883bd
- Location:
- src
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Common/PassVisitor.h
rf5883bd r0ac366b 305 305 void indexerAddUnionFwd ( UnionDecl * node ) { indexer_impl_addUnionFwd ( pass, 0, node ); } 306 306 void indexerAddTrait ( TraitDecl * node ) { indexer_impl_addTrait ( pass, 0, node ); } 307 void indexerAddWith ( std::list< Expression * > & exprs ) { indexer_impl_addWith ( pass, 0, exprs); }307 void indexerAddWith ( std::list< Expression * > & exprs, BaseSyntaxNode * withStmt ) { indexer_impl_addWith ( pass, 0, exprs, withStmt ); } 308 308 309 309 -
src/Common/PassVisitor.impl.h
rf5883bd r0ac366b 398 398 // shadow with exprs and not the other way around. 399 399 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 400 indexerAddWith( node->withExprs );400 indexerAddWith( node->withExprs, node ); 401 401 { 402 402 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); … … 428 428 // shadow with exprs and not the other way around. 429 429 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 430 indexerAddWith( node->withExprs );430 indexerAddWith( node->withExprs, node ); 431 431 { 432 432 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); … … 1069 1069 // catch statements introduce a level of scope (for the caught exception) 1070 1070 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1071 indexerAddWith( node->exprs );1071 indexerAddWith( node->exprs, node ); 1072 1072 maybeAccept_impl( node->stmt, *this ); 1073 1073 } … … 1082 1082 // catch statements introduce a level of scope (for the caught exception) 1083 1083 auto guard = makeFuncGuard( [this]() { indexerScopeEnter(); }, [this]() { indexerScopeLeave(); } ); 1084 indexerAddWith( node->exprs );1084 indexerAddWith( node->exprs, node ); 1085 1085 maybeMutate_impl( node->stmt, *this ); 1086 1086 } -
src/Common/PassVisitor.proto.h
rf5883bd r0ac366b 193 193 194 194 195 #define INDEXER_FUNC ( func, type ) \195 #define INDEXER_FUNC1( func, type ) \ 196 196 template<typename pass_type> \ 197 197 static inline auto indexer_impl_##func ( pass_type & pass, int, type arg ) -> decltype( pass.indexer.func( arg ), void() ) { \ … … 202 202 static inline void indexer_impl_##func ( pass_type &, long, type ) { } \ 203 203 204 INDEXER_FUNC( addId , DeclarationWithType * ); 205 INDEXER_FUNC( addType , NamedTypeDecl * ); 206 INDEXER_FUNC( addStruct , StructDecl * ); 207 INDEXER_FUNC( addEnum , EnumDecl * ); 208 INDEXER_FUNC( addUnion , UnionDecl * ); 209 INDEXER_FUNC( addTrait , TraitDecl * ); 210 INDEXER_FUNC( addWith , std::list< Expression * > & ); 204 #define INDEXER_FUNC2( func, type1, type2 ) \ 205 template<typename pass_type> \ 206 static inline auto indexer_impl_##func ( pass_type & pass, int, type1 arg1, type2 arg2 ) -> decltype( pass.indexer.func( arg1, arg2 ), void() ) { \ 207 pass.indexer.func( arg1, arg2 ); \ 208 } \ 209 \ 210 template<typename pass_type> \ 211 static inline void indexer_impl_##func ( pass_type &, long, type1, type2 ) { } 212 213 214 INDEXER_FUNC1( addId , DeclarationWithType * ); 215 INDEXER_FUNC1( addType , NamedTypeDecl * ); 216 INDEXER_FUNC1( addStruct , StructDecl * ); 217 INDEXER_FUNC1( addEnum , EnumDecl * ); 218 INDEXER_FUNC1( addUnion , UnionDecl * ); 219 INDEXER_FUNC1( addTrait , TraitDecl * ); 220 INDEXER_FUNC2( addWith , std::list< Expression * > &, BaseSyntaxNode * ); 211 221 212 222 -
src/SymTab/Indexer.cc
rf5883bd r0ac366b 286 286 } 287 287 288 DeclarationWithType *Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const {289 if ( ! tables ) return 0;290 if ( tables->scope < scope ) return 0;288 const Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const { 289 if ( ! tables ) return nullptr; 290 if ( tables->scope < scope ) return nullptr; 291 291 292 292 IdTable::const_iterator decls = tables->idTable.find( id ); … … 294 294 const MangleTable &mangleTable = decls->second; 295 295 MangleTable::const_iterator decl = mangleTable.find( mangleName ); 296 if ( decl != mangleTable.end() ) return decl->second.id;296 if ( decl != mangleTable.end() ) return &decl->second; 297 297 } 298 298 299 299 return tables->base.lookupIdAtScope( id, mangleName, scope ); 300 } 301 302 Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) { 303 return const_cast<IdData *>(const_cast<const Indexer *>(this)->lookupIdAtScope( id, mangleName, scope )); 300 304 } 301 305 … … 373 377 } 374 378 375 bool addedIdConflicts( DeclarationWithType *existing, DeclarationWithType *added) {379 bool addedIdConflicts( Indexer::IdData & existing, DeclarationWithType *added, BaseSyntaxNode * deleteStmt, Indexer::ConflictFunction handleConflicts ) { 376 380 // if we're giving the same name mangling to things of different types then there is something wrong 377 assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing ) )378 || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing ) ) );379 380 if ( LinkageSpec::isOverridable( existing ->get_linkage() ) ) {381 assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing.id ) ) 382 || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing.id ) ) ); 383 384 if ( LinkageSpec::isOverridable( existing.id->get_linkage() ) ) { 381 385 // new definition shadows the autogenerated one, even at the same scope 382 386 return false; 383 } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) { 387 } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing.id->get_type(), Indexer() ) ) { 388 389 // it is a conflict if one declaration is deleted and the other is not 390 if ( deleteStmt && ! existing.deleteStmt ) { 391 return handleConflicts( existing, "deletion of defined identifier " ); 392 } else if ( ! deleteStmt && existing.deleteStmt ) { 393 return handleConflicts( existing, "definition of deleted identifier " ); 394 } 395 384 396 // typesCompatible doesn't really do the right thing here. When checking compatibility of function types, 385 397 // we should ignore outermost pointer qualifiers, except _Atomic? 386 FunctionDecl * newentry = dynamic_cast< FunctionDecl* >( added );387 FunctionDecl * oldentry = dynamic_cast< FunctionDecl* >( existing);398 FunctionDecl * newentry = dynamic_cast< FunctionDecl * >( added ); 399 FunctionDecl * oldentry = dynamic_cast< FunctionDecl * >( existing.id ); 388 400 if ( newentry && oldentry ) { 389 401 if ( newentry->get_statements() && oldentry->get_statements() ) { 390 throw SemanticError( "duplicate function definition for ", added);402 return handleConflicts( existing, "duplicate function definition for " ); 391 403 } // if 392 404 } else { … … 395 407 // xxx - perhaps it's actually if either is intrinsic then this is okay? 396 408 // might also need to be same storage class? 397 ObjectDecl * newobj = dynamic_cast< ObjectDecl* >( added );398 ObjectDecl * oldobj = dynamic_cast< ObjectDecl* >( existing);409 ObjectDecl * newobj = dynamic_cast< ObjectDecl * >( added ); 410 ObjectDecl * oldobj = dynamic_cast< ObjectDecl * >( existing.id ); 399 411 if ( ! newobj->get_storageClasses().is_extern && ! oldobj->get_storageClasses().is_extern ) { 400 throw SemanticError( "duplicate object definition for ", added);412 return handleConflicts( existing, "duplicate object definition for " ); 401 413 } // if 402 414 } // if 403 415 } else { 404 throw SemanticError( "duplicate definition for ", added);416 return handleConflicts( existing, "duplicate definition for " ); 405 417 } // if 406 418 … … 408 420 } 409 421 410 void Indexer::addId( DeclarationWithType *decl, Expression * baseExpr) {422 void Indexer::addId( DeclarationWithType *decl, ConflictFunction handleConflicts, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) { 411 423 if ( decl->name == "" ) return; 412 424 debugPrint( "Adding Id " << decl->name << std::endl ); … … 441 453 442 454 // Skip repeat declarations of the same identifier 443 DeclarationWithType *existing = lookupIdAtScope( name, mangleName, scope );444 if ( existing && addedIdConflicts( existing, decl) ) return;455 IdData * existing = lookupIdAtScope( name, mangleName, scope ); 456 if ( existing && existing->id && addedIdConflicts( *existing, decl, deleteStmt, handleConflicts ) ) return; 445 457 446 458 // add to indexer 447 tables->idTable[ name ][ mangleName ] = { decl, baseExpr };459 tables->idTable[ name ][ mangleName ] = { decl, baseExpr, deleteStmt }; 448 460 ++tables->size; 461 } 462 463 void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) { 464 // default handling of conflicts is to raise an error 465 addId( decl, [decl](IdData &, const std::string & msg) { throw SemanticError( msg, decl ); return true; }, baseExpr ); 466 } 467 468 void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ) { 469 // default handling of conflicts is to raise an error 470 addId( decl, [decl](IdData &, const std::string & msg) { throw SemanticError( msg, decl ); return true; }, nullptr, deleteStmt ); 449 471 } 450 472 … … 573 595 } 574 596 575 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr ) {597 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction handleConflicts ) { 576 598 for ( Declaration * decl : aggr->members ) { 577 599 if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) { 578 addId( dwt, expr );600 addId( dwt, handleConflicts, expr ); 579 601 if ( dwt->name == "" ) { 580 602 Type * t = dwt->get_type()->stripReferences(); … … 582 604 Expression * base = expr->clone(); 583 605 ResolvExpr::referenceToRvalueConversion( base ); 584 addMembers( t->getAggr(), new MemberExpr( dwt, base ) );606 addMembers( t->getAggr(), new MemberExpr( dwt, base ), handleConflicts ); 585 607 } 586 608 } … … 589 611 } 590 612 591 void Indexer::addWith( std::list< Expression * > & withExprs ) {613 void Indexer::addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt ) { 592 614 for ( Expression * expr : withExprs ) { 593 615 if ( expr->result ) { … … 595 617 assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() ); 596 618 597 addMembers( aggr, expr ); 619 addMembers( aggr, expr, [withStmt](IdData & existing, const std::string &) { 620 // on conflict, delete the identifier 621 existing.deleteStmt = withStmt; 622 return true; 623 }); 598 624 } 599 625 } … … 680 706 681 707 Expression * Indexer::IdData::combine() const { 708 Expression * ret = nullptr; 682 709 if ( baseExpr ) { 683 710 Expression * base = baseExpr->clone(); 684 711 ResolvExpr::referenceToRvalueConversion( base ); 685 Expression *ret = new MemberExpr( id, base );712 ret = new MemberExpr( id, base ); 686 713 // xxx - this introduces hidden environments, for now remove them. 687 714 // std::swap( base->env, ret->env ); 688 715 delete base->env; 689 716 base->env = nullptr; 690 return ret; 691 } else { 692 return new VariableExpr( id ); 693 } 717 } else { 718 ret = new VariableExpr( id ); 719 } 720 if ( deleteStmt ) ret = new DeletedExpr( ret, deleteStmt ); 721 return ret; 694 722 } 695 723 } // namespace SymTab -
src/SymTab/Indexer.h
rf5883bd r0ac366b 19 19 #include <list> // for list 20 20 #include <string> // for string 21 #include <functional> // for function 21 22 22 23 #include "SynTree/Visitor.h" // for Visitor … … 65 66 66 67 /// looks up a specific mangled ID at the given scope 67 DeclarationWithType *lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const; 68 IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ); 69 const IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const; 68 70 /// returns true if there exists a declaration with C linkage and the given name with a different mangled name 69 71 bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const; … … 77 79 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const; 78 80 79 void addId( DeclarationWithType *decl, Expression * baseExpr = nullptr ); 81 typedef std::function<bool(IdData &, const std::string &)> ConflictFunction; 82 83 void addId( DeclarationWithType * decl, Expression * baseExpr = nullptr ); 84 void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ); 85 80 86 void addType( NamedTypeDecl *decl ); 81 87 void addStruct( const std::string &id ); … … 87 93 88 94 /// adds all of the IDs from WithStmt exprs 89 void addWith( std::list< Expression * > & withExprs );95 void addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt ); 90 96 91 97 /// adds all of the members of the Aggregate (addWith helper) 92 void addMembers( AggregateDecl * aggr, Expression * expr );98 void addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction ); 93 99 94 100 /// convenience function for adding a list of Ids to the indexer … … 120 126 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope) 121 127 void makeWritable(); 128 129 /// common code for addId, addDeletedId, etc. 130 void addId( DeclarationWithType * decl, ConflictFunction, Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr ); 122 131 }; 123 132 } // namespace SymTab
Note: See TracChangeset
for help on using the changeset viewer.