Changeset 692be4e


Ignore:
Timestamp:
Jan 29, 2019, 1:49:06 PM (3 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, persistent-indexer
Children:
72514aa
Parents:
528ccc8 (diff), 8f99233 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'jenkins-sandbox' of plg.uwaterloo.ca:software/cfa/cfa-cc into jenkins-sandbox

Files:
3 added
12 edited

Legend:

Unmodified
Added
Removed
  • Jenkinsfile

    r528ccc8 r692be4e  
    77node('master') {
    88        // Globals
    9         BuildDir  = null
    10         SrcDir    = null
     9        BuildDir  = pwd tmp: true
     10        SrcDir    = pwd tmp: false
    1111        Settings  = null
    1212        StageName = ''
     
    4646                                publish()
    4747                        }
     48
     49                        // Update the build directories when exiting the node
     50                        BuildDir  = pwd tmp: true
     51                        SrcDir    = pwd tmp: false
    4852
    4953                        notify_server(45)
     
    149153                dir (BuildDir) {
    150154                        //Append bench results
    151                         sh "make --no-print-directory -C benchmark jenkins githash=${Settings.GitNewRef} arch=${Settings.Architecture} | tee ${SrcDir}/bench.json"
     155                        sh "${SrcDir}/jenkins.sh ${GitNewRef} ${Architecture} ${BuildDir}/bench.json"
    152156                }
    153157        }
     
    175179
    176180                //Then publish the results
    177                 sh 'curl --silent --show-error -H \'Content-Type: application/json\' --data @bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true'
     181                sh 'curl --silent --show-error -H \'Content-Type: application/json\' --data @${BuildDir}/bench.json https://cforall.uwaterloo.ca:8082/jenkins/publish > /dev/null || true'
    178182        }
    179183}
     
    185189        if (!Settings || !Settings.GitOldRef || !Settings.GitNewRef) return "\nERROR retrieveing git information!\n"
    186190
    187         sh "${SrcDir}/tools/PrettyGitLogs.sh ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
     191        sh "${SrcDir}/tools/PrettyGitLogs.sh ${SrcDir} ${BuildDir} ${Settings.GitOldRef} ${Settings.GitNewRef}"
    188192
    189193        def gitUpdate = readFile("${BuildDir}/GIT_UPDATE")
     
    377381                ]])
    378382
     383        // It's unfortunate but it looks like we need to checkout the entire repo just to get the pretty git printer
     384        checkout scm
     385
    379386        final settings = new BuildSettings(params, env.BRANCH_NAME)
    380387
     
    404411        catch (Exception caughtError) {
    405412                err = caughtError //rethrow error later
    406                 sh 'cat *.log'
     413                sh 'cat build/*.log'
    407414        }
    408415        finally {
  • doc/theses/aaron_moss_PhD/phd/background.tex

    r528ccc8 r692be4e  
    213213The 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.
    214214
    215 \subsection{Implicit Conversions}
     215\subsection{Implicit Conversions} \label{implicit-conv-sec}
    216216
    217217In 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

    r528ccc8 r692be4e  
    22\label{resolution-chap}
    33
    4 Talk about the resolution heuristics. This is the bulk of the thesis.
     4The main task of the \CFACC{} type-checker is \emph{expression resolution}, determining which declarations the identifiers in each expression correspond to.
     5Resolution 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.
     6I 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.
     7To 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
    512
    613% Discuss changes to cost model, as promised in Ch. 2
     14
     15% Mention relevance of work to C++20 concepts
  • driver/cfa.cc

    r528ccc8 r692be4e  
    1010// Created On       : Tue Aug 20 13:44:49 2002
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Sep 14 23:02:59 2018
    13 // Update Count     : 277
     12// Last Modified On : Tue Jan 15 20:56:03 2019
     13// Update Count     : 280
    1414//
    1515
     
    384384        nargs += 1;
    385385
     386        for ( int i = 0; i < nlibs; i += 1 ) {                          // copy non-user libraries after all user libraries
     387                args[nargs] = libs[i];
     388                nargs += 1;
     389        } // for
     390
    386391        if ( link ) {
    387392                args[nargs] = "-Xlinker";
     
    414419                nargs += 1;
    415420                args[nargs] = "-lrt";
     421                nargs += 1;
     422                args[nargs] = "-lm";
    416423                nargs += 1;
    417424        } // if
     
    498505                args[nargs] = ( *new string( string("-B") + Bprefix ) ).c_str();
    499506                nargs += 1;
    500                 args[nargs] = "-lm";
    501                 nargs += 1;
    502507        } else {
    503508                cerr << argv[0] << " error, compiler \"" << compiler_name << "\" unsupported." << endl;
    504509                exit( EXIT_FAILURE );
    505510        } // 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
    511511
    512512        args[nargs] = NULL;                                                                     // terminate with NULL
  • src/ResolvExpr/AlternativeFinder.cc

    r528ccc8 r692be4e  
    474474                }
    475475
    476                 // mark specialization cost of return types
    477                 for ( DeclarationWithType* returnVal : function->returnVals ) {
    478                         convCost.decSpec( specCost( returnVal->get_type() ) );
    479                 }
     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                //   }
    480483
    481484                // mark type variable and specialization cost of forall clause
     
    483486                for ( TypeDecl* td : function->forall ) {
    484487                        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 );
    490488                }
    491489
     
    12291227                                Alternative newAlt{
    12301228                                        restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ),
    1231                                         alt.env, openVars, needAssertions, alt.cost + thisCost, thisCost };
     1229                                        alt.env, openVars, needAssertions, alt.cost, alt.cost + thisCost };
    12321230                                inferParameters( newAlt, back_inserter( candidates ) );
    12331231                        } // if
  • src/ResolvExpr/ResolveAssertions.cc

    r528ccc8 r692be4e  
    2020#include <list>                     // for list
    2121#include <memory>                   // for unique_ptr
     22#include <string>
    2223#include <unordered_map>            // for unordered_map, unordered_multimap
    2324#include <utility>                  // for move
     
    5556        using CandidateList = std::vector<AssnCandidate>;
    5657
     58        /// Unique identifier for a yet-to-be-resolved assertion
     59        struct AssnId {
     60                DeclarationWithType* decl;  ///< Declaration of assertion
     61                AssertionSetValue info;     ///< Information about assertion
     62
     63                AssnId(DeclarationWithType* decl, const AssertionSetValue& info) : decl(decl), info(info) {}
     64        };
     65
     66        /// Cached assertion items
     67        struct AssnCacheItem {
     68                CandidateList matches;         ///< Possible matches for this assertion
     69                std::vector<AssnId> deferIds;  ///< Deferred assertions which resolve to this item
     70
     71                AssnCacheItem( CandidateList&& m ) : matches(std::move(m)), deferIds() {}
     72        };
     73
     74        /// Cache of resolved assertions
     75        using AssnCache = std::unordered_map<std::string, AssnCacheItem>;
     76
    5777        /// Reference to single deferred item
    5878        struct DeferRef {
    59                 const DeclarationWithType* decl;
    60                 const AssertionSetValue& info;
     79                const AssnCacheItem& item;
    6180                const AssnCandidate& match;
    6281        };
     
    6584        /// Acts like indexed list of DeferRef
    6685        struct DeferItem {
    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] }; }
     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; }
    80105        };
    81106
     
    152177                                for ( const auto& assn : x.assns ) {
    153178                                        k += computeConversionCost(
    154                                                 assn.match.adjType, assn.decl->get_type(), indexer, x.env );
     179                                                assn.match.adjType, assn.item.deferIds[0].decl->get_type(), indexer,
     180                                                x.env );
    155181                                }
    156182                                it = cache.emplace_hint( it, &x, k );
     
    208234                                candidate->get_uniqueId(), match.adjType->clone(), decl->get_type()->clone(),
    209235                                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 };
    221236        }
    222237
    223238        /// Adds a captured assertion to the symbol table
    224239        void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) {
    225                 for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) {
    226                         if ( i->second.isUsed ) {
    227                                 indexer.addId( i->first );
     240                for ( auto&  i : assertSet ) {
     241                        if ( i.second.isUsed ) {
     242                                indexer.addId( i.first );
    228243                        }
    229244                }
     
    234249
    235250        /// Resolve a single assertion, in context
    236         bool resolveAssertion( AssertionItem& assn, ResnState& resn ) {
     251        bool resolveAssertion( AssertionItem& assn, ResnState& resn, AssnCache& cache ) {
    237252                // skip unused assertions
    238253                if ( ! assn.info.isUsed ) return true;
    239254
    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;
     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                                                }
    266288                                        }
    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;
     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                                }
    278295                        }
    279                 }
     296
     297                        it = cache.emplace_hint( it, assnKey, AssnCacheItem{ std::move(matches) } );
     298                }
     299
     300                CandidateList& matches = it->second.matches;
    280301
    281302                // break if no suitable assertion
     
    284305                // defer if too many suitable assertions
    285306                if ( matches.size() > 1 ) {
    286                         resn.deferred.emplace_back( assn.decl, assn.info, std::move(matches) );
     307                        it->second.deferIds.emplace_back( assn.decl, assn.info );
     308                        resn.deferred.emplace_back( cache, assnKey );
    287309                        return true;
    288310                }
     
    292314                addToIndexer( match.have, resn.indexer );
    293315                resn.newNeed.insert( match.need.begin(), match.need.end() );
    294                 resn.alt.env = std::move(match.env);
    295                 resn.alt.openVars = std::move(match.openVars);
     316                resn.alt.env = match.env;
     317                resn.alt.openVars = match.openVars;
    296318
    297319                bindAssertion( assn.decl, assn.info, resn.alt, match, resn.inferred );
     
    354376                ResnList resns{ ResnState{ alt, root_indexer } };
    355377                ResnList new_resns{};
     378                AssnCache assnCache;
    356379
    357380                // resolve assertions in breadth-first-order up to a limited number of levels deep
     
    362385                                for ( auto& assn : resn.need ) {
    363386                                        // fail early if any assertion is not resolvable
    364                                         if ( ! resolveAssertion( assn, resn ) ) goto nextResn;
     387                                        if ( ! resolveAssertion( assn, resn, assnCache ) ) goto nextResn;
    365388                                }
    366389
     
    373396                                        }
    374397                                } else {
     398                                        // only resolve each deferred assertion once
     399                                        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() );
    375402                                        // resolve deferred assertions by mutual compatibility
    376403                                        std::vector<CandidateEnvMerger::OutType> compatible = filterCombos(
     
    380407                                        CandidateCost coster{ resn.indexer };
    381408                                        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                                         // }
    388409
    389410                                        // keep map of detected options
     
    408429                                                        new_resn.newNeed.insert( match.need.begin(), match.need.end() );
    409430
    410                                                         bindAssertion( r.decl, r.info, new_resn.alt, match, new_resn.inferred );
     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                                                        }
    411436                                                }
    412437
  • src/SymTab/Mangler.cc

    r528ccc8 r692be4e  
    1515#include "Mangler.h"
    1616
    17 #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
     17#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
    2525#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 "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...
     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...
    3233
    3334namespace SymTab {
     
    3738                        struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler>, public WithGuards {
    3839                                Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
     40                                Mangler( const ResolvExpr::TypeEnvironment& env );
    3941                                Mangler( const Mangler & ) = delete;
    4042
     
    6567                          private:
    6668                                std::ostringstream mangleName;  ///< Mangled name being constructed
    67                                 typedef std::map< std::string, std::pair< int, int > > VarMapType;
     69                                typedef std::map< std::string, std::pair< std::string, int > > VarMapType;
    6870                                VarMapType varNums;             ///< Map of type variables to indices
    6971                                int nextVarNum;                 ///< Next type variable index
     72                                const ResolvExpr::TypeEnvironment* env;  ///< optional environment for substitutions
    7073                                bool isTopLevel;                ///< Is the Mangler at the top level
    7174                                bool mangleOverridable;         ///< Specially mangle overridable built-in methods
     
    7578                                bool inQualifiedType = false;   ///< Add start/end delimiters around qualified type
    7679
     80                          public:
     81                                Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams,
     82                                        int nextVarNum, const ResolvExpr::TypeEnvironment* env,
     83                                        const VarMapType& varNums );
     84
     85                          private:
    7786                                void mangleDecl( DeclarationWithType *declaration );
    7887                                void mangleRef( ReferenceToType *refType, std::string prefix );
     
    100109                }
    101110
     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
    102118                namespace {
    103119                        Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
    104                                 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( 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 ) {}
    105134
    106135                        void Mangler::mangleDecl( DeclarationWithType * declaration ) {
     
    329358                                                        assert( false );
    330359                                                } // switch
    331                                                 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
     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() );
    332377                                                for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
    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;
     378                                                        PassVisitor<Mangler> sub_mangler(
     379                                                                mangleOverridable, typeMode, mangleGenericParams, nextVarNum, env,
     380                                                                varNums );
    337381                                                        (*assert)->accept( sub_mangler );
    338                                                         assertionNames.push_back( sub_mangler.pass.mangleName.str() );
     382                                                        assertionNames.push_back( sub_mangler.pass.get_mangleName() );
    339383                                                        acount++;
    340384                                                } // for
  • src/SymTab/Mangler.h

    r528ccc8 r692be4e  
    3131// * Currently name compression is not implemented.
    3232
     33namespace ResolvExpr {
     34        class TypeEnvironment;
     35}
     36
    3337namespace SymTab {
    3438        namespace Mangler {
     
    4044                /// Mangle ignoring generic type parameters
    4145                std::string mangleConcrete( Type* ty );
     46                /// Mangle for assertion key
     47                std::string mangleAssnKey( DeclarationWithType* decl,
     48                        const ResolvExpr::TypeEnvironment& env );
    4249
    4350                namespace Encoding {
  • src/main.cc

    r528ccc8 r692be4e  
    1010// Created On       : Fri May 15 23:12:02 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Jun  6 15:51:47 2018
    13 // Update Count     : 498
     12// Last Modified On : Wed Dec 26 08:11:19 2018
     13// Update Count     : 499
    1414//
    1515
     
    371371                        }
    372372                } catch(const std::exception& e) {
    373                         std::cerr << "Unaught Exception \"" << e.what() << "\"\n";
     373                        std::cerr << "Uncaught Exception \"" << e.what() << "\"\n";
    374374                }
    375375                return 1;
  • tests/pybin/tools.py

    r528ccc8 r692be4e  
    33import __main__
    44import argparse
     5import fileinput
    56import multiprocessing
    67import os
    78import re
     9import resource
    810import signal
    911import stat
    1012import sys
    11 import fileinput
     13import time
    1214
    1315from pybin import settings
     
    131133
    132134    return None
     135
     136def run(exe, output, input):
     137        ret, _ = sh("timeout %d %s > %s 2>&1" % (settings.timeout.single, exe, output), input = input)
     138        return ret
     139
    133140################################################################################
    134141#               file handling
    135142################################################################################
     143# move a file
     144def mv(source, dest):
     145        ret, _ = sh("mv %s %s" % (source, dest))
     146        return ret
     147
     148# cat one file into the other
     149def cat(source, dest):
     150        ret, _ = sh("cat %s > %s" % (source, dest))
     151        return ret
    136152
    137153# helper function to replace patterns in a file
     
    230246                signal.signal(signal.SIGINT, signal.SIG_IGN)
    231247
     248
     249# enable core dumps for all the test children
     250resource.setrlimit(resource.RLIMIT_CORE, (resource.RLIM_INFINITY, resource.RLIM_INFINITY))
     251
    232252################################################################################
    233253#               misc
     
    251271        else:
    252272                print(text)
     273
     274
     275def 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
     290class Timed:
     291    def __enter__(self):
     292        self.start = time.time()
     293        return self
     294
     295    def __exit__(self, *args):
     296        self.end = time.time()
     297        self.duration = self.end - self.start
  • tests/test.py

    r528ccc8 r692be4e  
    121121#               running test functions
    122122################################################################################
    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 
     123def success(val):
     124        return val == 0 or settings.dry_run
     125
     126def isExe(file):
     127        return settings.dry_run or fileIsExecutable(file)
     128
     129def noRule(file, target):
     130        return not settings.dry_run and fileContainsOnly(file, "make: *** No rule to make target `%s'.  Stop." % target)
    130131
    131132# logic to run a single test and return the result (No handling of printing or other test framework logic)
     
    143144
    144145        # build, skipping to next test on error
    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 
     146        with Timed() as comp_dur:
     147                make_ret, _ = make( test.target(),      redirects  = ("2> %s 1> /dev/null" % out_file), error_file = err_file )
     148
     149        # if the make command succeds continue otherwise skip to diff
    154150        run_dur = None
    155 
    156         # if the make command succeds continue otherwise skip to diff
    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
     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)
    168159        else:
    169                 retcode, _ = sh("mv %s %s" % (err_file, out_file))
    170 
    171 
    172         if retcode == 0:
    173                 # fixoutput(out_file)
     160                retcode = mv(err_file, out_file)
     161
     162        if success(retcode):
    174163                if settings.generating :
    175164                        # if we are ounly generating the output we still need to check that the test actually exists
    176                         if not settings.dry_run and fileContainsOnly(out_file, "make: *** No rule to make target `%s'.  Stop." % test.target()) :
    177                                 retcode = 1;
     165                        if noRule(out_file, test.target()) :
     166                                retcode = 1
    178167                                error = "\t\tNo make target for test %s!" % test.target()
    179                                 sh("rm %s" % out_file, False)
     168                                rm(out_file)
    180169                        else:
    181170                                error = None
     
    188177                        error = myfile.read()
    189178
     179                ret, info = coreInfo(exe_file)
     180                error = error + info
     181
     182
    190183
    191184        # clean the executable
    192         sh("rm -f %s > /dev/null 2>&1" % test.target())
    193 
    194         return retcode, error, [comp_dur, run_dur]
     185        rm(exe_file)
     186
     187        return retcode, error, [comp_dur.duration, run_dur.duration if run_dur else None]
    195188
    196189# run a single test and handle the errors, outputs, printing, exception handling, etc.
     
    199192        with SignalHandling():
    200193                # print formated name
    201                 name_txt = "%20s  " % t.name
     194                name_txt = "%24s  " % t.name
    202195
    203196                retcode, error, duration = run_single_test(t)
     
    263256        allTests = listTests( options.include, options.exclude )
    264257
     258
    265259        # if user wants all tests than no other treatement of the test list is required
    266260        if options.all or options.list or options.list_comp or options.include :
  • tools/PrettyGitLogs.sh

    r528ccc8 r692be4e  
    33set -e
    44
    5 GIT_UPDATE="$1/GIT_UPDATE"
    6 GIT_LOG="$1/GIT_LOG"
    7 GIT_DIFF="$1/GIT_DIFF"
     5GIT="git --git-dir=$1/.git"
     6
     7GIT_UPDATE="$2/GIT_UPDATE"
     8GIT_LOG="$2/GIT_LOG"
     9GIT_DIFF="$2/GIT_DIFF"
    810
    911rm -f ${GIT_UPDATE}  ${GIT_LOG}  ${GIT_DIFF}
    1012
    11 GitOldRef=$2
    12 GitNewRef=$3
     13GitOldRef=$3
     14GitNewRef=$4
    1315
    1416
Note: See TracChangeset for help on using the changeset viewer.