Changes in / [1d832f4:af43394]
- Files:
-
- 2 deleted
- 13 edited
-
doc/theses/aaron_moss_PhD/phd/background.tex (modified) (1 diff)
-
doc/theses/aaron_moss_PhD/phd/resolution-heuristics.tex (modified) (1 diff)
-
driver/cfa.cc (modified) (4 diffs)
-
libcfa/src/concurrency/coroutine.cfa (modified) (1 diff)
-
src/Concurrency/Keywords.cc (modified) (2 diffs)
-
src/Concurrency/Waitfor.cc (modified) (4 diffs)
-
src/ResolvExpr/AlternativeFinder.cc (modified) (3 diffs)
-
src/ResolvExpr/ResolveAssertions.cc (modified) (13 diffs)
-
src/SymTab/Mangler.cc (modified) (6 diffs)
-
src/SymTab/Mangler.h (modified) (2 diffs)
-
src/main.cc (modified) (2 diffs)
-
tests/abort.cfa (deleted)
-
tests/pybin/print-core.gdb (deleted)
-
tests/pybin/tools.py (modified) (4 diffs)
-
tests/test.py (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/aaron_moss_PhD/phd/background.tex
r1d832f4 raf43394 213 213 The ability of types to begin or cease to satisfy traits when declarations go into or out of scope makes caching of trait satisfaction judgements difficult, and the ability of traits to take multiple type parameters can lead to a combinatorial explosion of work in any attempt to pre-compute trait satisfaction relationships. 214 214 215 \subsection{Implicit Conversions} \label{implicit-conv-sec}215 \subsection{Implicit Conversions} 216 216 217 217 In addition to the multiple interpretations of an expression produced by name overloading and polymorphic functions, for backward compatibility \CFA{} must support all of the implicit conversions present in C, producing further candidate interpretations for expressions. -
doc/theses/aaron_moss_PhD/phd/resolution-heuristics.tex
r1d832f4 raf43394 2 2 \label{resolution-chap} 3 3 4 The main task of the \CFACC{} type-checker is \emph{expression resolution}, determining which declarations the identifiers in each expression correspond to. 5 Resolution is a straightforward task in C, as each declaration has a unique identifier, but in \CFA{} the name overloading features discussed in Section~\ref{overloading-sec} generate multiple candidate declarations for each identifier. 6 I refer to a given matching between identifiers and declarations in an expression as an \emph{interpretation}; an interpretation also includes information about polymorphic type bindings and implicit casts to support the \CFA{} features discussed in Sections~\ref{poly-func-sec} and~\ref{implicit-conv-sec}, each of which increase the proportion of feasible candidate interpretations. 7 To choose between feasible interpretations, \CFA{} defines a \emph{conversion cost} to rank interpretations; the expression resolution problem is thus to find the unique minimal-cost interpretation for an expression, reporting an error if no such interpretation exists. 8 9 \section{Conversion Cost} 10 11 4 Talk about the resolution heuristics. This is the bulk of the thesis. 12 5 13 6 % Discuss changes to cost model, as promised in Ch. 2 14 15 % Mention relevance of work to C++20 concepts -
driver/cfa.cc
r1d832f4 raf43394 10 10 // Created On : Tue Aug 20 13:44:49 2002 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue Jan 15 20:56:03 201913 // Update Count : 2 8012 // Last Modified On : Fri Sep 14 23:02:59 2018 13 // Update Count : 277 14 14 // 15 15 … … 384 384 nargs += 1; 385 385 386 for ( int i = 0; i < nlibs; i += 1 ) { // copy non-user libraries after all user libraries387 args[nargs] = libs[i];388 nargs += 1;389 } // for390 391 386 if ( link ) { 392 387 args[nargs] = "-Xlinker"; … … 419 414 nargs += 1; 420 415 args[nargs] = "-lrt"; 421 nargs += 1;422 args[nargs] = "-lm";423 416 nargs += 1; 424 417 } // if … … 505 498 args[nargs] = ( *new string( string("-B") + Bprefix ) ).c_str(); 506 499 nargs += 1; 500 args[nargs] = "-lm"; 501 nargs += 1; 507 502 } else { 508 503 cerr << argv[0] << " error, compiler \"" << compiler_name << "\" unsupported." << endl; 509 504 exit( EXIT_FAILURE ); 510 505 } // if 506 507 for ( int i = 0; i < nlibs; i += 1 ) { // copy non-user libraries after all user libraries 508 args[nargs] = libs[i]; 509 nargs += 1; 510 } // for 511 511 512 512 args[nargs] = NULL; // terminate with NULL -
libcfa/src/concurrency/coroutine.cfa
r1d832f4 raf43394 83 83 84 84 void ^?{}(coroutine_desc& this) { 85 if(this.state != Halted && this.state != Start) {85 if(this.state != Halted) { 86 86 coroutine_desc * src = TL_GET( this_coroutine ); 87 87 coroutine_desc * dst = &this; -
src/Concurrency/Keywords.cc
r1d832f4 raf43394 575 575 576 576 //in reverse order : 577 // monitor_ dtor_guard_t __guard = { __monitors, func };577 // monitor_guard_t __guard = { __monitors, #, func }; 578 578 body->push_front( 579 579 new DeclStmt( new ObjectDecl( … … 634 634 assert(generic_func); 635 635 636 // in reverse order :636 //in reverse order : 637 637 // monitor_guard_t __guard = { __monitors, #, func }; 638 638 body->push_front( -
src/Concurrency/Waitfor.cc
r1d832f4 raf43394 66 66 void foo() { 67 67 while( true ) { 68 { 69 acceptable_t acceptables[3]; 70 if( a < 1 ) { 71 acceptables[0].func = f; 72 acceptables[0].mon = a; 68 69 acceptable_t acceptables[3]; 70 if( a < 1 ) { 71 acceptables[0].func = f; 72 acceptables[0].mon = a; 73 } 74 acceptables[1].func = g; 75 acceptables[1].mon = a; 76 77 acceptables[2].func = f; 78 acceptables[2].mon = a; 79 acceptables[2].is_dtor = true; 80 81 int ret = waitfor_internal( acceptables, swagl() ); 82 83 switch( ret ) { 84 case 0: 85 { 86 bar(); 73 87 } 74 acceptables[1].func = g; 75 acceptables[1].mon = a; 76 77 acceptables[2].func = f; 78 acceptables[2].mon = a; 79 acceptables[2].is_dtor = true; 80 81 int ret = waitfor_internal( acceptables, swagl() ); 82 83 switch( ret ) { 84 case 0: 88 case 1: 89 { 90 baz(); 91 } 92 case 2: 93 signal(a); 85 94 { 86 b ar();95 break; 87 96 } 88 case 1:89 {90 baz();91 }92 case 2:93 signal(a);94 {95 break;96 }97 }98 97 } 99 98 } … … 556 555 new ConstantExpr( Constant::from_ulong( i++ ) ), 557 556 { 558 new CompoundStmt({ 559 clause.statement, 560 new BranchStmt( 561 "", 562 BranchStmt::Break 563 ) 564 }) 557 clause.statement, 558 new BranchStmt( 559 "", 560 BranchStmt::Break 561 ) 565 562 } 566 563 ) … … 573 570 new ConstantExpr( Constant::from_int( -2 ) ), 574 571 { 575 new CompoundStmt({ 576 waitfor->timeout.statement, 577 new BranchStmt( 578 "", 579 BranchStmt::Break 580 ) 581 }) 572 waitfor->timeout.statement, 573 new BranchStmt( 574 "", 575 BranchStmt::Break 576 ) 582 577 } 583 578 ) … … 590 585 new ConstantExpr( Constant::from_int( -1 ) ), 591 586 { 592 new CompoundStmt({ 593 waitfor->orelse.statement, 594 new BranchStmt( 595 "", 596 BranchStmt::Break 597 ) 598 }) 587 waitfor->orelse.statement, 588 new BranchStmt( 589 "", 590 BranchStmt::Break 591 ) 599 592 } 600 593 ) -
src/ResolvExpr/AlternativeFinder.cc
r1d832f4 raf43394 474 474 } 475 475 476 // specialization cost of return types can't be accounted for directly, it disables 477 // otherwise-identical calls, like this example based on auto-newline in the I/O lib: 478 // 479 // forall(otype OS) { 480 // void ?|?(OS&, int); // with newline 481 // OS& ?|?(OS&, int); // no newline, always chosen due to more specialization 482 // } 476 // mark specialization cost of return types 477 for ( DeclarationWithType* returnVal : function->returnVals ) { 478 convCost.decSpec( specCost( returnVal->get_type() ) ); 479 } 483 480 484 481 // mark type variable and specialization cost of forall clause … … 486 483 for ( TypeDecl* td : function->forall ) { 487 484 convCost.decSpec( td->assertions.size() ); 485 } 486 487 // xxx -- replace with new costs in resolver 488 for ( InferredParams::const_iterator assert = appExpr->inferParams.begin(); assert != appExpr->inferParams.end(); ++assert ) { 489 convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); 488 490 } 489 491 … … 1227 1229 Alternative newAlt{ 1228 1230 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1229 alt.env, openVars, needAssertions, alt.cost , alt.cost +thisCost };1231 alt.env, openVars, needAssertions, alt.cost + thisCost, thisCost }; 1230 1232 inferParameters( newAlt, back_inserter( candidates ) ); 1231 1233 } // if -
src/ResolvExpr/ResolveAssertions.cc
r1d832f4 raf43394 20 20 #include <list> // for list 21 21 #include <memory> // for unique_ptr 22 #include <string>23 22 #include <unordered_map> // for unordered_map, unordered_multimap 24 23 #include <utility> // for move … … 56 55 using CandidateList = std::vector<AssnCandidate>; 57 56 58 /// Unique identifier for a yet-to-be-resolved assertion59 struct AssnId {60 DeclarationWithType* decl; ///< Declaration of assertion61 AssertionSetValue info; ///< Information about assertion62 63 AssnId(DeclarationWithType* decl, const AssertionSetValue& info) : decl(decl), info(info) {}64 };65 66 /// Cached assertion items67 struct AssnCacheItem {68 CandidateList matches; ///< Possible matches for this assertion69 std::vector<AssnId> deferIds; ///< Deferred assertions which resolve to this item70 71 AssnCacheItem( CandidateList&& m ) : matches(std::move(m)), deferIds() {}72 };73 74 /// Cache of resolved assertions75 using AssnCache = std::unordered_map<std::string, AssnCacheItem>;76 77 57 /// Reference to single deferred item 78 58 struct DeferRef { 79 const AssnCacheItem& item; 59 const DeclarationWithType* decl; 60 const AssertionSetValue& info; 80 61 const AssnCandidate& match; 81 62 }; … … 84 65 /// Acts like indexed list of DeferRef 85 66 struct DeferItem { 86 const AssnCache* cache; ///< Cache storing assertion item 87 std::string key; ///< Key into cache 88 89 DeferItem( const AssnCache& cache, const std::string& key ) : cache(&cache), key(key) {} 90 91 bool empty() const { return cache->at(key).matches.empty(); } 92 93 CandidateList::size_type size() const { return cache->at(key).matches.size(); } 94 95 DeferRef operator[] ( unsigned i ) const { 96 const AssnCacheItem& item = cache->at(key); 97 return { item, item.matches[i] }; 98 } 99 100 // sortable by key 101 // TODO look into optimizing combination process with other sort orders (e.g. by number 102 // of matches in candidate) 103 bool operator< ( const DeferItem& o ) const { return key < o.key; } 104 bool operator== ( const DeferItem& o ) const { return key == o.key; } 67 DeclarationWithType* decl; 68 AssertionSetValue info; 69 CandidateList matches; 70 71 DeferItem( DeclarationWithType* decl, const AssertionSetValue& info, 72 CandidateList&& matches ) 73 : decl(decl), info(info), matches(std::move(matches)) {} 74 75 bool empty() const { return matches.empty(); } 76 77 CandidateList::size_type size() const { return matches.size(); } 78 79 DeferRef operator[] ( unsigned i ) const { return { decl, info, matches[i] }; } 105 80 }; 106 81 … … 177 152 for ( const auto& assn : x.assns ) { 178 153 k += computeConversionCost( 179 assn.match.adjType, assn.item.deferIds[0].decl->get_type(), indexer, 180 x.env ); 154 assn.match.adjType, assn.decl->get_type(), indexer, x.env ); 181 155 } 182 156 it = cache.emplace_hint( it, &x, k ); … … 234 208 candidate->get_uniqueId(), match.adjType->clone(), decl->get_type()->clone(), 235 209 varExpr }; 210 211 // // follow the current assertion's ID chain to find the correct set of inferred parameters 212 // // to add the candidate o (i.e. the set of inferred parameters belonging to the entity 213 // // which requested the assertion parameter) 214 // InferredParams* inferParams = &alt.expr->inferParams; 215 // for ( UniqueId id : info.idChain ) { 216 // inferParams = (*inferParams)[ id ].inferParams.get(); 217 // } 218 219 // (*inferParams)[ decl->get_uniqueId() ] = ParamEntry{ 220 // candidate->get_uniqueId(), match.adjType, decl->get_type()->clone(), varExpr }; 236 221 } 237 222 238 223 /// Adds a captured assertion to the symbol table 239 224 void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) { 240 for ( auto& i : assertSet) {241 if ( i .second.isUsed ) {242 indexer.addId( i .first );225 for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) { 226 if ( i->second.isUsed ) { 227 indexer.addId( i->first ); 243 228 } 244 229 } … … 249 234 250 235 /// Resolve a single assertion, in context 251 bool resolveAssertion( AssertionItem& assn, ResnState& resn , AssnCache& cache) {236 bool resolveAssertion( AssertionItem& assn, ResnState& resn ) { 252 237 // skip unused assertions 253 238 if ( ! assn.info.isUsed ) return true; 254 239 255 // check cache for this assertion 256 std::string assnKey = SymTab::Mangler::mangleAssnKey( assn.decl, resn.alt.env ); 257 auto it = cache.find( assnKey ); 258 259 // attempt to resolve assertion if this is the first time seen 260 if ( it == cache.end() ) { 261 // lookup candidates for this assertion 262 std::list< SymTab::Indexer::IdData > candidates; 263 resn.indexer.lookupId( assn.decl->name, candidates ); 264 265 // find the candidates that unify with the desired type 266 CandidateList matches; 267 for ( const auto& cdata : candidates ) { 268 DeclarationWithType* candidate = cdata.id; 269 270 // build independent unification context for candidate 271 AssertionSet have, newNeed; 272 TypeEnvironment newEnv{ resn.alt.env }; 273 OpenVarSet newOpenVars{ resn.alt.openVars }; 274 Type* adjType = candidate->get_type()->clone(); 275 adjustExprType( adjType, newEnv, resn.indexer ); 276 renameTyVars( adjType ); 277 278 // keep unifying candidates 279 if ( unify( assn.decl->get_type(), adjType, newEnv, newNeed, have, newOpenVars, 280 resn.indexer ) ) { 281 // set up binding slot for recursive assertions 282 UniqueId crntResnSlot = 0; 283 if ( ! newNeed.empty() ) { 284 crntResnSlot = ++globalResnSlot; 285 for ( auto& a : newNeed ) { 286 a.second.resnSlot = crntResnSlot; 287 } 240 // lookup candidates for this assertion 241 std::list< SymTab::Indexer::IdData > candidates; 242 resn.indexer.lookupId( assn.decl->name, candidates ); 243 244 // find the candidates that unify with the desired type 245 CandidateList matches; 246 for ( const auto& cdata : candidates ) { 247 DeclarationWithType* candidate = cdata.id; 248 249 // build independent unification context for candidate 250 AssertionSet have, newNeed; 251 TypeEnvironment newEnv{ resn.alt.env }; 252 OpenVarSet newOpenVars{ resn.alt.openVars }; 253 Type* adjType = candidate->get_type()->clone(); 254 adjustExprType( adjType, newEnv, resn.indexer ); 255 renameTyVars( adjType ); 256 257 // keep unifying candidates 258 if ( unify( assn.decl->get_type(), adjType, newEnv, newNeed, have, newOpenVars, 259 resn.indexer ) ) { 260 // set up binding slot for recursive assertions 261 UniqueId crntResnSlot = 0; 262 if ( ! newNeed.empty() ) { 263 crntResnSlot = ++globalResnSlot; 264 for ( auto& a : newNeed ) { 265 a.second.resnSlot = crntResnSlot; 288 266 } 289 290 matches.emplace_back( cdata, adjType, std::move(newEnv), std::move(have), 291 std::move(newNeed), std::move(newOpenVars), crntResnSlot ); 292 } else { 293 delete adjType; 294 } 267 } 268 // // set up idChain on new assertions 269 // for ( auto& a : newNeed ) { 270 // a.second.idChain = assn.info.idChain; 271 // a.second.idChain.push_back( assn.decl->get_uniqueId() ); 272 // } 273 274 matches.emplace_back( cdata, adjType, std::move(newEnv), std::move(have), 275 std::move(newNeed), std::move(newOpenVars), crntResnSlot ); 276 } else { 277 delete adjType; 295 278 } 296 297 it = cache.emplace_hint( it, assnKey, AssnCacheItem{ std::move(matches) } ); 298 } 299 300 CandidateList& matches = it->second.matches; 279 } 301 280 302 281 // break if no suitable assertion … … 305 284 // defer if too many suitable assertions 306 285 if ( matches.size() > 1 ) { 307 it->second.deferIds.emplace_back( assn.decl, assn.info ); 308 resn.deferred.emplace_back( cache, assnKey ); 286 resn.deferred.emplace_back( assn.decl, assn.info, std::move(matches) ); 309 287 return true; 310 288 } … … 314 292 addToIndexer( match.have, resn.indexer ); 315 293 resn.newNeed.insert( match.need.begin(), match.need.end() ); 316 resn.alt.env = match.env;317 resn.alt.openVars = match.openVars;294 resn.alt.env = std::move(match.env); 295 resn.alt.openVars = std::move(match.openVars); 318 296 319 297 bindAssertion( assn.decl, assn.info, resn.alt, match, resn.inferred ); … … 376 354 ResnList resns{ ResnState{ alt, root_indexer } }; 377 355 ResnList new_resns{}; 378 AssnCache assnCache;379 356 380 357 // resolve assertions in breadth-first-order up to a limited number of levels deep … … 385 362 for ( auto& assn : resn.need ) { 386 363 // fail early if any assertion is not resolvable 387 if ( ! resolveAssertion( assn, resn , assnCache) ) goto nextResn;364 if ( ! resolveAssertion( assn, resn ) ) goto nextResn; 388 365 } 389 366 … … 396 373 } 397 374 } else { 398 // only resolve each deferred assertion once399 std::sort( resn.deferred.begin(), resn.deferred.end() );400 auto last = std::unique( resn.deferred.begin(), resn.deferred.end() );401 resn.deferred.erase( last, resn.deferred.end() );402 375 // resolve deferred assertions by mutual compatibility 403 376 std::vector<CandidateEnvMerger::OutType> compatible = filterCombos( … … 407 380 CandidateCost coster{ resn.indexer }; 408 381 std::sort( compatible.begin(), compatible.end(), coster ); 382 // // sort by cost if pruning 383 // if ( pruneAssertions ) { 384 // auto lmin = sort_mins( compatible.begin(), compatible.end(), 385 // CandidateCost{resn.indexer} ); 386 // compatible.erase( lmin, compatible.end() ); 387 // } 409 388 410 389 // keep map of detected options … … 429 408 new_resn.newNeed.insert( match.need.begin(), match.need.end() ); 430 409 431 // for each deferred assertion with the same form 432 for ( AssnId id : r.item.deferIds ) { 433 bindAssertion( 434 id.decl, id.info, new_resn.alt, match, new_resn.inferred ); 435 } 410 bindAssertion( r.decl, r.info, new_resn.alt, match, new_resn.inferred ); 436 411 } 437 412 -
src/SymTab/Mangler.cc
r1d832f4 raf43394 15 15 #include "Mangler.h" 16 16 17 #include <algorithm> // for copy, transform18 #include <cassert> // for assert, assertf19 #include <functional> // for const_mem_fun_t, mem_fun20 #include <iterator> // for ostream_iterator, back_insert_ite...21 #include <list> // for _List_iterator, list, _List_const...22 #include <string> // for string, char_traits, operator<<23 24 #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup17 #include <algorithm> // for copy, transform 18 #include <cassert> // for assert, assertf 19 #include <functional> // for const_mem_fun_t, mem_fun 20 #include <iterator> // for ostream_iterator, back_insert_ite... 21 #include <list> // for _List_iterator, list, _List_const... 22 #include <string> // for string, char_traits, operator<< 23 24 #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup 25 25 #include "Common/PassVisitor.h" 26 #include "Common/SemanticError.h" // for SemanticError 27 #include "Common/utility.h" // for toString 28 #include "Parser/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int... 29 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment 30 #include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType 31 #include "SynTree/Expression.h" // for TypeExpr, Expression, operator<< 32 #include "SynTree/Type.h" // for Type, ReferenceToType, Type::Fora... 26 #include "Common/SemanticError.h" // for SemanticError 27 #include "Common/utility.h" // for toString 28 #include "Parser/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int... 29 #include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType 30 #include "SynTree/Expression.h" // for TypeExpr, Expression, operator<< 31 #include "SynTree/Type.h" // for Type, ReferenceToType, Type::Fora... 33 32 34 33 namespace SymTab { … … 38 37 struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler>, public WithGuards { 39 38 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ); 40 Mangler( const ResolvExpr::TypeEnvironment& env );41 39 Mangler( const Mangler & ) = delete; 42 40 … … 67 65 private: 68 66 std::ostringstream mangleName; ///< Mangled name being constructed 69 typedef std::map< std::string, std::pair< std::string, int > > VarMapType;67 typedef std::map< std::string, std::pair< int, int > > VarMapType; 70 68 VarMapType varNums; ///< Map of type variables to indices 71 69 int nextVarNum; ///< Next type variable index 72 const ResolvExpr::TypeEnvironment* env; ///< optional environment for substitutions73 70 bool isTopLevel; ///< Is the Mangler at the top level 74 71 bool mangleOverridable; ///< Specially mangle overridable built-in methods … … 78 75 bool inQualifiedType = false; ///< Add start/end delimiters around qualified type 79 76 80 public:81 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams,82 int nextVarNum, const ResolvExpr::TypeEnvironment* env,83 const VarMapType& varNums );84 85 private:86 77 void mangleDecl( DeclarationWithType *declaration ); 87 78 void mangleRef( ReferenceToType *refType, std::string prefix ); … … 109 100 } 110 101 111 std::string mangleAssnKey( DeclarationWithType* decl,112 const ResolvExpr::TypeEnvironment& env ) {113 PassVisitor<Mangler> mangler( env );114 maybeAccept( decl, mangler );115 return mangler.pass.get_mangleName();116 }117 118 102 namespace { 119 103 Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ) 120 : nextVarNum( 0 ), env(nullptr), isTopLevel( true ), 121 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 122 mangleGenericParams( mangleGenericParams ) {} 123 124 Mangler::Mangler( const ResolvExpr::TypeEnvironment& env ) 125 : nextVarNum( 0 ), env( &env ), isTopLevel( true ), mangleOverridable( false ), 126 typeMode( false ), mangleGenericParams( true ) {} 127 128 Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 129 int nextVarNum, const ResolvExpr::TypeEnvironment* env, 130 const VarMapType& varNums ) 131 : varNums( varNums ), nextVarNum( nextVarNum ), env( env ), isTopLevel( false ), 132 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 133 mangleGenericParams( mangleGenericParams ) {} 104 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {} 134 105 135 106 void Mangler::mangleDecl( DeclarationWithType * declaration ) { … … 358 329 assert( false ); 359 330 } // switch 360 std::string varName; 361 // replace type with substitution name if environment is available and bound 362 if ( env ) { 363 const ResolvExpr::EqvClass* varClass = env->lookup( (*i)->name ); 364 if ( varClass && varClass->type ) { 365 PassVisitor<Mangler> sub_mangler( 366 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, 367 env, varNums ); 368 varClass->type->accept( sub_mangler ); 369 varName = std::string{"%"} + sub_mangler.pass.get_mangleName(); 370 } 371 } 372 // otherwise just give type numeric name 373 if ( varName.empty() ) { 374 varName = std::to_string( nextVarNum++ ); 375 } 376 varNums[ (*i)->name ] = std::make_pair( varName, (int)(*i)->get_kind() ); 331 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() ); 377 332 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) { 378 PassVisitor<Mangler> sub_mangler( 379 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, env, 380 varNums ); 333 PassVisitor<Mangler> sub_mangler( mangleOverridable, typeMode, mangleGenericParams ); 334 sub_mangler.pass.nextVarNum = nextVarNum; 335 sub_mangler.pass.isTopLevel = false; 336 sub_mangler.pass.varNums = varNums; 381 337 (*assert)->accept( sub_mangler ); 382 assertionNames.push_back( sub_mangler.pass. get_mangleName() );338 assertionNames.push_back( sub_mangler.pass.mangleName.str() ); 383 339 acount++; 384 340 } // for -
src/SymTab/Mangler.h
r1d832f4 raf43394 31 31 // * Currently name compression is not implemented. 32 32 33 namespace ResolvExpr {34 class TypeEnvironment;35 }36 37 33 namespace SymTab { 38 34 namespace Mangler { … … 44 40 /// Mangle ignoring generic type parameters 45 41 std::string mangleConcrete( Type* ty ); 46 /// Mangle for assertion key47 std::string mangleAssnKey( DeclarationWithType* decl,48 const ResolvExpr::TypeEnvironment& env );49 42 50 43 namespace Encoding { -
src/main.cc
r1d832f4 raf43394 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Dec 26 08:11:19201813 // Update Count : 49 912 // Last Modified On : Wed Jun 6 15:51:47 2018 13 // Update Count : 498 14 14 // 15 15 … … 371 371 } 372 372 } catch(const std::exception& e) { 373 std::cerr << "Un caught Exception \"" << e.what() << "\"\n";373 std::cerr << "Unaught Exception \"" << e.what() << "\"\n"; 374 374 } 375 375 return 1; -
tests/pybin/tools.py
r1d832f4 raf43394 3 3 import __main__ 4 4 import argparse 5 import fileinput6 5 import multiprocessing 7 6 import os 8 7 import re 9 import resource10 8 import signal 11 9 import stat 12 10 import sys 13 import time11 import fileinput 14 12 15 13 from pybin import settings … … 133 131 134 132 return None 135 136 def run(exe, output, input):137 ret, _ = sh("timeout %d %s > %s 2>&1" % (settings.timeout.single, exe, output), input = input)138 return ret139 140 133 ################################################################################ 141 134 # file handling 142 135 ################################################################################ 143 # move a file144 def mv(source, dest):145 ret, _ = sh("mv %s %s" % (source, dest))146 return ret147 148 # cat one file into the other149 def cat(source, dest):150 ret, _ = sh("cat %s > %s" % (source, dest))151 return ret152 136 153 137 # helper function to replace patterns in a file … … 246 230 signal.signal(signal.SIGINT, signal.SIG_IGN) 247 231 248 249 # enable core dumps for all the test children250 resource.setrlimit(resource.RLIMIT_CORE, (resource.RLIM_INFINITY, resource.RLIM_INFINITY))251 252 232 ################################################################################ 253 233 # misc … … 271 251 else: 272 252 print(text) 273 274 275 def coreInfo(path):276 cmd = os.path.join(settings.SRCDIR, "pybin/print-core.gdb")277 if not os.path.isfile(cmd):278 return 1, "ERR Printing format for core dumps not found"279 280 dname = os.path.dirname(path)281 core = os.path.join(dname, "core" )282 if not os.path.isfile(path):283 return 1, "ERR Executable path is wrong"284 285 if not os.path.isfile(core):286 return 1, "ERR No core dump"287 288 return sh("gdb -n %s %s -batch -x %s" % (path, core, cmd), print2stdout=False)289 290 class Timed:291 def __enter__(self):292 self.start = time.time()293 return self294 295 def __exit__(self, *args):296 self.end = time.time()297 self.duration = self.end - self.start -
tests/test.py
r1d832f4 raf43394 121 121 # running test functions 122 122 ################################################################################ 123 def success(val): 124 return val == 0 or settings.dry_run 125 126 def isExe(file): 127 return settings.dry_run or fileIsExecutable(file) 128 129 def noRule(file, target): 130 return not settings.dry_run and fileContainsOnly(file, "make: *** No rule to make target `%s'. Stop." % target) 123 # fix the absolute paths in the output 124 def fixoutput( fname ): 125 if not is_ascii(fname): 126 return 127 128 file_replace(fname, "%s/" % settings.SRCDIR, "") 129 131 130 132 131 # logic to run a single test and return the result (No handling of printing or other test framework logic) … … 144 143 145 144 # build, skipping to next test on error 146 with Timed() as comp_dur: 147 make_ret, _ = make( test.target(), redirects = ("2> %s 1> /dev/null" % out_file), error_file = err_file ) 145 before = time.time() 146 make_ret, _ = make( test.target(), 147 redirects = "2> %s 1> /dev/null" % out_file, 148 error_file = err_file 149 ) 150 after = time.time() 151 152 comp_dur = after - before 153 154 run_dur = None 148 155 149 156 # if the make command succeds continue otherwise skip to diff 150 run_dur = None 151 if success(make_ret): 152 with Timed() as run_dur: 153 if isExe(exe_file): 154 # run test 155 retcode = run(exe_file, out_file, in_file) 156 else : 157 # simply cat the result into the output 158 retcode = cat(exe_file, out_file) 157 if make_ret == 0 or settings.dry_run: 158 before = time.time() 159 if settings.dry_run or fileIsExecutable(exe_file) : 160 # run test 161 retcode, _ = sh("timeout %d %s > %s 2>&1" % (settings.timeout.single, exe_file, out_file), input = in_file) 162 else : 163 # simply cat the result into the output 164 retcode, _ = sh("cat %s > %s" % (exe_file, out_file)) 165 166 after = time.time() 167 run_dur = after - before 159 168 else: 160 retcode = mv(err_file, out_file) 161 162 if success(retcode): 169 retcode, _ = sh("mv %s %s" % (err_file, out_file)) 170 171 172 if retcode == 0: 173 # fixoutput(out_file) 163 174 if settings.generating : 164 175 # if we are ounly generating the output we still need to check that the test actually exists 165 if no Rule(out_file,test.target()) :166 retcode = 1 176 if not settings.dry_run and fileContainsOnly(out_file, "make: *** No rule to make target `%s'. Stop." % test.target()) : 177 retcode = 1; 167 178 error = "\t\tNo make target for test %s!" % test.target() 168 rm(out_file)179 sh("rm %s" % out_file, False) 169 180 else: 170 181 error = None … … 177 188 error = myfile.read() 178 189 179 ret, info = coreInfo(exe_file)180 error = error + info181 182 183 190 184 191 # clean the executable 185 rm(exe_file)186 187 return retcode, error, [comp_dur .duration, run_dur.duration if run_dur else None]192 sh("rm -f %s > /dev/null 2>&1" % test.target()) 193 194 return retcode, error, [comp_dur, run_dur] 188 195 189 196 # run a single test and handle the errors, outputs, printing, exception handling, etc. … … 192 199 with SignalHandling(): 193 200 # print formated name 194 name_txt = "%2 4s " % t.name201 name_txt = "%20s " % t.name 195 202 196 203 retcode, error, duration = run_single_test(t) … … 256 263 allTests = listTests( options.include, options.exclude ) 257 264 258 259 265 # if user wants all tests than no other treatement of the test list is required 260 266 if options.all or options.list or options.list_comp or options.include :
Note:
See TracChangeset
for help on using the changeset viewer.