Changeset 4e2b9710
- Timestamp:
- Aug 25, 2016, 9:14:18 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, 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:
- a839867
- Parents:
- c1c1112 (diff), 486341f (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:
-
- 2 added
- 28 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
rc1c1112 r4e2b9710 83 83 } 84 84 85 CodeGenerator::CodeGenerator( std::ostream & os ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this) {}85 CodeGenerator::CodeGenerator( std::ostream & os, bool mangle ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ), mangle( mangle ) {} 86 86 87 87 CodeGenerator::CodeGenerator( std::ostream & os, std::string init, int indentation, bool infunp ) … … 95 95 } 96 96 97 string mangleName( DeclarationWithType * decl ) { 97 string CodeGenerator::mangleName( DeclarationWithType * decl ) { 98 if ( ! mangle ) return decl->get_name(); 98 99 if ( decl->get_mangleName() != "" ) { 99 100 // need to incorporate scope level in order to differentiate names for destructors … … 311 312 Type * type = InitTweak::getPointerBase( (*arg)->get_results().front() ); 312 313 assert( type ); 313 newExpr->get_results().push_back( type );314 newExpr->get_results().push_back( type->clone() ); 314 315 *arg = newExpr; 315 316 } // if -
src/CodeGen/CodeGenerator.h
rc1c1112 r4e2b9710 30 30 static int tabsize; 31 31 32 CodeGenerator( std::ostream &os );32 CodeGenerator( std::ostream &os, bool mangle = true ); 33 33 CodeGenerator( std::ostream &os, std::string, int indent = 0, bool infun = false ); 34 34 CodeGenerator( std::ostream &os, char *, int indent = 0, bool infun = false ); … … 114 114 std::ostream &output; 115 115 LabelPrinter printLabels; 116 bool mangle = true; 116 117 117 118 void printDesignators( std::list< Expression * > & ); … … 119 120 void handleAggregate( AggregateDecl *aggDecl ); 120 121 void handleTypedef( NamedTypeDecl *namedType ); 122 std::string mangleName( DeclarationWithType * decl ); 121 123 }; // CodeGenerator 122 124 -
src/CodeGen/GenType.cc
rc1c1112 r4e2b9710 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // GenType.cc -- 7 // GenType.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 28 28 class GenType : public Visitor { 29 29 public: 30 GenType( const std::string &typeString );30 GenType( const std::string &typeString, bool mangle = true ); 31 31 std::string get_typeString() const { return typeString; } 32 32 void set_typeString( const std::string &newValue ) { typeString = newValue; } 33 33 34 34 virtual void visit( FunctionType *funcType ); 35 35 virtual void visit( VoidType *voidType ); … … 42 42 virtual void visit( TypeInstType *typeInst ); 43 43 virtual void visit( VarArgsType *varArgsType ); 44 44 45 45 private: 46 46 void handleQualifiers( Type *type ); 47 47 void genArray( const Type::Qualifiers &qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ); 48 48 49 49 std::string typeString; 50 bool mangle = true; 50 51 }; 51 52 52 std::string genType( Type *type, const std::string &baseString ) {53 GenType gt( baseString );53 std::string genType( Type *type, const std::string &baseString, bool mangle ) { 54 GenType gt( baseString, mangle ); 54 55 type->accept( gt ); 55 56 return gt.get_typeString(); 56 57 } 57 58 58 GenType::GenType( const std::string &typeString ) : typeString( typeString) {}59 GenType::GenType( const std::string &typeString, bool mangle ) : typeString( typeString ), mangle( mangle ) {} 59 60 60 61 void GenType::visit( VoidType *voidType ) { … … 100 101 } // if 101 102 if ( dimension != 0 ) { 102 CodeGenerator cg( os );103 CodeGenerator cg( os, mangle ); 103 104 dimension->accept( cg ); 104 105 } else if ( isVarLen ) { … … 109 110 110 111 typeString = os.str(); 111 112 112 113 base->accept( *this ); 113 114 } … … 142 143 } // if 143 144 } // if 144 145 145 146 /************* parameters ***************/ 146 147 … … 154 155 } // if 155 156 } else { 156 CodeGenerator cg( os );157 CodeGenerator cg( os, mangle ); 157 158 os << "(" ; 158 159 … … 164 165 os << ")"; 165 166 } // if 166 167 167 168 typeString = os.str(); 168 169 -
src/CodeGen/GenType.h
rc1c1112 r4e2b9710 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // GenType.h -- 7 // GenType.h -- 8 8 // 9 9 // Author : Richard C. Bilson … … 21 21 22 22 namespace CodeGen { 23 std::string genType( Type *type, const std::string &baseString );23 std::string genType( Type *type, const std::string &baseString, bool mangle = true ); 24 24 } // namespace CodeGen 25 25 -
src/Common/utility.h
rc1c1112 r4e2b9710 144 144 145 145 template < typename T > 146 std::string toString ( T value ) { 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 ) { 147 158 std::ostringstream os; 148 os << value; // << std::ends;159 toString_single( os, params... ); 149 160 return os.str(); 150 161 } … … 218 229 } 219 230 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 220 248 #endif // _UTILITY_H 221 249 -
src/InitTweak/FixInit.cc
rc1c1112 r4e2b9710 33 33 #include "GenPoly/PolyMutator.h" 34 34 #include "SynTree/AddStmtVisitor.h" 35 #include "CodeGen/GenType.h" // for warnings 35 36 36 37 bool ctordtorp = false; … … 174 175 virtual Expression * mutate( ImplicitCopyCtorExpr * impCpCtorExpr ); 175 176 }; 177 178 class WarnStructMembers : public Visitor { 179 public: 180 typedef Visitor Parent; 181 /// warn if a user-defined constructor or destructor is missing calls for 182 /// a struct member or if a member is used before constructed 183 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 }; 176 197 } // namespace 177 198 … … 187 208 // FixCopyCtors must happen after FixInit, so that destructors are placed correctly 188 209 FixCopyCtors::fixCopyCtors( translationUnit ); 210 211 WarnStructMembers::warnings( translationUnit ); 189 212 } 190 213 … … 231 254 } 232 255 256 void WarnStructMembers::warnings( std::list< Declaration * > & translationUnit ) { 257 if ( true ) { // fix this condition to skip this pass if warnings aren't enabled 258 WarnStructMembers warner; 259 acceptAll( translationUnit, warner ); 260 } 261 } 262 233 263 Expression * InsertImplicitCalls::mutate( ApplicationExpr * appExpr ) { 234 264 appExpr = dynamic_cast< ApplicationExpr * >( Mutator::mutate( appExpr ) ); … … 242 272 FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) ); 243 273 assert( ftype ); 244 if ( ( funcDecl->get_name() == "?{}"|| funcDecl->get_name() == "?=?") && ftype->get_parameters().size() == 2 ) {274 if ( (isConstructor( funcDecl->get_name() ) || funcDecl->get_name() == "?=?") && ftype->get_parameters().size() == 2 ) { 245 275 Type * t1 = ftype->get_parameters().front()->get_type(); 246 276 Type * t2 = ftype->get_parameters().back()->get_type(); … … 253 283 return appExpr; 254 284 } // if 255 } else if ( funcDecl->get_name() == "^?{}") {285 } else if ( isDestructor( funcDecl->get_name() ) ) { 256 286 // correctness: never copy construct arguments to a destructor 257 287 return appExpr; … … 284 314 UntypedExpr * untyped = new UntypedExpr( new NameExpr( fname ) ); 285 315 untyped->get_args().push_back( new AddressExpr( new VariableExpr( var ) ) ); 286 if (cpArg) untyped->get_args().push_back( cpArg );316 if (cpArg) untyped->get_args().push_back( cpArg->clone() ); 287 317 288 318 // resolve copy constructor … … 670 700 } // switch 671 701 } 702 703 bool checkWarnings( FunctionDecl * funcDecl ) { 704 // only check for warnings if the current function is a user-defined 705 // constructor or destructor 706 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 or 727 // destructed by the end of the function 728 unhandled.insert( field ); 729 } 730 } 731 } 732 } 733 Parent::visit( funcDecl ); 734 735 for ( DeclarationWithType * member : unhandled ) { 736 // emit a warning for each unhandled member 737 warn( "in ", CodeGen::genType( function->get_functionType(), function->get_name(), false ), ", 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 function 749 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 handles 753 // 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 then 759 // 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 constructors 764 // 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() ) ) return; 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 constructed 799 warn( "in ", CodeGen::genType( function->get_functionType(), function->get_name(), false ), ", member ", memberExpr->get_member()->get_name(), " used before being constructed" ); 800 } 801 } 802 } 803 } 804 } 805 Parent::visit( memberExpr ); 806 } 672 807 } // namespace 673 808 } // namespace InitTweak -
src/InitTweak/InitTweak.cc
rc1c1112 r4e2b9710 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 293 303 bool isIntrinsicSingleArgCallStmt( Statement * stmt ) { 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 ){ 304 return allofCtorDtor( stmt, []( Expression * callExpr ){ 298 305 if ( ApplicationExpr * appExpr = isIntrinsicCallExpr( callExpr ) ) { 299 306 assert( ! appExpr->get_function()->get_results().empty() ); … … 303 310 } 304 311 return false; 312 }); 313 } 314 315 bool isIntrinsicCallStmt( Statement * stmt ) { 316 return allofCtorDtor( stmt, []( Expression * callExpr ) { 317 return isIntrinsicCallExpr( callExpr ); 305 318 }); 306 319 } … … 420 433 } 421 434 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 ); } 422 438 } -
src/InitTweak/InitTweak.h
rc1c1112 r4e2b9710 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 28 32 /// transform Initializer into an argument list that can be passed to a call expression 29 33 std::list< Expression * > makeInitList( Initializer * init ); … … 41 45 /// Intended to be used for default ctor/dtor calls, but might have use elsewhere. 42 46 /// Currently has assertions that make it less than fully general. 43 bool isIntrinsicSingleArgCallStmt( Statement * expr ); 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 ); 44 51 45 52 /// get all Ctor/Dtor call expressions from a Statement -
src/Parser/DeclarationNode.cc
rc1c1112 r4e2b9710 50 50 newnode->isInline = isInline; 51 51 newnode->isNoreturn = isNoreturn; 52 newnode->bitfieldWidth = bitfieldWidth;52 newnode->bitfieldWidth = maybeClone( bitfieldWidth ); 53 53 newnode->hasEllipsis = hasEllipsis; 54 newnode->initializer = initializer;54 newnode->initializer = maybeClone( initializer ); 55 55 newnode->set_next( maybeClone( get_next() ) ); 56 56 newnode->linkage = linkage; … … 823 823 *out++ = decl; 824 824 } // if 825 delete extr; 825 826 } // if 826 827 Declaration *decl = cur->build(); -
src/Parser/LinkageSpec.cc
rc1c1112 r4e2b9710 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 ); 34 35 static const char *linkageKinds[LinkageSpec::NoOfSpecs] = { 35 36 "intrinsic", "Cforall", "C", "automatically generated", "compiler built-in", … … 39 40 40 41 bool LinkageSpec::isDecoratable( Spec spec ) { 42 assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs ); 41 43 static bool decoratable[LinkageSpec::NoOfSpecs] = { 42 44 // Intrinsic, Cforall, C, AutoGen, Compiler 43 true, true, false, true, false, 45 true, true, false, true, false, 44 46 }; 45 47 return decoratable[spec]; … … 47 49 48 50 bool LinkageSpec::isGeneratable( Spec spec ) { 51 assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs ); 49 52 static bool generatable[LinkageSpec::NoOfSpecs] = { 50 53 // Intrinsic, Cforall, C, AutoGen, Compiler 51 true, true, true, true, false, 54 true, true, true, true, false, 52 55 }; 53 56 return generatable[spec]; … … 55 58 56 59 bool LinkageSpec::isOverridable( Spec spec ) { 60 assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs ); 57 61 static bool overridable[LinkageSpec::NoOfSpecs] = { 58 62 // Intrinsic, Cforall, C, AutoGen, Compiler 59 true, false, false, true, false, 63 true, false, false, true, false, 60 64 }; 61 65 return overridable[spec]; … … 63 67 64 68 bool LinkageSpec::isBuiltin( Spec spec ) { 69 assert( spec >= 0 && spec < LinkageSpec::NoOfSpecs ); 65 70 static bool builtin[LinkageSpec::NoOfSpecs] = { 66 71 // Intrinsic, Cforall, C, AutoGen, Compiler 67 true, false, false, false, true, 72 true, false, false, false, true, 68 73 }; 69 74 return builtin[spec]; -
src/Parser/ParseNode.h
rc1c1112 r4e2b9710 109 109 ExpressionNode( const ExpressionNode &other ); 110 110 virtual ~ExpressionNode() {} 111 virtual ExpressionNode *clone() const { assert( false ); returnnullptr; }111 virtual ExpressionNode *clone() const { return expr ? new ExpressionNode( expr->clone() ) : nullptr; } 112 112 113 113 bool get_extension() const { return extension; } -
src/Parser/StatementNode.cc
rc1c1112 r4e2b9710 44 44 agg = decl; 45 45 } // if 46 stmt.reset( new DeclStmt( noLabels, maybe Build< Declaration >(agg) ) );46 stmt.reset( new DeclStmt( noLabels, maybeMoveBuild< Declaration >(agg) ) ); 47 47 } else { 48 48 assert( false ); -
src/Parser/TypeData.cc
rc1c1112 r4e2b9710 182 182 break; 183 183 case Array: 184 newtype->array->dimension = array->dimension;184 newtype->array->dimension = maybeClone( array->dimension ); 185 185 newtype->array->isVarLen = array->isVarLen; 186 186 newtype->array->isStatic = array->isStatic; -
src/ResolvExpr/AlternativeFinder.cc
rc1c1112 r4e2b9710 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 ->clone(), expr->clone() ), env, newCost ) );246 alternatives.push_back( Alternative( new MemberExpr( dwt, 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 ->clone()), env, Cost::zero ) );849 alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt ), env, Cost::zero ) ); 850 850 renameTypes( alternatives.back().expr ); 851 851 } else { -
src/ResolvExpr/Resolver.cc
rc1c1112 r4e2b9710 446 446 } else if ( StructInstType * st = dynamic_cast< StructInstType * >( initContext ) ) { 447 447 resolveAggrInit( st->get_baseStruct(), iter, end ); 448 } else if ( UnionInstType * st = dynamic_cast< UnionInstType * >( initContext ) ) {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 initContext 454 initContext = base; 455 visit( listInit ); 456 } else { 457 // missing implementation type -- might be an unknown type variable, so try proceeding with the current init context 458 Visitor::visit( listInit ); 459 } 450 460 } else { 461 assert( dynamic_cast< BasicType * >( initContext ) || dynamic_cast< PointerType * >( initContext ) ); 451 462 // basic types are handled here 452 463 Visitor::visit( listInit ); … … 539 550 } 540 551 541 // xxx - todo542 // if ( InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {543 // // can reduce the constructor down to a SingleInit using the544 // // second argument from the ctor call545 // }546 547 552 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->get_dtor() ) ) { 548 553 delete ctorInit->get_dtor(); 549 554 ctorInit->set_dtor( NULL ); 550 555 } 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 the 560 // // second argument from the ctor call, since 561 // delete ctorInit->get_ctor(); 562 // ctorInit->set_ctor( NULL ); 563 564 // Expression * arg = 565 // ctorInit->set_init( new SingleInit( arg ) ); 566 // } 551 567 } 552 568 } // namespace ResolvExpr -
src/ResolvExpr/TypeEnvironment.cc
rc1c1112 r4e2b9710 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 for 26 // some cases. The current resolution algorithm's speed partially depends on the order of 27 // assertions. Assertions which have fewer possible matches should appear before 28 // assertions which have more possible matches. This seems to imply that this could 29 // be further improved by providing an indexer as an additional argument and ordering based 30 // on the number of matches of the same kind (object, function) for the names of the 31 // 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 functions 36 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 order 39 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 order 48 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 parameters 58 // 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 vals 61 // int cmp = funcDecl1->get_name().compare( funcDecl2->get_name() ); 62 // if ( cmp < 0 ) return true; 63 // else if ( cmp > 0 ) return false; 64 // // same name 65 return ftype1 < ftype2; 66 } else { 67 return false; 68 } 69 } else { 70 assert( false ); 71 } 72 } 73 25 74 void printAssertionSet( const AssertionSet &assertions, std::ostream &os, int indent ) { 26 75 for ( AssertionSet::const_iterator i = assertions.begin(); i != assertions.end(); ++i ) { -
src/ResolvExpr/TypeEnvironment.h
rc1c1112 r4e2b9710 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 typedef std::map< DeclarationWithType*, bool > AssertionSet; 30 struct AssertCompare { 31 bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ); 32 }; 33 typedef std::map< DeclarationWithType*, bool, AssertCompare > AssertionSet; 31 34 typedef std::map< std::string, TypeDecl::Kind > OpenVarSet; 32 35 … … 39 42 bool allowWidening; 40 43 TypeDecl::Kind kind; 41 44 42 45 void initialize( const EqvClass &src, EqvClass &dest ); 43 46 EqvClass(); … … 62 65 void extractOpenVars( OpenVarSet &openVars ) const; 63 66 TypeEnvironment *clone() const { return new TypeEnvironment( *this ); } 64 67 65 68 typedef std::list< EqvClass >::iterator iterator; 66 69 iterator begin() { return env.begin(); } -
src/ResolvExpr/Unify.cc
rc1c1112 r4e2b9710 484 484 FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 ); 485 485 if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) { 486 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;486 if ( functionType->get_parameters().size() == otherFunction->get_parameters().size() && functionType->get_returnVals().size() == otherFunction->get_returnVals().size() ) { 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 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 } // if 495 495 } // if 496 496 } // if -
src/SymTab/Autogen.cc
rc1c1112 r4e2b9710 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( unionType) );70 copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) ); 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; }; generate 424 // 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 field 439 break; 440 } 441 } 442 422 443 declsToAdd.push_back( assignDecl ); 423 444 declsToAdd.push_back( ctorDecl ); 424 445 declsToAdd.push_back( copyCtorDecl ); 425 446 declsToAdd.push_back( dtorDecl ); 447 declsToAdd.splice( declsToAdd.end(), memCtors ); 426 448 } 427 449 -
src/SymTab/Validate.cc
rc1c1112 r4e2b9710 58 58 #include "Autogen.h" 59 59 #include "ResolvExpr/typeops.h" 60 #include <algorithm> 60 61 61 62 #define debugPrint( x ) if ( doDebug ) { std::cout << x; } … … 162 163 163 164 typedef std::map< std::string, std::pair< TypedefDecl *, int > > TypedefMap; 165 typedef std::map< std::string, TypeDecl * > TypeDeclMap; 164 166 TypedefMap typedefNames; 167 TypeDeclMap typedeclNames; 165 168 int scopeLevel; 166 169 }; … … 370 373 } // if 371 374 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() ) ); 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() ) ); 373 380 } 374 381 … … 521 528 delete typeInst; 522 529 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() ); 523 534 } // if 524 535 return typeInst; … … 565 576 typedefNames.erase( i ) ; 566 577 } // if 578 579 typedeclNames[ typeDecl->get_name() ] = typeDecl; 567 580 return typeDecl; 568 581 } -
src/SynTree/AggregateDecl.cc
rc1c1112 r4e2b9710 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
rc1c1112 r4e2b9710 200 200 201 201 OffsetofExpr::OffsetofExpr( const OffsetofExpr &other ) : 202 Expression( other ), type( maybeClone( other.type ) ), member( maybeClone( other.member )) {}202 Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {} 203 203 204 204 OffsetofExpr::~OffsetofExpr() { 205 205 delete type; 206 delete member;207 206 } 208 207 … … 359 358 assert( member ); 360 359 os << std::string( indent + 2, ' ' ); 360 os << (void*)member << " "; 361 361 member->print( os, indent + 2 ); 362 362 os << std::endl; … … 385 385 UntypedExpr::~UntypedExpr() { 386 386 delete function; 387 // deleteAll( args ); //TODO FIXME the arguments are leaked but they seem to be shared in some way387 deleteAll( args ); 388 388 } 389 389 -
src/SynTree/Initializer.cc
rc1c1112 r4e2b9710 43 43 44 44 SingleInit::~SingleInit() { 45 delete value; 45 46 deleteAll(designators); 46 47 } -
src/SynTree/TypeSubstitution.h
rc1c1112 r4e2b9710 169 169 TypeSubstitution sub = TypeSubstitution( formalBegin, formalEnd, actual ); 170 170 for ( std::list< Declaration* >::iterator i = memberBegin; i != memberEnd; ++i ) { 171 Declaration *newdecl = (*i)->clone(); 172 sub.apply( newdecl ); 173 *out++ = newdecl; 171 sub.apply( *i ); 172 *out++ = *i; 174 173 } // for 175 174 } -
src/tests/.expect/32/extension.txt
rc1c1112 r4e2b9710 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 } 72 77 __extension__ enum E { 73 78 __R__C2eE_1, … … 89 94 __extension__ int __c__i_2; 90 95 ((void)(__extension__ __a__i_2=(__extension__ __b__i_2+__extension__ __c__i_2))); 91 int _tmp_cp_ret 2;92 ((void)((_tmp_cp_ret 2=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret2));93 ((void)(_tmp_cp_ret 2) /* ^?{} */);96 int _tmp_cp_ret3; 97 ((void)((_tmp_cp_ret3=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret3)); 98 ((void)(_tmp_cp_ret3) /* ^?{} */); 94 99 ((void)__extension__ sizeof(3)); 95 100 ((void)__extension__ (((int )(3!=0)) || ((int )(4!=0)))); -
src/tests/.expect/64/extension.txt
rc1c1112 r4e2b9710 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 } 72 77 __extension__ enum E { 73 78 __R__C2eE_1, … … 89 94 __extension__ int __c__i_2; 90 95 ((void)(__extension__ __a__i_2=(__extension__ __b__i_2+__extension__ __c__i_2))); 91 int _tmp_cp_ret 2;92 ((void)((_tmp_cp_ret 2=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret2));93 ((void)(_tmp_cp_ret 2) /* ^?{} */);96 int _tmp_cp_ret3; 97 ((void)((_tmp_cp_ret3=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret3)); 98 ((void)(_tmp_cp_ret3) /* ^?{} */); 94 99 ((void)__extension__ sizeof(3)); 95 100 ((void)__extension__ (((int )(3!=0)) || ((int )(4!=0)))); -
src/tests/Makefile.am
rc1c1112 r4e2b9710 62 62 ${CC} ${CFLAGS} -CFA -XCFA -p ${<} -o ${@} 63 63 64 ctorWarnings: ctorWarnings.c 65 ${CC} ${CFALGS} -CFA -XCFA -p ${<} -o /dev/null 2> ${@} 66 -
src/tests/Makefile.in
rc1c1112 r4e2b9710 670 670 ${CC} ${CFLAGS} -CFA -XCFA -p ${<} -o ${@} 671 671 672 ctorWarnings: ctorWarnings.c 673 ${CC} ${CFALGS} -CFA -XCFA -p ${<} -o /dev/null 2> ${@} 674 672 675 # Tell versions [3.59,3.63) of GNU make to not export all variables. 673 676 # Otherwise a system limit (for SysV at least) may be exceeded.
Note: See TracChangeset
for help on using the changeset viewer.