Changeset 90a8125 for src/ControlStruct


Ignore:
Timestamp:
Jun 3, 2022, 3:10:01 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, ast-experimental, master, pthread-emulation, qualifiedEnum
Children:
7affcda
Parents:
bf0263c (diff), fc134a48 (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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src/ControlStruct
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/ExceptDecl.cc

    rbf0263c r90a8125  
    99// Author           : Henry Xue
    1010// Created On       : Tue Jul 20 04:10:50 2021
    11 // Last Modified By : Henry Xue
    12 // Last Modified On : Tue Aug 03 10:42:26 2021
    13 // Update Count     : 4
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed May 25 16:43:00 2022
     13// Update Count     : 5
    1414//
    1515
     
    3939}
    4040
    41 TypeInstType * makeExceptInstType(
    42         const std::string & exceptionName,
    43         const std::list< Expression *> & parameters
    44 ) {
    45         TypeInstType * exceptInstType = new TypeInstType(
     41StructInstType * makeExceptInstType(
     42        const std::string & exceptionName,
     43        const std::list< Expression *> & parameters
     44) {
     45        StructInstType * exceptInstType = new StructInstType(
    4646                noQualifiers,
    47                 exceptionName,
    48                 false
     47                exceptionName
    4948        );
    5049        cloneAll( parameters, exceptInstType->parameters );
     
    151150                nullptr,
    152151                new PointerType( noQualifiers,
    153                         new TypeInstType( Type::Const, "__cfavir_type_info", false ) ),
     152                        new StructInstType( Type::Const, "__cfavir_type_info" ) ),
    154153                nullptr
    155154        ) );
     
    257256        const std::string & exceptionName,
    258257        const std::list< TypeDecl *> & forallClause,
    259         const std::list< Expression *> & parameters, 
     258        const std::list< Expression *> & parameters,
    260259        const std::list< Declaration *> & members
    261260) {
     
    302301ObjectDecl * ehmExternVtable(
    303302        const std::string & exceptionName,
    304         const std::list< Expression *> & parameters, 
     303        const std::list< Expression *> & parameters,
    305304        const std::string & tableName
    306305) {
     
    457456}
    458457
     458class VTableCore : public WithDeclsToAdd {
     459public:
     460        // Remove any remaining vtable type nodes in the tree.
     461        Type * postmutate( VTableType * vtableType );
     462};
     463
     464Type * VTableCore::postmutate( VTableType * vtableType ) {
     465        auto inst = strict_dynamic_cast<ReferenceToType *>( vtableType->base );
     466
     467        std::string vtableName = Virtual::vtableTypeName( inst->name );
     468        StructInstType * newType = new StructInstType( noQualifiers, vtableName );
     469        cloneAll( inst->parameters, newType->parameters );
     470
     471        delete vtableType;
     472        return newType;
     473}
     474
    459475void translateExcept( std::list< Declaration *> & translationUnit ) {
    460476        PassVisitor<ExceptDeclCore> translator;
    461477        mutateAll( translationUnit, translator );
    462 }
    463 
    464 }
     478        PassVisitor<VTableCore> typeTranslator;
     479        mutateAll( translationUnit, typeTranslator );
     480}
     481
     482}
  • src/ControlStruct/MultiLevelExit.cpp

    rbf0263c r90a8125  
    1818#include "AST/Pass.hpp"
    1919#include "AST/Stmt.hpp"
     20#include "Common/CodeLocationTools.hpp"
    2021#include "LabelGeneratorNew.hpp"
    2122
     
    228229        // Labels on different stmts require different approaches to access
    229230        switch ( stmt->kind ) {
    230           case BranchStmt::Goto:
     231        case BranchStmt::Goto:
    231232                return stmt;
    232           case BranchStmt::Continue:
    233           case BranchStmt::Break: {
    234                   bool isContinue = stmt->kind == BranchStmt::Continue;
    235                   // Handle unlabeled break and continue.
    236                   if ( stmt->target.empty() ) {
    237                           if ( isContinue ) {
    238                                   targetEntry = findEnclosingControlStructure( isContinueTarget );
    239                           } else {
    240                                   if ( enclosing_control_structures.empty() ) {
     233        case BranchStmt::Continue:
     234        case BranchStmt::Break: {
     235                bool isContinue = stmt->kind == BranchStmt::Continue;
     236                // Handle unlabeled break and continue.
     237                if ( stmt->target.empty() ) {
     238                        if ( isContinue ) {
     239                                targetEntry = findEnclosingControlStructure( isContinueTarget );
     240                        } else {
     241                                if ( enclosing_control_structures.empty() ) {
    241242                                          SemanticError( stmt->location,
    242243                                                                         "'break' outside a loop, 'switch', or labelled block" );
    243                                   }
    244                                   targetEntry = findEnclosingControlStructure( isBreakTarget );
    245                           }
    246                           // Handle labeled break and continue.
    247                   } else {
    248                           // Lookup label in table to find attached control structure.
    249                           targetEntry = findEnclosingControlStructure(
    250                                   [ targetStmt = target_table.at(stmt->target) ](auto entry){
     244                                }
     245                                targetEntry = findEnclosingControlStructure( isBreakTarget );
     246                        }
     247                        // Handle labeled break and continue.
     248                } else {
     249                        // Lookup label in table to find attached control structure.
     250                        targetEntry = findEnclosingControlStructure(
     251                                [ targetStmt = target_table.at(stmt->target) ](auto entry){
    251252                                          return entry.stmt == targetStmt;
    252                                   } );
    253                   }
    254                   // Ensure that selected target is valid.
    255                   if ( targetEntry == enclosing_control_structures.rend() || ( isContinue && ! isContinueTarget( *targetEntry ) ) ) {
    256                           SemanticError( stmt->location, toString( (isContinue ? "'continue'" : "'break'"),
     253                                } );
     254                }
     255                // Ensure that selected target is valid.
     256                if ( targetEntry == enclosing_control_structures.rend() || ( isContinue && ! isContinueTarget( *targetEntry ) ) ) {
     257                        SemanticError( stmt->location, toString( (isContinue ? "'continue'" : "'break'"),
    257258                                                        " target must be an enclosing ", (isContinue ? "loop: " : "control structure: "),
    258259                                                        stmt->originalTarget ) );
    259                   }
    260                   break;
    261           }
    262           // handle fallthrough in case/switch stmts
    263           case BranchStmt::FallThrough: {
    264                   targetEntry = findEnclosingControlStructure( isFallthroughTarget );
    265                   // Check that target is valid.
    266                   if ( targetEntry == enclosing_control_structures.rend() ) {
    267                           SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );
    268                   }
    269                   if ( ! stmt->target.empty() ) {
    270                           // Labelled fallthrough: target must be a valid fallthough label.
    271                           if ( ! fallthrough_labels.count( stmt->target ) ) {
    272                                   SemanticError( stmt->location, toString( "'fallthrough' target must be a later case statement: ",
     260                }
     261                break;
     262        }
     263        // handle fallthrough in case/switch stmts
     264        case BranchStmt::FallThrough: {
     265                targetEntry = findEnclosingControlStructure( isFallthroughTarget );
     266                // Check that target is valid.
     267                if ( targetEntry == enclosing_control_structures.rend() ) {
     268                        SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );
     269                }
     270                if ( ! stmt->target.empty() ) {
     271                        // Labelled fallthrough: target must be a valid fallthough label.
     272                        if ( ! fallthrough_labels.count( stmt->target ) ) {
     273                                SemanticError( stmt->location, toString( "'fallthrough' target must be a later case statement: ",
    273274                                                                                                                   stmt->originalTarget ) );
    274                           }
    275                           return new BranchStmt( stmt->location, BranchStmt::Goto, stmt->originalTarget );
    276                   }
    277                   break;
    278           }
    279           case BranchStmt::FallThroughDefault: {
    280                   targetEntry = findEnclosingControlStructure( isFallthroughDefaultTarget );
    281 
    282                   // Check if in switch or choose statement.
    283                   if ( targetEntry == enclosing_control_structures.rend() ) {
    284                           SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );
    285                   }
    286 
    287                   // Check if switch or choose has default clause.
    288                   auto switchStmt = strict_dynamic_cast< const SwitchStmt * >( targetEntry->stmt );
    289                   bool foundDefault = false;
    290                   for ( auto caseStmt : switchStmt->cases ) {
    291                           if ( caseStmt->isDefault() ) {
    292                                   foundDefault = true;
    293                                   break;
    294                           }
    295                   }
    296                   if ( ! foundDefault ) {
    297                           SemanticError( stmt->location, "'fallthrough default' must be enclosed in a 'switch' or 'choose'"
    298                                                         "control structure with a 'default' clause" );
    299                   }
    300                   break;
    301           }
    302           default:
     275                        }
     276                        return new BranchStmt( stmt->location, BranchStmt::Goto, stmt->originalTarget );
     277                }
     278                break;
     279        }
     280        case BranchStmt::FallThroughDefault: {
     281                targetEntry = findEnclosingControlStructure( isFallthroughDefaultTarget );
     282
     283                // Check if in switch or choose statement.
     284                if ( targetEntry == enclosing_control_structures.rend() ) {
     285                        SemanticError( stmt->location, "'fallthrough' must be enclosed in a 'switch' or 'choose'" );
     286                }
     287
     288                // Check if switch or choose has default clause.
     289                auto switchStmt = strict_dynamic_cast< const SwitchStmt * >( targetEntry->stmt );
     290                bool foundDefault = false;
     291                for ( auto caseStmt : switchStmt->cases ) {
     292                        if ( caseStmt->isDefault() ) {
     293                                foundDefault = true;
     294                                break;
     295                        }
     296                }
     297                if ( ! foundDefault ) {
     298                        SemanticError( stmt->location, "'fallthrough default' must be enclosed in a 'switch' or 'choose'"
     299                                                  "control structure with a 'default' clause" );
     300                }
     301                break;
     302        }
     303        default:
    303304                assert( false );
    304305        }
     
    307308        Label exitLabel( CodeLocation(), "" );
    308309        switch ( stmt->kind ) {
    309           case BranchStmt::Break:
     310        case BranchStmt::Break:
    310311                assert( ! targetEntry->useBreakExit().empty() );
    311312                exitLabel = targetEntry->useBreakExit();
    312313                break;
    313           case BranchStmt::Continue:
     314        case BranchStmt::Continue:
    314315                assert( ! targetEntry->useContExit().empty() );
    315316                exitLabel = targetEntry->useContExit();
    316317                break;
    317           case BranchStmt::FallThrough:
     318        case BranchStmt::FallThrough:
    318319                assert( ! targetEntry->useFallExit().empty() );
    319320                exitLabel = targetEntry->useFallExit();
    320321                break;
    321           case BranchStmt::FallThroughDefault:
     322        case BranchStmt::FallThroughDefault:
    322323                assert( ! targetEntry->useFallDefaultExit().empty() );
    323324                exitLabel = targetEntry->useFallDefaultExit();
     
    327328                }
    328329                break;
    329           default:
     330        default:
    330331                assert(0);
    331332        }
     
    588589                }
    589590
     591                ptr<Stmt> else_stmt = nullptr;
     592                Stmt * loop_kid = nullptr;
     593                // check if loop node and if so add else clause if it exists
     594                const WhileDoStmt * whilePtr = dynamic_cast<const WhileDoStmt *>(kid.get());
     595                if ( whilePtr && whilePtr->else_) {
     596                        else_stmt = whilePtr->else_;
     597                        WhileDoStmt * mutate_ptr = mutate(whilePtr);
     598                        mutate_ptr->else_ = nullptr;
     599                        loop_kid = mutate_ptr;
     600                }
     601                const ForStmt * forPtr = dynamic_cast<const ForStmt *>(kid.get());
     602                if ( forPtr && forPtr->else_) {
     603                        else_stmt = forPtr->else_;
     604                        ForStmt * mutate_ptr = mutate(forPtr);
     605                        mutate_ptr->else_ = nullptr;
     606                        loop_kid = mutate_ptr;
     607                }
     608
    590609                try {
    591                         ret.push_back( kid->accept( *visitor ) );
     610                        if (else_stmt) ret.push_back( loop_kid->accept( *visitor ) );
     611                        else ret.push_back( kid->accept( *visitor ) );
    592612                } catch ( SemanticErrorException & e ) {
    593613                        errors.append( e );
    594614                }
    595615
    596                 // check if loop node and if so add else clause if it exists
    597                 const WhileDoStmt * whilePtr = dynamic_cast<const WhileDoStmt *>(kid.get());
    598                 if ( whilePtr && whilePtr->else_) ret.push_back(whilePtr->else_);
    599                 const ForStmt * forPtr = dynamic_cast<const ForStmt *>(kid.get());
    600                 if ( forPtr && forPtr->else_) ret.push_back(forPtr->else_);
     616                if (else_stmt) ret.push_back(else_stmt);
    601617
    602618                if ( ! break_label.empty() ) {
     
    618634        Pass<MultiLevelExitCore> visitor( labelTable );
    619635        const CompoundStmt * ret = stmt->accept( visitor );
    620         return ret;
     636        // There are some unset code locations slipping in, possibly by Labels.
     637        const Node * node = localFillCodeLocations( ret->location, ret );
     638        return strict_dynamic_cast<const CompoundStmt *>( node );
    621639}
    622640} // namespace ControlStruct
  • src/ControlStruct/module.mk

    rbf0263c r90a8125  
    1010## Author           : Richard C. Bilson
    1111## Created On       : Mon Jun  1 17:49:17 2015
    12 ## Last Modified By : Peter A. Buhr
    13 ## Last Modified On : Sat Jan 29 12:04:19 2022
    14 ## Update Count     : 7
     12## Last Modified By : Andrew Beach
     13## Last Modified On : Tue May 17 14:30:00 2022
     14## Update Count     : 8
    1515###############################################################################
    1616
    17 SRC_CONTROLSTRUCT = \
     17SRC += \
    1818        ControlStruct/ExceptDecl.cc \
    1919        ControlStruct/ExceptDecl.h \
     20        ControlStruct/ExceptTranslateNew.cpp \
     21        ControlStruct/ExceptTranslate.cc \
     22        ControlStruct/ExceptTranslate.h \
    2023        ControlStruct/FixLabels.cpp \
    2124        ControlStruct/FixLabels.hpp \
     
    3740        ControlStruct/Mutate.h
    3841
    39 SRC += $(SRC_CONTROLSTRUCT) \
    40         ControlStruct/ExceptTranslateNew.cpp \
    41         ControlStruct/ExceptTranslate.cc \
    42         ControlStruct/ExceptTranslate.h
    43 
    44 SRCDEMANGLE += $(SRC_CONTROLSTRUCT)
    45 
Note: See TracChangeset for help on using the changeset viewer.