Changeset 7c70089 for src


Ignore:
Timestamp:
Mar 17, 2017, 1:36:27 PM (8 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
31ce3d6
Parents:
b32ada31 (diff), 946bcca (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 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
src
Files:
34 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rb32ada31 r7c70089  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 09:09:09 2017
    13 // Update Count     : 480
     12// Last Modified On : Fri Mar 17 09:06:01 2017
     13// Update Count     : 481
    1414//
    1515
     
    539539                if ( castExpr->get_result()->isVoid() ) {
    540540                        output << "(void)" ;
    541                 } else if ( ! castExpr->get_result()->get_isLvalue() ) {
     541                } else if ( ! castExpr->get_result()->get_lvalue() ) {
    542542                        // at least one result type of cast, but not an lvalue
    543543                        output << "(";
  • src/CodeGen/GenType.cc

    rb32ada31 r7c70089  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb  2 13:53:43 2017
    13 // Update Count     : 20
     12// Last Modified On : Fri Mar 17 09:02:28 2017
     13// Update Count     : 22
    1414//
    1515
     
    9999                        os << "static ";
    100100                } // if
    101                 if ( qualifiers.isConst ) {
     101                if ( qualifiers.is_const ) {
    102102                        os << "const ";
    103103                } // if
    104                 if ( qualifiers.isVolatile ) {
     104                if ( qualifiers.is_volatile ) {
    105105                        os << "volatile ";
    106106                } // if
    107                 if ( qualifiers.isRestrict ) {
     107                if ( qualifiers.is_restrict ) {
    108108                        os << "__restrict ";
    109109                } // if
    110                 if ( qualifiers.isAtomic ) {
     110                if ( qualifiers.is_atomic ) {
    111111                        os << "_Atomic ";
    112112                } // if
     
    238238
    239239        void GenType::handleQualifiers( Type *type ) {
    240                 if ( type->get_isConst() ) {
     240                if ( type->get_const() ) {
    241241                        typeString = "const " + typeString;
    242242                } // if
    243                 if ( type->get_isVolatile() ) {
     243                if ( type->get_volatile() ) {
    244244                        typeString = "volatile " + typeString;
    245245                } // if
    246                 if ( type->get_isRestrict() ) {
     246                if ( type->get_restrict() ) {
    247247                        typeString = "__restrict " + typeString;
    248248                } // if
    249                 if ( type->get_isAtomic() ) {
     249                if ( type->get_atomic() ) {
    250250                        typeString = "_Atomic " + typeString;
    251251                } // if
  • src/Concurrency/Keywords.cc

    rb32ada31 r7c70089  
    1212// Last Modified By :
    1313// Last Modified On :
    14 // Update Count     : 1
     14// Update Count     : 3
    1515//
    1616
     
    264264                        //Find mutex arguments
    265265                        Type* ty = arg->get_type();
    266                         if( ! ty->get_qualifiers().isMutex ) continue;
     266                        if( ! ty->get_mutex() ) continue;
    267267
    268268                        //Append it to the list
     
    285285
    286286                //Make sure that typed isn't mutex
    287                 if( base->get_qualifiers().isMutex ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
     287                if( ! base->get_mutex() ) throw SemanticError( "mutex keyword may only appear once per argument ", arg );
    288288        }
    289289
  • src/GenPoly/Box.cc

    rb32ada31 r7c70089  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 08:35:33 2017
    13 // Update Count     : 338
     12// Last Modified On : Fri Mar 17 09:06:37 2017
     13// Update Count     : 339
    1414//
    1515
     
    753753                                        // if the argument's type is polymorphic, we don't need to box again!
    754754                                        return;
    755                                 } else if ( arg->get_result()->get_isLvalue() ) {
     755                                } else if ( arg->get_result()->get_lvalue() ) {
    756756                                        // VariableExpr and MemberExpr are lvalues; need to check this isn't coming from the second arg of a comma expression though (not an lvalue)
    757757                                        // xxx - need to test that this code is still reachable
  • src/GenPoly/Lvalue.cc

    rb32ada31 r7c70089  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec 15 15:33:13 2015
    13 // Update Count     : 3
     12// Last Modified On : Fri Mar 17 09:11:18 2017
     13// Update Count     : 5
    1414//
    1515
     
    7979                        if ( function->get_returnVals().empty() ) return 0;
    8080                        Type *ty = function->get_returnVals().front()->get_type();
    81                         return ty->get_isLvalue() ? ty : 0;
     81                        return ty->get_lvalue() ? ty : 0;
    8282                }
    8383
     
    134134                Statement * Pass1::mutate(ReturnStmt *retStmt) {
    135135                        if ( retval && retStmt->get_expr() ) {
    136                                 if ( retStmt->get_expr()->get_result()->get_isLvalue() ) {
     136                                if ( retStmt->get_expr()->get_result()->get_lvalue() ) {
    137137                                        // ***** Code Removal ***** because casts may be stripped already
    138138
  • src/GenPoly/ScrubTyVars.cc

    rb32ada31 r7c70089  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 19 16:42:42 2015
    13 // Update Count     : 2
     12// Last Modified On : Thu Mar 16 15:44:27 2017
     13// Update Count     : 3
    1414//
    1515
     
    109109                if ( Type *dynType = shouldScrub( pointer->get_base() ) ) {
    110110                        Type *ret = dynType->acceptMutator( *this );
    111                         ret->get_qualifiers() += pointer->get_qualifiers();
     111                        ret->get_qualifiers() |= pointer->get_qualifiers();
    112112                        pointer->set_base( 0 );
    113113                        delete pointer;
  • src/InitTweak/FixInit.cc

    rb32ada31 r7c70089  
    1010// Created On       : Wed Jan 13 16:29:30 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 08:08:04 2017
    13 // Update Count     : 67
     12// Last Modified On : Fri Mar 17 09:13:47 2017
     13// Update Count     : 71
    1414//
    1515
     
    232232                        void handleFirstParam( Expression * firstParam );
    233233                        template< typename... Params >
    234                         void emit( const Params &... params );
     234                        void emit( CodeLocation, const Params &... params );
    235235
    236236                        FunctionDecl * function = 0;
    237                         std::set< DeclarationWithType * > unhandled, usedUninit;
     237                        std::set< DeclarationWithType * > unhandled;
     238                        std::map< DeclarationWithType *, CodeLocation > usedUninit;
    238239                        ObjectDecl * thisParam = 0;
    239240                        bool isCtor = false; // true if current function is a constructor
     
    336337                        GenStructMemberCalls warner;
    337338                        acceptAll( translationUnit, warner );
    338 
    339                         // visitor doesn't throw so that it can collect all errors
    340                         if ( ! warner.errors.isEmpty() ) {
    341                                 throw warner.errors;
    342                         }
    343339                }
    344340
     
    438434                        env->apply( result );
    439435                        ObjectDecl * tmp = new ObjectDecl( tempNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
    440                         tmp->get_type()->set_isConst( false );
     436                        tmp->get_type()->set_const( false );
    441437
    442438                        // create and resolve copy constructor
     
    484480                                env->apply( result );
    485481                                ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
    486                                 ret->get_type()->set_isConst( false );
     482                                ret->get_type()->set_const( false );
    487483                                impCpCtorExpr->get_returnDecls().push_back( ret );
    488484                                CP_CTOR_PRINT( std::cerr << "makeCtorDtor for a return" << std::endl; )
    489                                 if ( ! result->get_isLvalue() ) {
     485                                if ( ! result->get_lvalue() ) {
    490486                                        // destructing lvalue returns is bad because it can cause multiple destructor calls to the same object - the returned object is not a temporary
    491487                                        destructRet( ret, impCpCtorExpr );
     
    507503                                env->apply( result );
    508504                                ObjectDecl * ret = new ObjectDecl( retNamer.newName(), Type::StorageClasses(), LinkageSpec::C, 0, result, 0 );
    509                                 ret->get_type()->set_isConst( false );
     505                                ret->get_type()->set_const( false );
    510506                                stmtExpr->get_returnDecls().push_front( ret );
    511507
     
    588584
    589585                                Expression * retExpr = new CommaExpr( assign, new VariableExpr( returnDecl ) );
    590                                 if ( callExpr->get_result()->get_isLvalue() ) {
     586                                if ( callExpr->get_result()->get_lvalue() ) {
    591587                                        // lvalue returning functions are funny. Lvalue.cc inserts a *? in front of any lvalue returning
    592588                                        // non-intrinsic function. Add an AddressExpr to the call to negate the derefence and change the
     
    940936                        ValueGuard< FunctionDecl * > oldFunction( funcDecl );
    941937                        ValueGuard< std::set< DeclarationWithType * > > oldUnhandled( unhandled );
    942                         ValueGuard< std::set< DeclarationWithType * > > oldUsedUninit( usedUninit );
     938                        ValueGuard< std::map< DeclarationWithType *, CodeLocation > > oldUsedUninit( usedUninit );
    943939                        ValueGuard< ObjectDecl * > oldThisParam( thisParam );
    944940                        ValueGuard< bool > oldIsCtor( isCtor );
    945941                        ValueGuard< StructDecl * > oldStructDecl( structDecl );
     942                        errors = SemanticError();  // clear previous errors
    946943
    947944                        // need to start with fresh sets
     
    972969                        // remove the unhandled objects from usedUninit, because a call is inserted
    973970                        // to handle them - only objects that are later constructed are used uninitialized.
    974                         std::set< DeclarationWithType * > diff;
    975                         std::set_difference( usedUninit.begin(), usedUninit.end(), unhandled.begin(), unhandled.end(), std::inserter( diff, diff.begin() ) );
    976                         for ( DeclarationWithType * member : diff ) {
    977                                 emit( "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", member->get_name(), " used before being constructed" );
     971                        std::map< DeclarationWithType *, CodeLocation > diff;
     972                        // need the comparator since usedUninit and unhandled have different types
     973                        struct comp_t {
     974                                typedef decltype(usedUninit)::value_type usedUninit_t;
     975                                typedef decltype(unhandled)::value_type unhandled_t;
     976                                bool operator()(usedUninit_t x, unhandled_t y) { return x.first < y; }
     977                                bool operator()(unhandled_t x, usedUninit_t y) { return x < y.first; }
     978                        } comp;
     979                        std::set_difference( usedUninit.begin(), usedUninit.end(), unhandled.begin(), unhandled.end(), std::inserter( diff, diff.begin() ), comp );
     980                        for ( auto p : diff ) {
     981                                DeclarationWithType * member = p.first;
     982                                CodeLocation loc = p.second;
     983                                // xxx - make error message better by also tracking the location that the object is constructed at?
     984                                emit( loc, "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", member->get_name(), " used before being constructed" );
    978985                        }
    979986
     
    10201027                                                        }
    10211028                                                } catch ( SemanticError & error ) {
    1022                                                         emit( "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", field->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed",  " and no ", isCtor ? "default constructor" : "destructor", " found" );
     1029                                                        emit( funcDecl->location, "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", field->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed",  " and no ", isCtor ? "default constructor" : "destructor", " found" );
    10231030                                                }
    10241031                                        }
    10251032                                }
    10261033                                leaveScope();
     1034                        }
     1035                        if (! errors.isEmpty()) {
     1036                                throw errors;
    10271037                        }
    10281038                }
     
    10791089                                                        if ( unhandled.count( memberExpr->get_member() ) ) {
    10801090                                                                // emit a warning because a member was used before it was constructed
    1081                                                                 usedUninit.insert( memberExpr->get_member() );
     1091                                                                usedUninit.insert( { memberExpr->get_member(), memberExpr->location } );
    10821092                                                        }
    10831093                                                }
     
    10891099
    10901100                template< typename Visitor, typename... Params >
    1091                 void error( Visitor & v, const Params &... params ) {
    1092                         v.errors.append( toString( params... ) );
     1101                void error( Visitor & v, CodeLocation loc, const Params &... params ) {
     1102                        SemanticError err( toString( params... ) );
     1103                        err.set_location( loc );
     1104                        v.errors.append( err );
    10931105                }
    10941106
    10951107                template< typename... Params >
    1096                 void GenStructMemberCalls::emit( const Params &... params ) {
     1108                void GenStructMemberCalls::emit( CodeLocation loc, const Params &... params ) {
    10971109                        // toggle warnings vs. errors here.
    10981110                        // warn( params... );
    1099                         error( *this, params... );
     1111                        error( *this, loc, params... );
    11001112                }
    11011113
  • src/InitTweak/GenInit.cc

    rb32ada31 r7c70089  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 08:01:25 2017
    13 // Update Count     : 181
     12// Last Modified On : Fri Mar 17 09:12:36 2017
     13// Update Count     : 183
    1414//
    1515
     
    143143                // is being returned
    144144                // Note: under the assumption that assignments return *this, checking for ?=? here is an optimization, since it shouldn't be necessary to copy construct `this`. This is a temporary optimization until reference types are added, at which point this should be removed, along with the analogous optimization in copy constructor generation.
    145                 if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_isLvalue() ) {
     145                if ( returnStmt->get_expr() && returnVals.size() == 1 && funcName != "?=?" && ! returnVals.front()->get_type()->get_lvalue() ) {
    146146                        // explicitly construct the return value using the return expression and the retVal object
    147147                        assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() );
     
    195195
    196196                        ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, SymTab::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) );
    197                         arrayDimension->get_type()->set_isConst( true );
     197                        arrayDimension->get_type()->set_const( true );
    198198
    199199                        arrayType->set_dimension( new VariableExpr( arrayDimension ) );
  • src/Parser/DeclarationNode.cc

    rb32ada31 r7c70089  
    1010// Created On       : Sat May 16 12:34:05 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 09:10:57 2017
    13 // Update Count     : 1007
     12// Last Modified On : Fri Mar 17 08:46:05 2017
     13// Update Count     : 1017
    1414//
    1515
     
    1919#include <algorithm>
    2020#include <cassert>
    21 #include <strings.h>                                                                    // ffs
    2221
    2322#include "TypeData.h"
     
    243242
    244243DeclarationNode * DeclarationNode::newAggregate( Aggregate kind, const string * name, ExpressionNode * actuals, DeclarationNode * fields, bool body ) {
     244        assert( name );
    245245        DeclarationNode * newnode = new DeclarationNode;
    246246        newnode->type = new TypeData( TypeData::Aggregate );
    247247        newnode->type->aggregate.kind = kind;
    248         if ( name ) {
    249                 newnode->type->aggregate.name = name;
    250         } else {                                                                                        // anonymous aggregate ?
    251                 newnode->type->aggregate.name = new string( anonymous.newName() );
    252         } // if
     248        newnode->type->aggregate.name = name;
    253249        newnode->type->aggregate.actuals = actuals;
    254250        newnode->type->aggregate.fields = fields;
     
    258254
    259255DeclarationNode * DeclarationNode::newEnum( string * name, DeclarationNode * constants, bool body ) {
     256        assert( name );
    260257        DeclarationNode * newnode = new DeclarationNode;
    261258        newnode->type = new TypeData( TypeData::Enum );
    262         if ( name ) {
    263                 newnode->type->enumeration.name = name;
    264         } else {                                                                                        // anonymous aggregate ?
    265                 newnode->type->enumeration.name = new string( anonymous.newName() );
    266         } // if
     259        newnode->type->enumeration.name = name;
    267260        newnode->type->enumeration.constants = constants;
    268261        newnode->type->enumeration.body = body;
     
    436429        const Type::Qualifiers qsrc = src->qualifiers, qdst = dst->qualifiers; // optimization
    437430
    438         if ( (qsrc.val & qdst.val) != 0 ) {                                     // duplicates ?
     431        if ( (qsrc & qdst).any() ) {                                            // duplicates ?
    439432                for ( unsigned int i = 0; i < Type::NumTypeQualifier; i += 1 ) { // find duplicates
    440433                        if ( qsrc[i] && qdst[i] ) {
    441                                 appendError( error, string( "duplicate " ) + Type::Qualifiers::Names[i] );
     434                                appendError( error, string( "duplicate " ) + Type::QualifiersNames[i] );
    442435                        } // if
    443436                } // for
     
    446439
    447440void DeclarationNode::checkSpecifiers( DeclarationNode * src ) {
    448         if ( (funcSpecs.val & src->funcSpecs.val) != 0 ) {      // duplicates ?
     441        if ( (funcSpecs & src->funcSpecs).any() ) {                     // duplicates ?
    449442                for ( unsigned int i = 0; i < Type::NumFuncSpecifier; i += 1 ) { // find duplicates
    450443                        if ( funcSpecs[i] && src->funcSpecs[i] ) {
    451                                 appendError( error, string( "duplicate " ) + Type::FuncSpecifiers::Names[i] );
     444                                appendError( error, string( "duplicate " ) + Type::FuncSpecifiersNames[i] );
    452445                        } // if
    453446                } // for
     
    455448
    456449        if ( storageClasses.any() && src->storageClasses.any() ) { // any reason to check ?
    457                 if ( (storageClasses.val & src->storageClasses.val ) != 0 ) { // duplicates ?
     450                if ( (storageClasses & src->storageClasses ).any() ) { // duplicates ?
    458451                        for ( unsigned int i = 0; i < Type::NumStorageClass; i += 1 ) { // find duplicates
    459452                                if ( storageClasses[i] && src->storageClasses[i] ) {
    460                                         appendError( error, string( "duplicate " ) + Type::StorageClasses::Names[i] );
     453                                        appendError( error, string( "duplicate " ) + Type::StorageClassesNames[i] );
    461454                                } // if
    462455                        } // for
    463456                        // src is the new item being added and has a single bit
    464457                } else if ( ! src->storageClasses.is_threadlocal ) { // conflict ?
    465                         appendError( error, string( "conflicting " ) + Type::StorageClasses::Names[ffs( storageClasses.val ) - 1] +
    466                                                  " & " + Type::StorageClasses::Names[ffs( src->storageClasses.val ) - 1] );
    467                         src->storageClasses.val = 0;                            // FIX to preserve invariant of one basic storage specifier
     458                        appendError( error, string( "conflicting " ) + Type::StorageClassesNames[storageClasses.ffs()] +
     459                                                 " & " + Type::StorageClassesNames[src->storageClasses.ffs()] );
     460                        src->storageClasses.reset();                            // FIX to preserve invariant of one basic storage specifier
    468461                } // if
    469462        } // if
     
    473466
    474467DeclarationNode * DeclarationNode::copySpecifiers( DeclarationNode * q ) {
    475         funcSpecs.val |= q->funcSpecs.val;
    476         storageClasses.val |= q->storageClasses.val;
     468        funcSpecs |= q->funcSpecs;
     469        storageClasses |= q->storageClasses;
    477470
    478471        for ( Attribute *attr: reverseIterate( q->attributes ) ) {
     
    497490                src = nullptr;
    498491        } else {
    499                 dst->qualifiers += src->qualifiers;
     492                dst->qualifiers |= src->qualifiers;
    500493        } // if
    501494} // addQualifiersToType
     
    555548                switch ( dst->kind ) {
    556549                  case TypeData::Unknown:
    557                         src->qualifiers += dst->qualifiers;
     550                        src->qualifiers |= dst->qualifiers;
    558551                        dst = src;
    559552                        src = nullptr;
    560553                        break;
    561554                  case TypeData::Basic:
    562                         dst->qualifiers += src->qualifiers;
     555                        dst->qualifiers |= src->qualifiers;
    563556                        if ( src->kind != TypeData::Unknown ) {
    564557                                assert( src->kind == TypeData::Basic );
     
    596589                                        dst->base->aggInst.params = maybeClone( src->aggregate.actuals );
    597590                                } // if
    598                                 dst->base->qualifiers += src->qualifiers;
     591                                dst->base->qualifiers |= src->qualifiers;
    599592                                src = nullptr;
    600593                                break;
     
    628621                                                type->aggInst.hoistType = o->type->enumeration.body;
    629622                                        } // if
    630                                         type->qualifiers += o->type->qualifiers;
     623                                        type->qualifiers |= o->type->qualifiers;
    631624                                } else {
    632625                                        type = o->type;
     
    784777                                        p->type->base->aggInst.params = maybeClone( type->aggregate.actuals );
    785778                                } // if
    786                                 p->type->base->qualifiers += type->qualifiers;
     779                                p->type->base->qualifiers |= type->qualifiers;
    787780                                break;
    788781
     
    821814                                lastArray->base->aggInst.params = maybeClone( type->aggregate.actuals );
    822815                        } // if
    823                         lastArray->base->qualifiers += type->qualifiers;
     816                        lastArray->base->qualifiers |= type->qualifiers;
    824817                        break;
    825818                  default:
  • src/Parser/ExpressionNode.cc

    rb32ada31 r7c70089  
    254254Expression *build_pfieldSel( ExpressionNode *expr_node, Expression *member ) {
    255255        UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
     256        deref->location = expr_node->location;
    256257        deref->get_args().push_back( maybeMoveBuild< Expression >(expr_node) );
    257258        UntypedMemberExpr *ret = new UntypedMemberExpr( member, deref );
  • src/Parser/ParseNode.h

    rb32ada31 r7c70089  
    134134                        Expression * p = orig->build();
    135135                        p->set_extension( orig->get_extension() );
     136                        p->location = orig->location;
    136137                        return p;
    137138                } else {
  • src/Parser/TypeData.cc

    rb32ada31 r7c70089  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 08:32:42 2017
    13 // Update Count     : 559
     12// Last Modified On : Fri Mar 17 08:46:10 2017
     13// Update Count     : 560
    1414//
    1515
     
    227227void TypeData::print( ostream &os, int indent ) const {
    228228        for ( int i = 0; i < Type::NumTypeQualifier; i += 1 ) {
    229                 if ( qualifiers[i] ) os << Type::Qualifiers::Names[ i ] << ' ';
     229                if ( qualifiers[i] ) os << Type::QualifiersNames[ i ] << ' ';
    230230        } // for
    231231
  • src/Parser/lex.ll

    rb32ada31 r7c70089  
    1010 * Created On       : Sat Sep 22 08:58:10 2001
    1111 * Last Modified By : Peter A. Buhr
    12  * Last Modified On : Thu Mar  9 21:38:26 2017
    13  * Update Count     : 505
     12 * Last Modified On : Mon Mar 13 08:36:17 2017
     13 * Update Count     : 506
    1414 */
    1515
     
    313313
    314314                                /* punctuation */
     315"@"                             { ASCIIOP_RETURN(); }
    315316"["                             { ASCIIOP_RETURN(); }
    316317"]"                             { ASCIIOP_RETURN(); }
  • src/Parser/parser.yy

    rb32ada31 r7c70089  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 08:36:17 2017
    13 // Update Count     : 2310
     12// Last Modified On : Thu Mar 16 12:57:03 2017
     13// Update Count     : 2316
    1414//
    1515
     
    16121612aggregate_type:                                                                                 // struct, union
    16131613        aggregate_key attribute_list_opt '{' field_declaration_list '}'
    1614                 { $$ = DeclarationNode::newAggregate( $1, nullptr, nullptr, $4, true )->addQualifiers( $2 ); }
     1614                { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), nullptr, $4, true )->addQualifiers( $2 ); }
    16151615        | aggregate_key attribute_list_opt no_attr_identifier_or_type_name
    16161616                { typedefTable.makeTypedef( *$3 ); }
     
    16181618                { $$ = DeclarationNode::newAggregate( $1, $3, nullptr, $6, true )->addQualifiers( $2 ); }
    16191619        | aggregate_key attribute_list_opt '(' type_name_list ')' '{' field_declaration_list '}' // CFA
    1620                 { $$ = DeclarationNode::newAggregate( $1, nullptr, $4, $7, false )->addQualifiers( $2 ); }
     1620                { $$ = DeclarationNode::newAggregate( $1, new string( DeclarationNode::anonymous.newName() ), $4, $7, false )->addQualifiers( $2 ); }
    16211621        | aggregate_type_nobody
    16221622        ;
     
    16881688        // empty
    16891689                { $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name
    1690         // '@' // empty
    1691         //      { $$ = DeclarationNode::newName( 0 ); /* XXX */ } // CFA, no field name
     1690        // '@'
     1691        //      { $$ = DeclarationNode::newName( new string( DeclarationNode::anonymous.newName() ) ); } // CFA, no field name
    16921692        | bit_subrange_size                                                                     // no field name
    16931693                { $$ = DeclarationNode::newBitfield( $1 ); }
     
    17151715enum_type:                                                                                              // enum
    17161716        ENUM attribute_list_opt '{' enumerator_list comma_opt '}'
    1717                 { $$ = DeclarationNode::newEnum( nullptr, $4, true )->addQualifiers( $2 ); }
     1717                { $$ = DeclarationNode::newEnum( new string( DeclarationNode::anonymous.newName() ), $4, true )->addQualifiers( $2 ); }
    17181718        | ENUM attribute_list_opt no_attr_identifier_or_type_name
    17191719                { typedefTable.makeTypedef( *$3 ); }
  • src/ResolvExpr/AlternativeFinder.cc

    rb32ada31 r7c70089  
    1010// Created On       : Sat May 16 23:52:08 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul  4 17:02:51 2016
    13 // Update Count     : 29
     12// Last Modified On : Fri Mar 17 09:14:17 2017
     13// Update Count     : 30
    1414//
    1515
     
    200200                }
    201201
    202                 // Central location to handle gcc extension keyword for all expression types.
     202                // Central location to handle gcc extension keyword, etc. for all expression types.
    203203                for ( Alternative &iter: alternatives ) {
    204204                        iter.expr->set_extension( expr->get_extension() );
     205                        iter.expr->location = expr->location;
    205206                } // for
    206207        }
     
    771772        bool isLvalue( Expression *expr ) {
    772773                // xxx - recurse into tuples?
    773                 return expr->has_result() && expr->get_result()->get_isLvalue();
     774                return expr->has_result() && expr->get_result()->get_lvalue();
    774775        }
    775776
  • src/ResolvExpr/CommonType.cc

    rb32ada31 r7c70089  
    1010// Created On       : Sun May 17 06:59:27 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:35:34 2016
    13 // Update Count     : 3
     12// Last Modified On : Thu Mar 16 16:24:31 2017
     13// Update Count     : 7
    1414//
    1515
     
    7171                                                        if ( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) {
    7272                                                                result = type1->clone();
    73                                                                 result->get_qualifiers() = tq1 + tq2;
     73                                                                result->get_qualifiers() = tq1 | tq2;
    7474                                                        } // if
    7575                                                        type1->get_qualifiers() = tq1;
     
    133133                        BasicType::Kind newType = combinedType[ basicType->get_kind() ][ otherBasic->get_kind() ];
    134134                        if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers() ) || widenSecond ) ) {
    135                                 result = new BasicType( basicType->get_qualifiers() + otherBasic->get_qualifiers(), newType );
     135                                result = new BasicType( basicType->get_qualifiers() | otherBasic->get_qualifiers(), newType );
    136136                        } // if
    137137                } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {
     
    139139                        BasicType::Kind newType = combinedType[ basicType->get_kind() ][ BasicType::SignedInt ];
    140140                        if ( ( ( newType == basicType->get_kind() && basicType->get_qualifiers() >= type2->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= type2->get_qualifiers() ) || widenSecond ) ) {
    141                                 result = new BasicType( basicType->get_qualifiers() + type2->get_qualifiers(), newType );
     141                                result = new BasicType( basicType->get_qualifiers() | type2->get_qualifiers(), newType );
    142142                        } // if
    143143                } // if
     
    154154                }
    155155                result = voidPointer->clone();
    156                 result->get_qualifiers() += otherPointer->get_qualifiers();
     156                result->get_qualifiers() |= otherPointer->get_qualifiers();
    157157        }
    158158
     
    176176                                                result = otherPointer->clone();
    177177                                        } // if
    178                                         result->get_qualifiers() = tq1 + tq2;
     178                                        result->get_qualifiers() = tq1 | tq2;
    179179                                } else {
    180180                                        /// std::cout << "place for ptr-to-type" << std::endl;
     
    185185                } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
    186186                        result = pointerType->clone();
    187                         result->get_qualifiers() += type2->get_qualifiers();
     187                        result->get_qualifiers() |= type2->get_qualifiers();
    188188                } // if
    189189        }
     
    230230                                        if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) {
    231231                                                result = type2->clone();
    232                                                 result->get_qualifiers() = tq1 + tq2;
     232                                                result->get_qualifiers() = tq1 | tq2;
    233233                                        } // if
    234234                                        type2->get_qualifiers() = tq2;
     
    250250                                if ( widenSecond || zeroType->get_qualifiers() <= type2->get_qualifiers() ) {
    251251                                        result = type2->clone();
    252                                         result->get_qualifiers() += zeroType->get_qualifiers();
     252                                        result->get_qualifiers() |= zeroType->get_qualifiers();
    253253                                }
    254254                        } else if ( widenSecond && dynamic_cast< OneType* >( type2 ) ) {
    255255                                result = new BasicType( zeroType->get_qualifiers(), BasicType::SignedInt );
    256                                 result->get_qualifiers() += type2->get_qualifiers();
     256                                result->get_qualifiers() |= type2->get_qualifiers();
    257257                        }
    258258                }
     
    264264                                if ( widenSecond || oneType->get_qualifiers() <= type2->get_qualifiers() ) {
    265265                                        result = type2->clone();
    266                                         result->get_qualifiers() += oneType->get_qualifiers();
     266                                        result->get_qualifiers() |= oneType->get_qualifiers();
    267267                                }
    268268                        } else if ( widenSecond && dynamic_cast< ZeroType* >( type2 ) ) {
    269269                                result = new BasicType( oneType->get_qualifiers(), BasicType::SignedInt );
    270                                 result->get_qualifiers() += type2->get_qualifiers();
     270                                result->get_qualifiers() |= type2->get_qualifiers();
    271271                        }
    272272                }
  • src/ResolvExpr/Unify.cc

    rb32ada31 r7c70089  
    1010// Created On       : Sun May 17 12:27:10 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 07:59:59 2017
    13 // Update Count     : 40
     12// Last Modified On : Thu Mar 16 16:22:54 2017
     13// Update Count     : 42
    1414//
    1515
     
    353353#endif
    354354                        if ( ( common = commonType( type1, type2, widenMode.widenFirst, widenMode.widenSecond, indexer, env, openVars ) ) ) {
    355                                 common->get_qualifiers() = tq1 + tq2;
     355                                common->get_qualifiers() = tq1 | tq2;
    356356#ifdef DEBUG
    357357                                std::cerr << "unifyInexact: common type is ";
     
    370370                                if ( ( tq1 > tq2 || widenMode.widenFirst ) && ( tq2 > tq1 || widenMode.widenSecond ) ) {
    371371                                        common = type1->clone();
    372                                         common->get_qualifiers() = tq1 + tq2;
     372                                        common->get_qualifiers() = tq1 | tq2;
    373373                                        result = true;
    374374                                } else {
  • src/SymTab/Autogen.cc

    rb32ada31 r7c70089  
    1010// Created On       : Thu Mar 03 15:45:56 2016
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 08:37:22 2017
    13 // Update Count     : 59
     12// Last Modified On : Fri Mar 17 09:41:08 2017
     13// Update Count     : 60
    1414//
    1515
     
    323323                                }
    324324
    325                                 if ( type->get_qualifiers().isConst && func->get_name() == "?=?" ) {
     325                                if ( type->get_const() && func->get_name() == "?=?" ) {
    326326                                        // don't assign const members, but do construct/destruct
    327327                                        continue;
  • src/SymTab/Autogen.h

    rb32ada31 r7c70089  
    1010// Created On       : Sun May 17 21:53:34 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 07:51:39 2017
    13 // Update Count     : 8
     12// Last Modified On : Fri Mar 17 09:10:41 2017
     13// Update Count     : 9
    1414//
    1515
     
    6060//                      castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, false);
    6161                        castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    62                         castType->set_isLvalue( true ); // xxx - might not need this
     62                        castType->set_lvalue( true ); // xxx - might not need this
    6363                        dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) );
    6464                }
  • src/SymTab/ImplementationType.cc

    rb32ada31 r7c70089  
    1010// Created On       : Sun May 17 21:32:01 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Mar  2 17:31:20 2016
    13 // Update Count     : 3
     12// Last Modified On : Thu Mar 16 15:54:08 2017
     13// Update Count     : 4
    1414//
    1515
     
    105105                if ( typeDecl && typeDecl->get_base() ) {
    106106                        Type *base = implementationType( typeDecl->get_base(), indexer );
    107                         base->get_qualifiers() += inst->get_qualifiers();
     107                        base->get_qualifiers() |= inst->get_qualifiers();
    108108                        result = base;
    109109                } // if
     
    114114                for ( std::list< Type* >::iterator i = tupleType->get_types().begin(); i != tupleType->get_types().end(); ++i ) {
    115115                        Type *implType = implementationType( *i, indexer );
    116                         implType->get_qualifiers() += tupleType->get_qualifiers();
     116                        implType->get_qualifiers() |= tupleType->get_qualifiers();
    117117                        newType->get_types().push_back( implType );
    118118                } // for
  • src/SymTab/Mangler.cc

    rb32ada31 r7c70089  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:40:29 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Wed Aug 19 15:52:24 2015
    13 // Update Count     : 19
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Mar 17 09:40:01 2017
     13// Update Count     : 20
    1414//
    1515
     
    294294                        mangleName << "_";
    295295                } // if
    296                 if ( type->get_isConst() ) {
     296                if ( type->get_const() ) {
    297297                        mangleName << "C";
    298298                } // if
    299                 if ( type->get_isVolatile() ) {
     299                if ( type->get_volatile() ) {
    300300                        mangleName << "V";
    301301                } // if
     
    304304//                      mangleName << "R";
    305305//              } // if
    306                 if ( type->get_isLvalue() ) {
     306                if ( type->get_lvalue() ) {
    307307                        mangleName << "L";
    308308                } // if
    309                 if ( type->get_isAtomic() ) {
     309                if ( type->get_atomic() ) {
    310310                        mangleName << "A";
    311311                } // if
  • src/SymTab/Validate.cc

    rb32ada31 r7c70089  
    1010// Created On       : Sun May 17 21:50:04 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 08:02:54 2017
    13 // Update Count     : 351
     12// Last Modified On : Thu Mar 16 16:39:15 2017
     13// Update Count     : 353
    1414//
    1515
     
    611611                if ( def != typedefNames.end() ) {
    612612                        Type *ret = def->second.first->get_base()->clone();
    613                         ret->get_qualifiers() += typeInst->get_qualifiers();
     613                        ret->get_qualifiers() |= typeInst->get_qualifiers();
    614614                        // place instance parameters on the typedef'd type
    615615                        if ( ! typeInst->get_parameters().empty() ) {
     
    656656                // hence the type-name "screen" must be defined.
    657657                // Note, qualifiers on the typedef are superfluous for the forward declaration.
    658                 if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( tyDecl->get_base() ) ) {
     658
     659                Type *designatorType = tyDecl->get_base()->stripDeclarator();
     660                if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
    659661                        return new StructDecl( aggDecl->get_name() );
    660                 } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( tyDecl->get_base() ) ) {
     662                } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
    661663                        return new UnionDecl( aggDecl->get_name() );
    662                 } else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( tyDecl->get_base() ) ) {
     664                } else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
    663665                        return new EnumDecl( enumDecl->get_name() );
    664666                } else {
  • src/SynTree/ArrayType.cc

    rb32ada31 r7c70089  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Feb  1 17:16:29 2017
    13 // Update Count     : 12
     12// Last Modified On : Fri Mar 17 09:40:30 2017
     13// Update Count     : 13
    1414//
    1515
     
    2121ArrayType::ArrayType( const Type::Qualifiers &tq, Type *base, Expression *dimension, bool isVarLen, bool isStatic, const std::list< Attribute * > & attributes )
    2222        : Type( tq, attributes ), base( base ), dimension( dimension ), isVarLen( isVarLen ), isStatic( isStatic ) {
    23         base->set_isLvalue( false );
     23        base->set_lvalue( false );
    2424}
    2525
  • src/SynTree/Declaration.cc

    rb32ada31 r7c70089  
    3232
    3333Declaration::Declaration( const Declaration &other )
    34         : name( other.name ), storageClasses( other.storageClasses ), linkage( other.linkage ), uniqueId( other.uniqueId ) {
     34        : BaseSyntaxNode( other ), name( other.name ), storageClasses( other.storageClasses ), linkage( other.linkage ), uniqueId( other.uniqueId ) {
    3535}
    3636
  • src/SynTree/Expression.cc

    rb32ada31 r7c70089  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug  5 14:23:56 2016
    13 // Update Count     : 49
     12// Last Modified On : Fri Mar 17 09:42:04 2017
     13// Update Count     : 51
    1414//
    1515
     
    3333Expression::Expression( Expression *_aname ) : result( 0 ), env( 0 ), argName( _aname ) {}
    3434
    35 Expression::Expression( const Expression &other ) : result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ), extension( other.extension ) {
     35Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), argName( maybeClone( other.get_argName() ) ), extension( other.extension ) {
    3636}
    3737
     
    7777        assert( var->get_type() );
    7878        Type * type = var->get_type()->clone();
    79         type->set_isLvalue( true );
     79        type->set_lvalue( true );
    8080        set_result( type );
    8181}
     
    352352        sub.apply( res );
    353353        set_result( res );
    354         get_result()->set_isLvalue( true );
     354        get_result()->set_lvalue( true );
    355355}
    356356
  • src/SynTree/Initializer.cc

    rb32ada31 r7c70089  
    2020
    2121Initializer::Initializer( bool maybeConstructed ) : maybeConstructed( maybeConstructed ) {}
    22 Initializer::Initializer( const Initializer & other ) : maybeConstructed( other.maybeConstructed ) {
     22Initializer::Initializer( const Initializer & other ) : BaseSyntaxNode( other ), maybeConstructed( other.maybeConstructed ) {
    2323}
    2424
  • src/SynTree/Initializer.h

    rb32ada31 r7c70089  
    112112// ConstructorInit represents an initializer that is either a constructor expression or
    113113// a C-style initializer.
     114// It should not be necessary to create ConstructorInit nodes manually. Instead, set maybeConstructed
     115// to true on SingleInit or ListInit constructors if object should be constructed.
    114116class ConstructorInit : public Initializer {
    115117  public:
  • src/SynTree/TupleExpr.cc

    rb32ada31 r7c70089  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon May 18 10:59:19 2015
    13 // Update Count     : 1
     12// Last Modified On : Fri Mar 17 09:42:29 2017
     13// Update Count     : 3
    1414//
    1515
     
    6060        assertf( type->size() > index, "TupleIndexExpr index out of bounds: tuple size %d, requested index %d in expr %s", type->size(), index, toString( tuple ).c_str() );
    6161        set_result( (*std::next( type->get_types().begin(), index ))->clone() );
    62         get_result()->set_isLvalue( type->get_isLvalue() );
     62        get_result()->set_lvalue( type->get_lvalue() );
    6363}
    6464
  • src/SynTree/Type.cc

    rb32ada31 r7c70089  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 10:25:06 2017
    13 // Update Count     : 23
     12// Last Modified On : Fri Mar 17 08:42:47 2017
     13// Update Count     : 28
    1414//
    1515
     
    1919#include "Declaration.h"
    2020#include "Attribute.h"
     21#include "InitTweak/InitTweak.h"
    2122#include "Common/utility.h"
    2223
     
    4950Type::Type( const Qualifiers &tq, const std::list< Attribute * > & attributes ) : tq( tq ), attributes( attributes ) {}
    5051
    51 Type::Type( const Type &other ) : tq( other.tq ) {
     52Type::Type( const Type &other ) : BaseSyntaxNode( other ), tq( other.tq ) {
    5253        cloneAll( other.forall, forall );
    5354        cloneAll( other.attributes, attributes );
     
    6061
    6162// These must remain in the same order as the corresponding bit fields.
    62 const char * Type::FuncSpecifiers::Names[] = { "inline", "fortran", "_Noreturn" };
    63 const char * Type::StorageClasses::Names[] = { "extern", "static", "auto", "register", "_Thread_local" };
    64 const char * Type::Qualifiers::Names[] = { "const", "restrict", "volatile", "lvalue", "mutex", "_Atomic" };
     63const char * Type::FuncSpecifiersNames[] = { "inline", "fortran", "_Noreturn" };
     64const char * Type::StorageClassesNames[] = { "extern", "static", "auto", "register", "_Thread_local" };
     65const char * Type::QualifiersNames[] = { "const", "restrict", "volatile", "lvalue", "mutex", "_Atomic" };
     66
     67Type *Type::stripDeclarator() {
     68        Type * type = this;
     69        while ( Type * at = InitTweak::getPointerBase( type ) ) {
     70                type = at;
     71        }
     72        return type;
     73}
    6574
    6675void Type::print( std::ostream &os, int indent ) const {
     
    7584                printAll( attributes, os, indent+4 );
    7685        } // if
    77        
     86
    7887        tq.print( os );
    7988}
  • src/SynTree/Type.h

    rb32ada31 r7c70089  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 12:11:50 2017
    13 // Update Count     : 116
     12// Last Modified On : Fri Mar 17 09:04:03 2017
     13// Update Count     : 147
    1414//
    1515
     
    2121#include "SynTree.h"
    2222#include "Visitor.h"
     23#include <strings.h>                                                                    // ffs
    2324
    2425class Type : public BaseSyntaxNode {
    2526  public:
    26         #define CommonBF( N ) \
     27        // Simulate inheritance because union does not allow it.
     28        // Bug in g++-4.9 prevents static field in union
     29        //static const char * Names[];
     30        #define BFCommon( BFType, N ) \
    2731                bool operator[]( unsigned int i ) const { return val & (1 << i); } \
    2832                bool any() const { return val != 0; } \
    29                 static const char * Names[]; \
     33                void reset() { val = 0; } \
     34                int ffs() { return ::ffs( val ) - 1; } \
     35                BFType operator&=( BFType other ) { \
     36                        val &= other.val; return *this; \
     37                } \
     38                BFType operator&( BFType other ) const { \
     39                        BFType q = other; \
     40                        q &= *this; \
     41                        return q; \
     42                } \
     43                BFType operator|=( BFType other ) { \
     44                        val |= other.val; return *this; \
     45                } \
     46                BFType operator|( BFType other ) const { \
     47                        BFType q = other; \
     48                        q |= *this; \
     49                        return q; \
     50                } \
     51                BFType operator-=( BFType other ) { \
     52                        val &= ~other.val; return *this; \
     53                } \
    3054                void print( std::ostream & os ) const { \
    3155                        if ( (*this).any() ) { \
    3256                                for ( unsigned int i = 0; i < N; i += 1 ) { \
    3357                                        if ( (*this)[i] ) { \
    34                                                 os << Names[i] << ' '; \
     58                                                os << BFType##Names[i] << ' '; \
    3559                                        } \
    3660                                } \
     
    4165
    4266        enum { Inline = 1 << 0, Noreturn = 1 << 1, Fortran = 1 << 2, NumFuncSpecifier = 3 };
     67        static const char * FuncSpecifiersNames[];
    4368        union FuncSpecifiers {
    4469                unsigned int val;
     
    5075                FuncSpecifiers() : val( 0 ) {}
    5176                FuncSpecifiers( unsigned int val ) : val( val ) {}
    52                 CommonBF( NumFuncSpecifier )
     77                // equality (==, !=) works implicitly on first field "val", relational operations are undefined.
     78                BFCommon( FuncSpecifiers, NumFuncSpecifier )
    5379        }; // FuncSpecifiers
    5480
    5581        enum { Extern = 1 << 0, Static = 1 << 1, Auto = 1 << 2, Register = 1 << 3, Threadlocal = 1 << 4, NumStorageClass = 5 };
     82        static const char * StorageClassesNames[];
    5683        union StorageClasses {
    5784                unsigned int val;
     
    6693                StorageClasses() : val( 0 ) {}
    6794                StorageClasses( unsigned int val ) : val( val ) {}
    68                 CommonBF( NumStorageClass )
     95                // equality (==, !=) works implicitly on first field "val", relational operations are undefined.
     96                BFCommon( StorageClasses, NumStorageClass )
    6997        }; // StorageClasses
    7098
    7199        enum { Const = 1 << 0, Restrict = 1 << 1, Volatile = 1 << 2, Lvalue = 1 << 3, Mutex = 1 << 4, Atomic = 1 << 5, NumTypeQualifier = 6 };
     100        static const char * QualifiersNames[];
    72101        union Qualifiers {
    73102                enum { Mask = ~(Restrict | Lvalue) };
    74103                unsigned int val;
    75104                struct {
    76                         bool isConst : 1;
    77                         bool isRestrict : 1;
    78                         bool isVolatile : 1;
    79                         bool isLvalue : 1;
    80                         bool isMutex : 1;
    81                         bool isAtomic : 1;
     105                        bool is_const : 1;
     106                        bool is_restrict : 1;
     107                        bool is_volatile : 1;
     108                        bool is_lvalue : 1;
     109                        bool is_mutex : 1;
     110                        bool is_atomic : 1;
    82111                };
    83112
    84113                Qualifiers() : val( 0 ) {}
    85114                Qualifiers( unsigned int val ) : val( val ) {}
    86                 bool operator==( Qualifiers other ) const {
    87                         return (val & Mask) == (other.val & Mask);
     115                // Complex comparisons provide implicit qualifier downcasting, e.g., T downcast to const T.
     116                bool operator==( Qualifiers other ) const { return (val & Mask) == (other.val & Mask); }
     117                bool operator!=( Qualifiers other ) const { return (val & Mask) != (other.val & Mask); }
     118                bool operator<=( Qualifiers other ) const {
     119                        return is_const <= other.is_const && is_volatile <= other.is_volatile &&
     120                                is_mutex >= other.is_mutex && is_atomic == other.is_atomic;
    88121                }
    89                 bool operator!=( Qualifiers other ) const {
    90                         return (val & Mask) != (other.val & Mask);
    91                 }
    92                 bool operator<=( Qualifiers other ) const {
    93                         return isConst <= other.isConst && isVolatile <= other.isVolatile &&
    94                                 isMutex >= other.isMutex && isAtomic == other.isAtomic;
    95                 }
    96                 bool operator>=( Qualifiers other ) const {
    97                         return isConst >= other.isConst && isVolatile >= other.isVolatile &&
    98                                 isMutex <= other.isMutex && isAtomic == other.isAtomic;
    99                 }
    100                 bool operator<( Qualifiers other ) const {
    101                         return *this != other && *this <= other;
    102                 }
    103                 bool operator>( Qualifiers other ) const {
    104                         return *this != other && *this >= other;
    105                 }
    106                 Qualifiers operator&=( Type::Qualifiers other ) {
    107                         val &= other.val; return *this;
    108                 }
    109                 Qualifiers operator+=( Qualifiers other ) {
    110                         val |= other.val; return *this;
    111                 }
    112                 Qualifiers operator-=( Qualifiers other ) {
    113                         val &= ~other.val; return *this;
    114                 }
    115                 Qualifiers operator+( Qualifiers other ) const {
    116                         Qualifiers q = other;
    117                         q += *this;
    118                         return q;
    119                 }
    120                 CommonBF( NumTypeQualifier )
     122                bool operator<( Qualifiers other ) const { return *this != other && *this <= other; }
     123                bool operator>=( Qualifiers other ) const { return ! (*this < other); }
     124                bool operator>( Qualifiers other ) const { return *this != other && *this >= other; }
     125                BFCommon( Qualifiers, NumTypeQualifier )
    121126        }; // Qualifiers
    122127
     
    126131
    127132        Qualifiers & get_qualifiers() { return tq; }
    128         bool get_isConst() { return tq.isConst; }
    129         bool get_isVolatile() { return tq.isVolatile; }
    130         bool get_isRestrict() { return tq.isRestrict; }
    131         bool get_isLvalue() { return tq.isLvalue; }
    132         bool get_isAtomic() { return tq.isAtomic; }
    133         void set_isConst( bool newValue ) { tq.isConst = newValue; }
    134         void set_isVolatile( bool newValue ) { tq.isVolatile = newValue; }
    135         void set_isRestrict( bool newValue ) { tq.isRestrict = newValue; }
    136         void set_isLvalue( bool newValue ) { tq.isLvalue = newValue; }
    137         void set_isAtomic( bool newValue ) { tq.isAtomic = newValue; }
     133        bool get_const() { return tq.is_const; }
     134        bool get_volatile() { return tq.is_volatile; }
     135        bool get_restrict() { return tq.is_restrict; }
     136        bool get_lvalue() { return tq.is_lvalue; }
     137        bool get_mutex() { return tq.is_mutex; }
     138        bool get_atomic() { return tq.is_atomic; }
     139        void set_const( bool newValue ) { tq.is_const = newValue; }
     140        void set_volatile( bool newValue ) { tq.is_volatile = newValue; }
     141        void set_restrict( bool newValue ) { tq.is_restrict = newValue; }
     142        void set_lvalue( bool newValue ) { tq.is_lvalue = newValue; }
     143        void set_mutex( bool newValue ) { tq.is_mutex = newValue; }
     144        void set_atomic( bool newValue ) { tq.is_atomic = newValue; }
    138145
    139146        typedef std::list<TypeDecl *> ForallList;
     
    147154        virtual bool isVoid() const { return size() == 0; }
    148155        virtual Type * getComponent( unsigned i ) { assertf( size() == 1 && i == 0, "Type::getComponent was called with size %d and index %d\n", size(), i ); return this; }
     156
     157        Type *stripDeclarator();
    149158
    150159        virtual bool isComplete() const { return true; }
  • src/SynTree/TypeSubstitution.cc

    rb32ada31 r7c70089  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Rob Schluntz
    12 // Last Modified On : Tue Apr 26 11:15:29 2016
    13 // Update Count     : 3
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Thu Mar 16 15:54:35 2017
     13// Update Count     : 4
    1414//
    1515
     
    127127                subCount++;
    128128                Type *newtype = i->second->clone();
    129                 newtype->get_qualifiers() += inst->get_qualifiers();
     129                newtype->get_qualifiers() |= inst->get_qualifiers();
    130130                delete inst;
    131131                return newtype;
  • src/Tuples/TupleAssignment.cc

    rb32ada31 r7c70089  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 08:04:51 2017
    13 // Update Count     : 7
     12// Last Modified On : Fri Mar 17 09:43:03 2017
     13// Update Count     : 8
    1414//
    1515
     
    200200                                assert( type );
    201201                                type->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic );
    202                                 type->set_isLvalue( true ); // xxx - might not need this
     202                                type->set_lvalue( true ); // xxx - might not need this
    203203                                expr = new CastExpr( expr, castType );
    204204                        }
  • src/Tuples/TupleExpansion.cc

    rb32ada31 r7c70089  
    126126                /// given a expression representing the member and an expression representing the aggregate,
    127127                /// reconstructs a flattened UntypedMemberExpr with the right precedence
    128                 Expression * reconstructMemberExpr( Expression * member, Expression * aggr ) {
     128                Expression * reconstructMemberExpr( Expression * member, Expression * aggr, CodeLocation & loc ) {
    129129                        if ( UntypedMemberExpr * memberExpr = dynamic_cast< UntypedMemberExpr * >( member ) ) {
    130130                                // construct a new UntypedMemberExpr with the correct structure , and recursively
    131131                                // expand that member expression.
    132132                                MemberTupleExpander expander;
    133                                 UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->get_member(), new UntypedMemberExpr( memberExpr->get_aggregate(), aggr->clone() ) );
    134 
     133                                UntypedMemberExpr * inner = new UntypedMemberExpr( memberExpr->get_aggregate(), aggr->clone() );
     134                                UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->get_member(), inner );
     135                                inner->location = newMemberExpr->location = loc;
    135136                                memberExpr->set_member(nullptr);
    136137                                memberExpr->set_aggregate(nullptr);
     
    139140                        } else {
    140141                                // not a member expression, so there is nothing to do but attach and return
    141                                 return new UntypedMemberExpr( member, aggr->clone() );
     142                                UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( member, aggr->clone() );
     143                                newMemberExpr->location = loc;
     144                                return newMemberExpr;
    142145                        }
    143146                }
     
    152155                        aggr = new UniqueExpr( aggr );
    153156                        for ( Expression *& expr : tupleExpr->get_exprs() ) {
    154                                 expr = reconstructMemberExpr( expr, aggr );
     157                                expr = reconstructMemberExpr( expr, aggr, memberExpr->location );
     158                                expr->location = memberExpr->location;
    155159                        }
    156160                        delete aggr;
     161                        tupleExpr->location = memberExpr->location;
    157162                        return tupleExpr;
    158163                } else {
    159164                        // there may be a tuple expr buried in the aggregate
    160165                        // xxx - this is a memory leak
    161                         return new UntypedMemberExpr( memberExpr->get_member()->clone(), memberExpr->get_aggregate()->acceptMutator( *this ) );
     166                        UntypedMemberExpr * newMemberExpr = new UntypedMemberExpr( memberExpr->get_member()->clone(), memberExpr->get_aggregate()->acceptMutator( *this ) );
     167                        newMemberExpr->location = memberExpr->location;
     168                        return newMemberExpr;
    162169                }
    163170        }
  • src/tests/.expect/memberCtors-ERR1.txt

    rb32ada31 r7c70089  
    1 error: in void ?{}(struct B *b), field a2 used before being constructed
     1memberCtors.c:62 error: in void ?{}(struct B *b), field a2 used before being constructed
    22make: *** [memberCtors-ERR1] Error 1
Note: See TracChangeset for help on using the changeset viewer.