- Timestamp:
- Apr 11, 2017, 4:20:51 PM (9 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:
- 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. - Location:
- src
- Files:
-
- 8 edited
-
ControlStruct/LabelGenerator.cc (modified) (2 diffs)
-
ControlStruct/LabelGenerator.h (modified) (2 diffs)
-
ControlStruct/MLEMutator.cc (modified) (6 diffs)
-
ResolvExpr/AlternativeFinder.cc (modified) (5 diffs)
-
ResolvExpr/AlternativeFinder.h (modified) (1 diff)
-
SymTab/Autogen.cc (modified) (1 diff)
-
SymTab/Validate.cc (modified) (3 diffs)
-
SynTree/Expression.cc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/LabelGenerator.cc
ra0fc78a rf674479 20 20 #include "SynTree/Label.h" 21 21 #include "SynTree/Attribute.h" 22 #include "SynTree/Statement.h" 22 23 23 24 namespace ControlStruct { … … 31 32 } 32 33 33 Label LabelGenerator::newLabel( std::string suffix ) {34 Label LabelGenerator::newLabel( std::string suffix, Statement * stmt ) { 34 35 std::ostringstream os; 35 36 os << "__L" << current++ << "__" << suffix; 37 if ( stmt && ! stmt->get_labels().empty() ) { 38 os << "_" << stmt->get_labels().front() << "__"; 39 } 36 40 std::string ret = os.str(); 37 41 Label l( ret ); -
src/ControlStruct/LabelGenerator.h
ra0fc78a rf674479 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // LabelGenerator.h -- 7 // LabelGenerator.h -- 8 8 // 9 9 // Author : Rodolfo G. Esteves … … 24 24 public: 25 25 static LabelGenerator *getGenerator(); 26 Label newLabel(std::string suffix = "");26 Label newLabel(std::string suffix, Statement * stmt = nullptr); 27 27 void reset() { current = 0; } 28 28 void rewind() { current--; } -
src/ControlStruct/MLEMutator.cc
ra0fc78a rf674479 56 56 bool labeledBlock = !(cmpndStmt->get_labels().empty()); 57 57 if ( labeledBlock ) { 58 Label brkLabel = generator->newLabel("blockBreak" );58 Label brkLabel = generator->newLabel("blockBreak", cmpndStmt); 59 59 enclosingControlStructures.push_back( Entry( cmpndStmt, brkLabel ) ); 60 60 } // if … … 80 80 // whether brkLabel and contLabel are used with branch statements and will recursively do the same to nested 81 81 // 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); 84 84 enclosingControlStructures.push_back( Entry( loopStmt, brkLabel, contLabel ) ); 85 85 loopStmt->set_body ( loopStmt->get_body()->acceptMutator( *this ) ); 86 86 87 assert( ! enclosingControlStructures.empty() ); 87 88 Entry &e = enclosingControlStructures.back(); 88 89 // sanity check that the enclosing loops have been popped correctly … … 108 109 bool labeledBlock = !(ifStmt->get_labels().empty()); 109 110 if ( labeledBlock ) { 110 Label brkLabel = generator->newLabel("blockBreak" );111 Label brkLabel = generator->newLabel("blockBreak", ifStmt); 111 112 enclosingControlStructures.push_back( Entry( ifStmt, brkLabel ) ); 112 113 } // if 113 114 114 115 Parent::mutate( ifStmt ); 115 116 116 117 if ( labeledBlock ) { 117 118 if ( ! enclosingControlStructures.back().useBreakExit().empty() ) { … … 126 127 Statement *MLEMutator::handleSwitchStmt( SwitchClass *switchStmt ) { 127 128 // generate a label for breaking out of a labeled switch 128 Label brkLabel = generator->newLabel("switchBreak" );129 Label brkLabel = generator->newLabel("switchBreak", switchStmt); 129 130 enclosingControlStructures.push_back( Entry(switchStmt, brkLabel) ); 130 131 mutateAll( switchStmt->get_statements(), *this ); … … 158 159 159 160 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 183 190 184 191 // branch error checks, get the appropriate label name and create a goto … … 197 204 } // switch 198 205 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 ); 209 209 } 210 210 -
src/ResolvExpr/AlternativeFinder.cc
ra0fc78a rf674479 211 211 } 212 212 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 } 214 226 215 227 template< typename StructOrUnionType > … … 220 232 std::list< Declaration* > members; 221 233 aggInst->lookup( name, members ); 234 222 235 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 223 236 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 224 237 alternatives.push_back( Alternative( new MemberExpr( dwt, expr->clone() ), env, newCost ) ); 225 238 renameTypes( alternatives.back().expr ); 239 addAnonConversions( alternatives.back() ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression. 226 240 } else { 227 241 assert( false ); … … 730 744 if ( candidates.empty() && ! errors.isEmpty() ) { throw errors; } 731 745 746 // compute conversionsion costs 732 747 for ( AltList::iterator withFunc = candidates.begin(); withFunc != candidates.end(); ++withFunc ) { 733 748 Cost cvtCost = computeConversionCost( *withFunc, indexer ); … … 751 766 } // if 752 767 } // 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 753 773 candidates.clear(); 754 774 candidates.splice( candidates.end(), alternatives ); … … 885 905 ) 886 906 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. 894 908 } // for 895 909 } -
src/ResolvExpr/AlternativeFinder.h
ra0fc78a rf674479 78 78 void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out ); 79 79 80 /// Adds alternatives for anonymous members 81 void addAnonConversions( const Alternative & alt ); 80 82 /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member 81 83 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); -
src/SymTab/Autogen.cc
ra0fc78a rf674479 498 498 makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) ); 499 499 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 ) ) ); 502 501 } 503 502 } -
src/SymTab/Validate.cc
ra0fc78a rf674479 208 208 }; 209 209 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 210 224 class CompoundLiteral final : public GenPoly::DeclMutator { 211 225 Type::StorageClasses storageClasses; … … 235 249 acceptAll( translationUnit, pass3 ); 236 250 VerifyCtorDtorAssign::verify( translationUnit ); 251 ArrayLength::computeLength( translationUnit ); 237 252 } 238 253 … … 869 884 } 870 885 } 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 } 871 900 } // namespace SymTab 872 901 -
src/SynTree/Expression.cc
ra0fc78a rf674479 339 339 return TypeSubstitution( aggInst->get_baseParameters()->begin(), aggInst->get_baseParameters()->end(), aggInst->get_parameters().begin() ); 340 340 } 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() ); 342 342 } 343 343 }
Note:
See TracChangeset
for help on using the changeset viewer.