Ignore:
Timestamp:
Jun 5, 2023, 1:29:55 PM (15 months ago)
Author:
Michael Brooks <mlbrooks@…>
Branches:
ast-experimental, master
Children:
134e6d9
Parents:
84334d0
Message:

Make the symbol table's error-checking times explicit.

Previously, error checking happened on all WithSymbolTable? uses. Error checking means having a symbol-table add operation potentially cause a user-visible error report. Now, this only happens on the resolver pass's symbol table, while other passes' run in an "assert no errors can happen" mode.

An "ignore errors for now" mode is implemented too, which will be used in upcoming commits, for pre-resolver passes that use the symbol table.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/AST/SymbolTable.cpp

    r84334d0 rb9fe89b  
    8888}
    8989
    90 SymbolTable::SymbolTable()
     90SymbolTable::SymbolTable( ErrorDetection errorMode )
    9191: idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(),
    92   prevScope(), scope( 0 ), repScope( 0 ) { ++*stats().count; }
     92  prevScope(), scope( 0 ), repScope( 0 ), errorMode(errorMode) { ++*stats().count; }
    9393
    9494SymbolTable::~SymbolTable() { stats().size->push( idTable ? idTable->size() : 0 ); }
     95
     96void SymbolTable::OnFindError( CodeLocation location, std::string error ) const {
     97        assertf( errorMode != AssertClean, "Name collision/redefinition, found during a compilation phase where none should be possible.  Detail: %s", error.c_str() );
     98        if (errorMode == ValidateOnAdd) {
     99                SemanticError(location, error);
     100        }
     101        assertf( errorMode == IgnoreErrors, "Unrecognized symbol-table error mode %d", errorMode );
     102}
    95103
    96104void SymbolTable::enterScope() {
     
    269277}
    270278
    271 namespace {
    272         /// true if redeclaration conflict between two types
    273         bool addedTypeConflicts( const NamedTypeDecl * existing, const NamedTypeDecl * added ) {
    274                 if ( existing->base == nullptr ) {
    275                         return false;
    276                 } else if ( added->base == nullptr ) {
    277                         return true;
    278                 } else {
    279                         // typedef redeclarations are errors only if types are different
    280                         if ( ! ResolvExpr::typesCompatible( existing->base, added->base ) ) {
    281                                 SemanticError( added->location, "redeclaration of " + added->name );
    282                         }
    283                 }
    284                 // does not need to be added to the table if both existing and added have a base that are
    285                 // the same
     279bool SymbolTable::addedTypeConflicts(
     280                const NamedTypeDecl * existing, const NamedTypeDecl * added ) const {
     281        if ( existing->base == nullptr ) {
     282                return false;
     283        } else if ( added->base == nullptr ) {
    286284                return true;
    287         }
    288 
    289         /// true if redeclaration conflict between two aggregate declarations
    290         bool addedDeclConflicts( const AggregateDecl * existing, const AggregateDecl * added ) {
    291                 if ( ! existing->body ) {
    292                         return false;
    293                 } else if ( added->body ) {
    294                         SemanticError( added, "redeclaration of " );
    295                 }
    296                 return true;
    297         }
     285        } else {
     286                // typedef redeclarations are errors only if types are different
     287                if ( ! ResolvExpr::typesCompatible( existing->base, added->base ) ) {
     288                        OnFindError( added->location, "redeclaration of " + added->name );
     289                }
     290        }
     291        // does not need to be added to the table if both existing and added have a base that are
     292        // the same
     293        return true;
     294}
     295
     296bool SymbolTable::addedDeclConflicts(
     297                const AggregateDecl * existing, const AggregateDecl * added ) const {
     298        if ( ! existing->body ) {
     299                return false;
     300        } else if ( added->body ) {
     301                OnFindError( added, "redeclaration of " );
     302        }
     303        return true;
    298304}
    299305
     
    648654                if ( deleter && ! existing.deleter ) {
    649655                        if ( handleConflicts.mode == OnConflict::Error ) {
    650                                 SemanticError( added, "deletion of defined identifier " );
     656                                OnFindError( added, "deletion of defined identifier " );
    651657                        }
    652658                        return true;
    653659                } else if ( ! deleter && existing.deleter ) {
    654660                        if ( handleConflicts.mode == OnConflict::Error ) {
    655                                 SemanticError( added, "definition of deleted identifier " );
     661                                OnFindError( added, "definition of deleted identifier " );
    656662                        }
    657663                        return true;
     
    661667                if ( isDefinition( added ) && isDefinition( existing.id ) ) {
    662668                        if ( handleConflicts.mode == OnConflict::Error ) {
    663                                 SemanticError( added,
     669                                OnFindError( added,
    664670                                        isFunction( added ) ?
    665671                                                "duplicate function definition for " :
     
    670676        } else {
    671677                if ( handleConflicts.mode == OnConflict::Error ) {
    672                         SemanticError( added, "duplicate definition for " );
     678                        OnFindError( added, "duplicate definition for " );
    673679                }
    674680                return true;
     
    722728                // Check that a Cforall declaration doesn't override any C declaration
    723729                if ( hasCompatibleCDecl( name, mangleName ) ) {
    724                         SemanticError( decl, "Cforall declaration hides C function " );
     730                        OnFindError( decl, "Cforall declaration hides C function " );
    725731                }
    726732        } else {
     
    728734                // type-compatibility, which it may not be.
    729735                if ( hasIncompatibleCDecl( name, mangleName ) ) {
    730                         SemanticError( decl, "conflicting overload of C function " );
     736                        OnFindError( decl, "conflicting overload of C function " );
    731737                }
    732738        }
Note: See TracChangeset for help on using the changeset viewer.