Changes in / [0555f4b:f39096c]
- Location:
- src
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/GenType.h
r0555f4b rf39096c 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // GenType.h -- 7 // GenType.h -- 8 8 // 9 9 // Author : Richard C. Bilson -
src/Common/utility.h
r0555f4b rf39096c 144 144 145 145 template < typename T > 146 void toString_single ( std::ostream & os, const T & value ) { 147 os << value; 148 } 149 150 template < typename T, typename... Params > 151 void toString_single ( std::ostream & os, const T & value, const Params & ... params ) { 152 os << value; 153 toString_single( os, params ... ); 154 } 155 156 template < typename ... Params > 157 std::string toString ( const Params & ... params ) { 146 std::string toString ( T value ) { 158 147 std::ostringstream os; 159 toString_single( os, params... );148 os << value; // << std::ends; 160 149 return os.str(); 161 150 } … … 229 218 } 230 219 231 template< typename T >232 void warn_single( const T & arg ) {233 std::cerr << arg << std::endl;234 }235 236 template< typename T, typename... Params >237 void warn_single(const T & arg, const Params & ... params ) {238 std::cerr << arg;239 warn_single( params... );240 }241 242 template< typename... Params >243 void warn( const Params & ... params ) {244 std::cerr << "Warning: ";245 warn_single( params... );246 }247 248 220 #endif // _UTILITY_H 249 221 -
src/InitTweak/FixInit.cc
r0555f4b rf39096c 33 33 #include "GenPoly/PolyMutator.h" 34 34 #include "SynTree/AddStmtVisitor.h" 35 #include "CodeGen/GenType.h" // for warnings36 35 37 36 bool ctordtorp = false; … … 175 174 virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ); 176 175 }; 177 178 class WarnStructMembers : public Visitor {179 public:180 typedef Visitor Parent;181 /// warn if a user-defined constructor or destructor is missing calls for182 /// a struct member or if a member is used before constructed183 static void warnings( std::list< Declaration * > & translationUnit );184 185 virtual void visit( FunctionDecl * funcDecl );186 187 virtual void visit( MemberExpr * memberExpr );188 virtual void visit( ApplicationExpr * appExpr );189 190 private:191 void handleFirstParam( Expression * firstParam );192 193 FunctionDecl * function = 0;194 std::set< DeclarationWithType * > unhandled;195 ObjectDecl * thisParam = 0;196 };197 176 } // namespace 198 177 … … 208 187 // FixCopyCtors must happen after FixInit, so that destructors are placed correctly 209 188 FixCopyCtors::fixCopyCtors( translationUnit ); 210 211 WarnStructMembers::warnings( translationUnit );212 189 } 213 190 … … 254 231 } 255 232 256 void WarnStructMembers::warnings( std::list< Declaration * > & translationUnit ) {257 if ( true ) { // fix this condition to skip this pass if warnings aren't enabled258 WarnStructMembers warner;259 acceptAll( translationUnit, warner );260 }261 }262 263 233 Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) { 264 234 appExpr = dynamic_cast< ApplicationExpr * >( Mutator::mutate( appExpr ) ); … … 272 242 FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) ); 273 243 assert( ftype ); 274 if ( ( isConstructor( funcDecl->get_name() )|| funcDecl->get_name() == "?=?") && ftype->get_parameters().size() == 2 ) {244 if ( (funcDecl->get_name() == "?{}" || funcDecl->get_name() == "?=?") && ftype->get_parameters().size() == 2 ) { 275 245 Type * t1 = ftype->get_parameters().front()->get_type(); 276 246 Type * t2 = ftype->get_parameters().back()->get_type(); … … 283 253 return appExpr; 284 254 } // if 285 } else if ( isDestructor( funcDecl->get_name() )) {255 } else if ( funcDecl->get_name() == "^?{}" ) { 286 256 // correctness: never copy construct arguments to a destructor 287 257 return appExpr; … … 700 670 } // switch 701 671 } 702 703 bool checkWarnings( FunctionDecl * funcDecl ) {704 // only check for warnings if the current function is a user-defined705 // constructor or destructor706 if ( ! funcDecl ) return false;707 if ( ! funcDecl->get_statements() ) return false;708 return isCtorDtor( funcDecl->get_name() ) && ! LinkageSpec::isOverridable( funcDecl->get_linkage() );709 }710 711 void WarnStructMembers::visit( FunctionDecl * funcDecl ) {712 WarnStructMembers old = *this;713 *this = WarnStructMembers();714 715 function = funcDecl;716 if ( checkWarnings( funcDecl ) ) {717 FunctionType * type = funcDecl->get_functionType();718 assert( ! type->get_parameters().empty() );719 thisParam = safe_dynamic_cast< ObjectDecl * >( type->get_parameters().front() );720 PointerType * ptrType = safe_dynamic_cast< PointerType * > ( thisParam->get_type() );721 StructInstType * structType = dynamic_cast< StructInstType * >( ptrType->get_base() );722 if ( structType ) {723 StructDecl * structDecl = structType->get_baseStruct();724 for ( Declaration * member : structDecl->get_members() ) {725 if ( ObjectDecl * field = dynamic_cast< ObjectDecl * >( member ) ) {726 // record all of the struct type's members that need to be constructed or727 // destructed by the end of the function728 unhandled.insert( field );729 }730 }731 }732 }733 Parent::visit( funcDecl );734 735 for ( DeclarationWithType * member : unhandled ) {736 // emit a warning for each unhandled member737 warn( "in ", CodeGen::genType( function->get_functionType(), function->get_name() ), ", member ", member->get_name(), " may not have been ", isConstructor( funcDecl->get_name() ) ? "constructed" : "destructed" );738 }739 740 *this = old;741 }742 743 void WarnStructMembers::visit( ApplicationExpr * appExpr ) {744 if ( ! checkWarnings( function ) ) return;745 746 std::string fname = getFunctionName( appExpr );747 if ( fname == function->get_name() ) {748 // call to same kind of function749 Expression * firstParam = appExpr->get_args().front();750 751 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( firstParam ) ) {752 // if calling another constructor on thisParam, assume that function handles753 // all members - if it doesn't a warning will appear in that function.754 if ( varExpr->get_var() == thisParam ) {755 unhandled.clear();756 }757 } else {758 // if first parameter is a member expression then759 // remove the member from unhandled set.760 handleFirstParam( firstParam );761 }762 } else if ( fname == "?=?" && isIntrinsicCallExpr( appExpr ) ) {763 // forgive use of intrinsic assignment to construct, since instrinsic constructors764 // codegen as assignment anyway.765 assert( appExpr->get_args().size() == 2 );766 handleFirstParam( appExpr->get_args().front() );767 }768 769 Parent::visit( appExpr );770 }771 772 void WarnStructMembers::handleFirstParam( Expression * firstParam ) {773 using namespace std;774 if ( AddressExpr * addrExpr = dynamic_cast< AddressExpr * >( firstParam ) ) {775 if ( MemberExpr * memberExpr = dynamic_cast< MemberExpr * >( addrExpr->get_arg() ) ) {776 if ( ApplicationExpr * deref = dynamic_cast< ApplicationExpr * >( memberExpr->get_aggregate() ) ) {777 if ( getFunctionName( deref ) == "*?" && deref->get_args().size() == 1 ) {778 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( deref->get_args().front() ) ) {779 if ( varExpr->get_var() == thisParam ) {780 unhandled.erase( memberExpr->get_member() );781 }782 }783 }784 }785 }786 }787 }788 789 void WarnStructMembers::visit( MemberExpr * memberExpr ) {790 if ( ! checkWarnings( function ) ) return;791 if ( ! isConstructor( function->get_name() ) );792 793 if ( ApplicationExpr * deref = dynamic_cast< ApplicationExpr * >( memberExpr->get_aggregate() ) ) {794 if ( getFunctionName( deref ) == "*?" && deref->get_args().size() == 1 ) {795 if ( VariableExpr * varExpr = dynamic_cast< VariableExpr * >( deref->get_args().front() ) ) {796 if ( varExpr->get_var() == thisParam ) {797 if ( unhandled.count( memberExpr->get_member() ) ) {798 // emit a warning because a member was used before it was constructed799 warn( "in ", CodeGen::genType( function->get_functionType(), function->get_name() ), ", member ", memberExpr->get_member()->get_name(), " used before being constructed" );800 }801 }802 }803 }804 }805 Parent::visit( memberExpr );806 }807 672 } // namespace 808 673 } // namespace InitTweak -
src/InitTweak/InitTweak.cc
r0555f4b rf39096c 291 291 } 292 292 293 namespace {294 template <typename Predicate>295 bool allofCtorDtor( Statement * stmt, const Predicate & pred ) {296 std::list< Expression * > callExprs;297 collectCtorDtorCalls( stmt, callExprs );298 // if ( callExprs.empty() ) return false; // xxx - do I still need this check?299 return std::all_of( callExprs.begin(), callExprs.end(), pred);300 }301 }302 303 293 bool isIntrinsicSingleArgCallStmt( Statement * stmt ) { 304 return allofCtorDtor( stmt, []( Expression * callExpr ){ 294 std::list< Expression * > callExprs; 295 collectCtorDtorCalls( stmt, callExprs ); 296 // if ( callExprs.empty() ) return false; // xxx - do I still need this check? 297 return std::all_of( callExprs.begin(), callExprs.end(), []( Expression * callExpr ){ 305 298 if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) { 306 299 assert( ! appExpr->get_function()->get_results().empty() ); … … 310 303 } 311 304 return false; 312 });313 }314 315 bool isIntrinsicCallStmt( Statement * stmt ) {316 return allofCtorDtor( stmt, []( Expression * callExpr ) {317 return isIntrinsicCallExpr( callExpr );318 305 }); 319 306 } … … 433 420 } 434 421 435 bool isConstructor( const std::string & str ) { return str == "?{}"; }436 bool isDestructor( const std::string & str ) { return str == "^?{}"; }437 bool isCtorDtor( const std::string & str ) { return isConstructor( str ) || isDestructor( str ); }438 422 } -
src/InitTweak/InitTweak.h
r0555f4b rf39096c 26 26 // helper functions for initialization 27 27 namespace InitTweak { 28 bool isConstructor( const std::string & );29 bool isDestructor( const std::string & );30 bool isCtorDtor( const std::string & );31 32 28 /// transform Initializer into an argument list that can be passed to a call expression 33 29 std::list< Expression * > makeInitList( Initializer * init ); … … 45 41 /// Intended to be used for default ctor/dtor calls, but might have use elsewhere. 46 42 /// Currently has assertions that make it less than fully general. 47 bool isIntrinsicSingleArgCallStmt( Statement * stmt ); 48 49 /// True if stmt is a call statement where the function called is intrinsic. 50 bool isIntrinsicCallStmt( Statement * stmt ); 43 bool isIntrinsicSingleArgCallStmt( Statement * expr ); 51 44 52 45 /// get all Ctor/Dtor call expressions from a Statement -
src/Parser/LinkageSpec.cc
r0555f4b rf39096c 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // LinkageSpec.cc -- 8 // 7 // LinkageSpec.cc -- 8 // 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:22:09 2015 … … 12 12 // Last Modified On : Sun Aug 21 12:32:53 2016 13 13 // Update Count : 17 14 // 14 // 15 15 16 16 #include <string> … … 32 32 33 33 std::string LinkageSpec::toString( LinkageSpec::Spec linkage ) { 34 assert( linkage >= 0 && linkage < LinkageSpec::NoOfSpecs );35 34 static const char *linkageKinds[LinkageSpec::NoOfSpecs] = { 36 35 "intrinsic", "Cforall", "C", "automatically generated", "compiler built-in", … … 40 39 41 40 bool LinkageSpec::isDecoratable( Spec spec ) { 42 assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs );43 41 static bool decoratable[LinkageSpec::NoOfSpecs] = { 44 42 // Intrinsic, Cforall, C, AutoGen, Compiler 45 true, true, false, true, false, 43 true, true, false, true, false, 46 44 }; 47 45 return decoratable[spec]; … … 49 47 50 48 bool LinkageSpec::isGeneratable( Spec spec ) { 51 assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs );52 49 static bool generatable[LinkageSpec::NoOfSpecs] = { 53 50 // Intrinsic, Cforall, C, AutoGen, Compiler 54 true, true, true, true, false, 51 true, true, true, true, false, 55 52 }; 56 53 return generatable[spec]; … … 58 55 59 56 bool LinkageSpec::isOverridable( Spec spec ) { 60 assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs );61 57 static bool overridable[LinkageSpec::NoOfSpecs] = { 62 58 // Intrinsic, Cforall, C, AutoGen, Compiler 63 true, false, false, true, false, 59 true, false, false, true, false, 64 60 }; 65 61 return overridable[spec]; … … 67 63 68 64 bool LinkageSpec::isBuiltin( Spec spec ) { 69 assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs );70 65 static bool builtin[LinkageSpec::NoOfSpecs] = { 71 66 // Intrinsic, Cforall, C, AutoGen, Compiler 72 true, false, false, false, true, 67 true, false, false, false, true, 73 68 }; 74 69 return builtin[spec]; -
src/ResolvExpr/AlternativeFinder.cc
r0555f4b rf39096c 244 244 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 245 245 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 246 alternatives.push_back( Alternative( new MemberExpr( dwt , expr->clone() ), env, newCost ) );246 alternatives.push_back( Alternative( new MemberExpr( dwt->clone(), expr->clone() ), env, newCost ) ); 247 247 renameTypes( alternatives.back().expr ); 248 248 } else { … … 418 418 // /// Map of declaration uniqueIds (intended to be the assertions in an AssertionSet) to their parents and the number of times they've been included 419 419 //typedef std::unordered_map< UniqueId, std::unordered_map< UniqueId, unsigned > > AssertionParentSet; 420 420 421 421 static const int recursionLimit = /*10*/ 4; ///< Limit to depth of recursion satisfaction 422 422 //static const unsigned recursionParentLimit = 1; ///< Limit to the number of times an assertion can recursively use itself … … 429 429 } 430 430 } 431 431 432 432 template< typename ForwardIterator, typename OutputIterator > 433 void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, /*const AssertionParentSet &needParents,*/ 433 void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, /*const AssertionParentSet &needParents,*/ 434 434 int level, const SymTab::Indexer &indexer, OutputIterator out ) { 435 435 if ( begin == end ) { … … 469 469 std::cerr << std::endl; 470 470 ) 471 471 472 472 AssertionSet newHave, newerNeed( newNeed ); 473 473 TypeEnvironment newEnv( newAlt.env ); … … 847 847 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 848 848 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 849 alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt ), env, Cost::zero ) );849 alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt->clone() ), env, Cost::zero ) ); 850 850 renameTypes( alternatives.back().expr ); 851 851 } else { -
src/ResolvExpr/Resolver.cc
r0555f4b rf39096c 446 446 } else if ( StructInstType * st = dynamic_cast< StructInstType * >( initContext ) ) { 447 447 resolveAggrInit( st->get_baseStruct(), iter, end ); 448 } else if ( UnionInstType * 448 } else if ( UnionInstType *st = dynamic_cast< UnionInstType * >( initContext ) ) { 449 449 resolveAggrInit( st->get_baseUnion(), iter, end ); 450 } else if ( TypeInstType * tt = dynamic_cast< TypeInstType * >( initContext ) ) {451 Type * base = tt->get_baseType()->get_base();452 if ( base ) {453 // know the implementation type, so try using that as the initContext454 initContext = base;455 visit( listInit );456 } else {457 // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context458 Visitor::visit( listInit );459 }460 450 } else { 461 assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext ) );462 451 // basic types are handled here 463 452 Visitor::visit( listInit ); … … 550 539 } 551 540 541 // xxx - todo 542 // if ( InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) { 543 // // can reduce the constructor down to a SingleInit using the 544 // // second argument from the ctor call 545 // } 546 552 547 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) { 553 548 delete ctorInit->get_dtor(); 554 549 ctorInit->set_dtor( NULL ); 555 550 } 556 557 // xxx - todo -- what about arrays?558 // if ( dtor == NULL && InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {559 // // can reduce the constructor down to a SingleInit using the560 // // second argument from the ctor call, since561 // delete ctorInit->get_ctor();562 // ctorInit->set_ctor( NULL );563 564 // Expression * arg =565 // ctorInit->set_init( new SingleInit( arg ) );566 // }567 551 } 568 552 } // namespace ResolvExpr -
src/ResolvExpr/TypeEnvironment.cc
r0555f4b rf39096c 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // TypeEnvironment.cc -- 7 // TypeEnvironment.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 23 23 24 24 namespace ResolvExpr { 25 // adding this comparison operator significantly improves assertion resolution run time for26 // some cases. The current resolution algorithm's speed partially depends on the order of27 // assertions. Assertions which have fewer possible matches should appear before28 // assertions which have more possible matches. This seems to imply that this could29 // be further improved by providing an indexer as an additional argument and ordering based30 // on the number of matches of the same kind (object, function) for the names of the31 // declarations.32 //33 // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator.34 bool AssertCompare::operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) {35 // Objects are always less than functions36 if ( ObjectDecl * objectDecl1 = dynamic_cast< ObjectDecl * >( d1 ) ) {37 if ( ObjectDecl * objectDecl2 = dynamic_cast< ObjectDecl * >( d2 ) ) {38 // objects are ordered by name then type pointer, in that order39 int cmp = objectDecl1->get_name().compare( objectDecl2->get_name() );40 return cmp < 0 ||41 ( cmp == 0 && objectDecl1->get_type() < objectDecl2->get_type() );42 } else {43 return true;44 }45 } else if ( FunctionDecl * funcDecl1 = dynamic_cast< FunctionDecl * >( d1 ) ) {46 if ( FunctionDecl * funcDecl2 = dynamic_cast< FunctionDecl * >( d2 ) ) {47 // functions are ordered by name, # parameters, # returnVals, type pointer in that order48 FunctionType * ftype1 = funcDecl1->get_functionType();49 FunctionType * ftype2 = funcDecl2->get_functionType();50 int numThings1 = ftype1->get_parameters().size() + ftype1->get_returnVals().size();51 int numThings2 = ftype2->get_parameters().size() + ftype2->get_returnVals().size();52 if ( numThings1 < numThings2 ) return true;53 if ( numThings1 > numThings2 ) return false;54 55 // if ( ftype1->get_parameters().size() < ftype2->get_parameters().size() ) return true;56 // else if ( ftype1->get_parameters().size() > ftype2->get_parameters().size() ) return false;57 // // same number of parameters58 // if ( ftype1->get_returnVals().size() < ftype2->get_returnVals().size() ) return true;59 // else if ( ftype1->get_returnVals().size() > ftype2->get_returnVals().size() ) return false;60 // same number of return vals61 // int cmp = funcDecl1->get_name().compare( funcDecl2->get_name() );62 // if ( cmp < 0 ) return true;63 // else if ( cmp > 0 ) return false;64 // // same name65 return ftype1 < ftype2;66 } else {67 return false;68 }69 } else {70 assert( false );71 }72 }73 74 25 void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent ) { 75 26 for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) { -
src/ResolvExpr/TypeEnvironment.h
r0555f4b rf39096c 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // TypeEnvironment.h -- 7 // TypeEnvironment.h -- 8 8 // 9 9 // Author : Richard C. Bilson … … 28 28 29 29 namespace ResolvExpr { 30 struct AssertCompare { 31 bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ); 32 }; 33 typedef std::map< DeclarationWithType*, bool, AssertCompare > AssertionSet; 30 typedef std::map< DeclarationWithType*, bool > AssertionSet; 34 31 typedef std::map< std::string, TypeDecl::Kind > OpenVarSet; 35 32 … … 42 39 bool allowWidening; 43 40 TypeDecl::Kind kind; 44 41 45 42 void initialize( const EqvClass &src, EqvClass &dest ); 46 43 EqvClass(); … … 65 62 void extractOpenVars( OpenVarSet &openVars ) const; 66 63 TypeEnvironment *clone() const { return new TypeEnvironment( *this ); } 67 64 68 65 typedef std::list< EqvClass >::iterator iterator; 69 66 iterator begin() { return env.begin(); } -
src/ResolvExpr/Unify.cc
r0555f4b rf39096c 484 484 FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 ); 485 485 if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) { 486 if ( functionType->get_parameters().size() == otherFunction->get_parameters().size() && functionType->get_returnVals().size() == otherFunction->get_returnVals().size() ) { 487 488 if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 489 490 markAssertions( haveAssertions, needAssertions, functionType ); 491 markAssertions( haveAssertions, needAssertions, otherFunction);492 493 result = true; 494 } // if486 487 if ( unifyDeclList( functionType->get_parameters().begin(), functionType->get_parameters().end(), otherFunction->get_parameters().begin(), otherFunction->get_parameters().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 488 489 if ( unifyDeclList( functionType->get_returnVals().begin(), functionType->get_returnVals().end(), otherFunction->get_returnVals().begin(), otherFunction->get_returnVals().end(), env, needAssertions, haveAssertions, openVars, indexer ) ) { 490 491 markAssertions( haveAssertions, needAssertions, functionType ); 492 markAssertions( haveAssertions, needAssertions, otherFunction ); 493 494 result = true; 495 495 } // if 496 496 } // if -
src/SymTab/Autogen.cc
r0555f4b rf39096c 68 68 copy->get_args().push_back( new VariableExpr( dstParam ) ); 69 69 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 70 copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone()) );70 copy->get_args().push_back( new SizeofExpr( unionType ) ); 71 71 72 72 *out++ = new ExprStmt( noLabels, copy ); … … 420 420 copyCtorDecl->set_statements( assignDecl->get_statements()->clone() ); 421 421 422 // create a constructor which takes the first member type as a parameter.423 // for example, for Union A { int x; double y; }; generate424 // void ?{}(A *, int)425 // This is to mimic C's behaviour which initializes the first member of the union.426 std::list<Declaration *> memCtors;427 for ( Declaration * member : aggregateDecl->get_members() ) {428 if ( DeclarationWithType * field = dynamic_cast< DeclarationWithType * >( member ) ) {429 ObjectDecl * srcParam = new ObjectDecl( "src", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, field->get_type()->clone(), 0 );430 431 FunctionType * memCtorType = ctorType->clone();432 memCtorType->get_parameters().push_back( srcParam );433 FunctionDecl * ctor = new FunctionDecl( "?{}", functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, memCtorType, new CompoundStmt( noLabels ), true, false );434 ctor->fixUniqueId();435 436 makeUnionFieldsAssignment( srcParam, dstParam, cloneWithParams( refType, unionParams ), back_inserter( ctor->get_statements()->get_kids() ) );437 memCtors.push_back( ctor );438 // only generate a ctor for the first field439 break;440 }441 }442 443 422 declsToAdd.push_back( assignDecl ); 444 423 declsToAdd.push_back( ctorDecl ); 445 424 declsToAdd.push_back( copyCtorDecl ); 446 425 declsToAdd.push_back( dtorDecl ); 447 declsToAdd.splice( declsToAdd.end(), memCtors );448 426 } 449 427 -
src/SymTab/Validate.cc
r0555f4b rf39096c 58 58 #include "Autogen.h" 59 59 #include "ResolvExpr/typeops.h" 60 #include <algorithm>61 60 62 61 #define debugPrint( x ) if ( doDebug ) { std::cout << x; } … … 163 162 164 163 typedef std::map< std::string, std::pair< TypedefDecl *, int > > TypedefMap; 165 typedef std::map< std::string, TypeDecl * > TypeDeclMap;166 164 TypedefMap typedefNames; 167 TypeDeclMap typedeclNames;168 165 int scopeLevel; 169 166 }; … … 373 370 } // if 374 371 375 // need to clone members of the context for ownership purposes 376 std::list< Declaration * > members; 377 std::transform( ctx->get_members().begin(), ctx->get_members().end(), back_inserter( members ), [](Declaration * dwt) { return dwt->clone(); } ); 378 379 applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), members.begin(), members.end(), back_inserter( contextInst->get_members() ) ); 372 applySubstitution( ctx->get_parameters().begin(), ctx->get_parameters().end(), contextInst->get_parameters().begin(), ctx->get_members().begin(), ctx->get_members().end(), back_inserter( contextInst->get_members() ) ); 380 373 } 381 374 … … 528 521 delete typeInst; 529 522 return ret; 530 } else {531 TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );532 assert( base != typedeclNames.end() );533 typeInst->set_baseType( base->second->clone() );534 523 } // if 535 524 return typeInst; … … 576 565 typedefNames.erase( i ) ; 577 566 } // if 578 579 typedeclNames[ typeDecl->get_name() ] = typeDecl;580 567 return typeDecl; 581 568 } -
src/SynTree/AggregateDecl.cc
r0555f4b rf39096c 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // AggregateDecl.cc -- 7 // AggregateDecl.cc -- 8 8 // 9 9 // Author : Richard C. Bilson -
src/SynTree/Expression.cc
r0555f4b rf39096c 200 200 201 201 OffsetofExpr::OffsetofExpr( const OffsetofExpr &other ) : 202 Expression( other ), type( maybeClone( other.type ) ), member( other.member) {}202 Expression( other ), type( maybeClone( other.type ) ), member( maybeClone( other.member ) ) {} 203 203 204 204 OffsetofExpr::~OffsetofExpr() { 205 205 delete type; 206 delete member; 206 207 } 207 208 … … 358 359 assert( member ); 359 360 os << std::string( indent + 2, ' ' ); 360 os << (void*)member << " ";361 361 member->print( os, indent + 2 ); 362 362 os << std::endl; -
src/SynTree/TypeSubstitution.h
r0555f4b rf39096c 169 169 TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual ); 170 170 for ( std::list< Declaration* >::iterator i = memberBegin; i != memberEnd; ++i ) { 171 sub.apply( *i ); 172 *out++ = *i; 171 Declaration *newdecl = (*i)->clone(); 172 sub.apply( newdecl ); 173 *out++ = newdecl; 173 174 } // for 174 175 } -
src/tests/.expect/32/extension.txt
r0555f4b rf39096c 70 70 static inline void ___destructor__F_P2uU_autogen___1(union U *___dst__P2uU_1){ 71 71 } 72 static inline void ___constructor__F_P2uUi_autogen___1(union U *___dst__P2uU_1, int __src__i_1){73 void *_tmp_cp_ret2;74 ((void)((_tmp_cp_ret2=__builtin_memcpy(((void *)___dst__P2uU_1), ((const void *)(&__src__i_1)), sizeof(int ))) , _tmp_cp_ret2));75 ((void)(_tmp_cp_ret2) /* ^?{} */);76 }77 72 __extension__ enum E { 78 73 __R__C2eE_1, … … 94 89 __extension__ int __c__i_2; 95 90 ((void)(__extension__ __a__i_2=(__extension__ __b__i_2+__extension__ __c__i_2))); 96 int _tmp_cp_ret 3;97 ((void)((_tmp_cp_ret 3=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret3));98 ((void)(_tmp_cp_ret 3) /* ^?{} */);91 int _tmp_cp_ret2; 92 ((void)((_tmp_cp_ret2=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret2)); 93 ((void)(_tmp_cp_ret2) /* ^?{} */); 99 94 ((void)__extension__ sizeof(3)); 100 95 ((void)__extension__ (((int )(3!=0)) || ((int )(4!=0)))); -
src/tests/.expect/64/extension.txt
r0555f4b rf39096c 70 70 static inline void ___destructor__F_P2uU_autogen___1(union U *___dst__P2uU_1){ 71 71 } 72 static inline void ___constructor__F_P2uUi_autogen___1(union U *___dst__P2uU_1, int __src__i_1){73 void *_tmp_cp_ret2;74 ((void)((_tmp_cp_ret2=__builtin_memcpy(((void *)___dst__P2uU_1), ((const void *)(&__src__i_1)), sizeof(int ))) , _tmp_cp_ret2));75 ((void)(_tmp_cp_ret2) /* ^?{} */);76 }77 72 __extension__ enum E { 78 73 __R__C2eE_1, … … 94 89 __extension__ int __c__i_2; 95 90 ((void)(__extension__ __a__i_2=(__extension__ __b__i_2+__extension__ __c__i_2))); 96 int _tmp_cp_ret 3;97 ((void)((_tmp_cp_ret 3=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret3));98 ((void)(_tmp_cp_ret 3) /* ^?{} */);91 int _tmp_cp_ret2; 92 ((void)((_tmp_cp_ret2=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret2)); 93 ((void)(_tmp_cp_ret2) /* ^?{} */); 99 94 ((void)__extension__ sizeof(3)); 100 95 ((void)__extension__ (((int )(3!=0)) || ((int )(4!=0))));
Note:
See TracChangeset
for help on using the changeset viewer.