Changeset f674479 for src


Ignore:
Timestamp:
Apr 11, 2017, 4:20:51 PM (9 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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:
da1c772
Parents:
a0fc78a (diff), 32bcef7 (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 plg2:software/cfa/cfa-cc

Location:
src
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/LabelGenerator.cc

    ra0fc78a rf674479  
    2020#include "SynTree/Label.h"
    2121#include "SynTree/Attribute.h"
     22#include "SynTree/Statement.h"
    2223
    2324namespace ControlStruct {
     
    3132        }
    3233
    33         Label LabelGenerator::newLabel( std::string suffix ) {
     34        Label LabelGenerator::newLabel( std::string suffix, Statement * stmt ) {
    3435                std::ostringstream os;
    3536                os << "__L" << current++ << "__" << suffix;
     37                if ( stmt && ! stmt->get_labels().empty() ) {
     38                        os << "_" << stmt->get_labels().front() << "__";
     39                }
    3640                std::string ret = os.str();
    3741                Label l( ret );
  • src/ControlStruct/LabelGenerator.h

    ra0fc78a rf674479  
    55// file "LICENCE" distributed with Cforall.
    66//
    7 // LabelGenerator.h -- 
     7// LabelGenerator.h --
    88//
    99// Author           : Rodolfo G. Esteves
     
    2424          public:
    2525                static LabelGenerator *getGenerator();
    26                 Label newLabel(std::string suffix = "");
     26                Label newLabel(std::string suffix, Statement * stmt = nullptr);
    2727                void reset() { current = 0; }
    2828                void rewind() { current--; }
  • src/ControlStruct/MLEMutator.cc

    ra0fc78a rf674479  
    5656                bool labeledBlock = !(cmpndStmt->get_labels().empty());
    5757                if ( labeledBlock ) {
    58                         Label brkLabel = generator->newLabel("blockBreak");
     58                        Label brkLabel = generator->newLabel("blockBreak", cmpndStmt);
    5959                        enclosingControlStructures.push_back( Entry( cmpndStmt, brkLabel ) );
    6060                } // if
     
    8080                // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested
    8181                // loops
    82                 Label brkLabel = generator->newLabel("loopBreak");
    83                 Label contLabel = generator->newLabel("loopContinue");
     82                Label brkLabel = generator->newLabel("loopBreak", loopStmt);
     83                Label contLabel = generator->newLabel("loopContinue", loopStmt);
    8484                enclosingControlStructures.push_back( Entry( loopStmt, brkLabel, contLabel ) );
    8585                loopStmt->set_body ( loopStmt->get_body()->acceptMutator( *this ) );
    8686
     87                assert( ! enclosingControlStructures.empty() );
    8788                Entry &e = enclosingControlStructures.back();
    8889                // sanity check that the enclosing loops have been popped correctly
     
    108109                bool labeledBlock = !(ifStmt->get_labels().empty());
    109110                if ( labeledBlock ) {
    110                         Label brkLabel = generator->newLabel("blockBreak");
     111                        Label brkLabel = generator->newLabel("blockBreak", ifStmt);
    111112                        enclosingControlStructures.push_back( Entry( ifStmt, brkLabel ) );
    112113                } // if
    113114
    114115                Parent::mutate( ifStmt );
    115                
     116
    116117                if ( labeledBlock ) {
    117118                        if ( ! enclosingControlStructures.back().useBreakExit().empty() ) {
     
    126127        Statement *MLEMutator::handleSwitchStmt( SwitchClass *switchStmt ) {
    127128                // generate a label for breaking out of a labeled switch
    128                 Label brkLabel = generator->newLabel("switchBreak");
     129                Label brkLabel = generator->newLabel("switchBreak", switchStmt);
    129130                enclosingControlStructures.push_back( Entry(switchStmt, brkLabel) );
    130131                mutateAll( switchStmt->get_statements(), *this );
     
    158159
    159160                std::list< Entry >::reverse_iterator targetEntry;
    160                 if ( branchStmt->get_type() == BranchStmt::Goto ) {
    161                         return branchStmt;
    162                 } else if ( branchStmt->get_type() == BranchStmt::Continue) {
    163                         // continue target must be a loop
    164                         if ( branchStmt->get_target() == "" ) {
    165                                 targetEntry = std::find_if( enclosingControlStructures.rbegin(), enclosingControlStructures.rend(), [](Entry &e) { return isLoop( e.get_controlStructure() ); } );
    166                         } else {
    167                                 // labelled continue - lookup label in table ot find attached control structure
    168                                 targetEntry = std::find( enclosingControlStructures.rbegin(), enclosingControlStructures.rend(), (*targetTable)[branchStmt->get_target()] );
    169                         } // if
    170                         if ( targetEntry == enclosingControlStructures.rend() || ! isLoop( targetEntry->get_controlStructure() ) ) {
    171                                 throw SemanticError( "'continue' target must be an enclosing loop: " + originalTarget );
    172                         } // if
    173                 } else if ( branchStmt->get_type() == BranchStmt::Break ) {
    174                         if ( enclosingControlStructures.empty() ) throw SemanticError( "'break' outside a loop, switch, or labelled block" );
    175                         targetEntry = enclosingControlStructures.rbegin();
    176                 } else {
    177                         assert( false );
    178                 } // if
    179 
    180                 if ( branchStmt->get_target() != "" && targetTable->find( branchStmt->get_target() ) == targetTable->end() ) {
    181                         throw SemanticError("The label defined in the exit loop statement does not exist: " + originalTarget );  // shouldn't happen (since that's already checked)
    182                 } // if
     161                switch ( branchStmt->get_type() ) {
     162                        case BranchStmt::Goto:
     163                                return branchStmt;
     164                        case BranchStmt::Continue:
     165                        case BranchStmt::Break: {
     166                                bool isContinue = branchStmt->get_type() == BranchStmt::Continue;
     167                                // unlabeled break/continue
     168                                if ( branchStmt->get_target() == "" ) {
     169                                        if ( isContinue ) {
     170                                                // continue target is outermost loop
     171                                                targetEntry = std::find_if( enclosingControlStructures.rbegin(), enclosingControlStructures.rend(), [](Entry &e) { return isLoop( e.get_controlStructure() ); } );
     172                                        } else {
     173                                                // break target is outmost control structure
     174                                                if ( enclosingControlStructures.empty() ) throw SemanticError( "'break' outside a loop, switch, or labelled block" );
     175                                                targetEntry = enclosingControlStructures.rbegin();
     176                                        } // if
     177                                } else {
     178                                        // labeled break/continue - lookup label in table to find attached control structure
     179                                        targetEntry = std::find( enclosingControlStructures.rbegin(), enclosingControlStructures.rend(), (*targetTable)[branchStmt->get_target()] );
     180                                } // if
     181                                // ensure that selected target is valid
     182                                if ( targetEntry == enclosingControlStructures.rend() || (isContinue && ! isLoop( targetEntry->get_controlStructure() ) ) ) {
     183                                        throw SemanticError( toString( (isContinue ? "'continue'" : "'break'"), " target must be an enclosing ", (isContinue ? "loop: " : "control structure: "), originalTarget ) );
     184                                } // if
     185                                break;
     186                        }
     187                        default:
     188                                assert( false );
     189                } // switch
    183190
    184191                // branch error checks, get the appropriate label name and create a goto
     
    197204                } // switch
    198205
    199                 if ( branchStmt->get_target() == "" && branchStmt->get_type() != BranchStmt::Continue ) {
    200                         // unlabelled break/continue - can keep branch as break/continue for extra semantic information, but add
    201                         // exitLabel as its destination so that label passes can easily determine where the break/continue goes to
    202                         branchStmt->set_target( exitLabel );
    203                         return branchStmt;
    204                 } else {
    205                         // labelled break/continue - can't easily emulate this with break and continue, so transform into a goto
    206                         delete branchStmt;
    207                         return new BranchStmt( std::list<Label>(), exitLabel, BranchStmt::Goto );
    208                 } // if
     206                // transform break/continue statements into goto to simplify later handling of branches
     207                delete branchStmt;
     208                return new BranchStmt( std::list<Label>(), exitLabel, BranchStmt::Goto );
    209209        }
    210210
  • src/ResolvExpr/AlternativeFinder.cc

    ra0fc78a rf674479  
    211211        }
    212212
    213         // std::unordered_map< Expression *, UniqueExpr * > ;
     213        void AlternativeFinder::addAnonConversions( const Alternative & alt ) {
     214                // adds anonymous member interpretations whenever an aggregate value type is seen.
     215                Expression * expr = alt.expr->clone();
     216                std::unique_ptr< Expression > manager( expr ); // RAII for expr
     217                alt.env.apply( expr->get_result() );
     218                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( expr->get_result() ) ) {
     219                        NameExpr nameExpr( "" );
     220                        addAggMembers( structInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr );
     221                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( expr->get_result() ) ) {
     222                        NameExpr nameExpr( "" );
     223                        addAggMembers( unionInst, expr, alt.cost+Cost( 0, 0, 1 ), alt.env, &nameExpr );
     224                } // if
     225        }
    214226
    215227        template< typename StructOrUnionType >
     
    220232                std::list< Declaration* > members;
    221233                aggInst->lookup( name, members );
     234
    222235                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
    223236                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
    224237                                alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) );
    225238                                renameTypes( alternatives.back().expr );
     239                                addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression.
    226240                        } else {
    227241                                assert( false );
     
    730744                if ( candidates.empty() && ! errors.isEmpty() ) { throw errors; }
    731745
     746                // compute conversionsion costs
    732747                for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) {
    733748                        Cost cvtCost = computeConversionCost( *withFunc, indexer );
     
    751766                        } // if
    752767                } // for
     768                // function may return struct or union value, in which case we need to add alternatives for implicit conversions to each of the anonymous members
     769                for ( const Alternative & alt : alternatives ) {
     770                        addAnonConversions( alt );
     771                }
     772
    753773                candidates.clear();
    754774                candidates.splice( candidates.end(), alternatives );
     
    885905                        )
    886906                        renameTypes( alternatives.back().expr );
    887                         if ( StructInstType *structInst = dynamic_cast< StructInstType* >( (*i)->get_type() ) ) {
    888                                 NameExpr nameExpr( "" );
    889                                 addAggMembers( structInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
    890                         } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( (*i)->get_type() ) ) {
    891                                 NameExpr nameExpr( "" );
    892                                 addAggMembers( unionInst, &newExpr, Cost( 0, 0, 1 ), env, &nameExpr );
    893                         } // if
     907                        addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a name expression.
    894908                } // for
    895909        }
  • src/ResolvExpr/AlternativeFinder.h

    ra0fc78a rf674479  
    7878                void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out );
    7979
     80                /// Adds alternatives for anonymous members
     81                void addAnonConversions( const Alternative & alt );
    8082                /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
    8183                template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member );
  • src/SymTab/Autogen.cc

    ra0fc78a rf674479  
    498498                makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) );
    499499                if ( returnVal ) {
    500                         if ( isDynamicLayout ) makeUnionFieldsAssignment( srcParam, returnVal, back_inserter( funcDecl->get_statements()->get_kids() ) );
    501                         else funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
     500                        funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) );
    502501                }
    503502        }
  • src/SymTab/Validate.cc

    ra0fc78a rf674479  
    208208        };
    209209
     210        class ArrayLength : public Visitor {
     211        public:
     212                /// for array types without an explicit length, compute the length and store it so that it
     213                /// is known to the rest of the phases. For example,
     214                ///   int x[] = { 1, 2, 3 };
     215                ///   int y[][2] = { { 1, 2, 3 }, { 1, 2, 3 } };
     216                /// here x and y are known at compile-time to have length 3, so change this into
     217                ///   int x[3] = { 1, 2, 3 };
     218                ///   int y[3][2] = { { 1, 2, 3 }, { 1, 2, 3 } };
     219                static void computeLength( std::list< Declaration * > & translationUnit );
     220
     221                virtual void visit( ObjectDecl * objDecl );
     222        };
     223
    210224        class CompoundLiteral final : public GenPoly::DeclMutator {
    211225                Type::StorageClasses storageClasses;
     
    235249                acceptAll( translationUnit, pass3 );
    236250                VerifyCtorDtorAssign::verify( translationUnit );
     251                ArrayLength::computeLength( translationUnit );
    237252        }
    238253
     
    869884                }
    870885        }
     886
     887        void ArrayLength::computeLength( std::list< Declaration * > & translationUnit ) {
     888                ArrayLength len;
     889                acceptAll( translationUnit, len );
     890        }
     891
     892        void ArrayLength::visit( ObjectDecl * objDecl ) {
     893                if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
     894                        if ( at->get_dimension() != nullptr ) return;
     895                        if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->get_init() ) ) {
     896                                at->set_dimension( new ConstantExpr( Constant::from_ulong( init->get_initializers().size() ) ) );
     897                        }
     898                }
     899        }
    871900} // namespace SymTab
    872901
  • src/SynTree/Expression.cc

    ra0fc78a rf674479  
    339339                        return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->get_parameters().begin() );
    340340                } else {
    341                         assertf( false, "makeSub expects struct or union type for aggregate" );
     341                        assertf( false, "makeSub expects struct or union type for aggregate, but got: %s", toString( t ).c_str() );
    342342                }
    343343        }
Note: See TracChangeset for help on using the changeset viewer.