Changeset 90152a4 for src/SymTab


Ignore:
Timestamp:
Aug 27, 2018, 4:40:34 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
b7c89aa
Parents:
f9feab8 (diff), 305581d (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' into cleanup-dtors

Location:
src/SymTab
Files:
3 added
1 deleted
9 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Autogen.cc

    rf9feab8 r90152a4  
    99// Author           : Rob Schluntz
    1010// Created On       : Thu Mar 03 15:45:56 2016
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul 14 16:41:00 2017
    13 // Update Count     : 62
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Apr 27 14:39:06 2018
     13// Update Count     : 63
    1414//
    1515
     
    2424#include <vector>                  // for vector
    2525
    26 #include "AddVisit.h"              // for addVisit
    2726#include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign
    2827#include "Common/PassVisitor.h"    // for PassVisitor
     
    335334                        definitions.push_back( dcl );
    336335                        indexer.addId( dcl );
    337                 } catch ( SemanticError err ) {
     336                } catch ( SemanticErrorException & ) {
    338337                        // okay if decl does not resolve - that means the function should not be generated
    339338                        delete dcl;
     
    380379                        paramType->attributes.clear();
    381380                        // add a parameter corresponding to this field
    382                         memCtorType->parameters.push_back( new ObjectDecl( field->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType, nullptr ) );
     381                        ObjectDecl * param = new ObjectDecl( field->name, Type::StorageClasses(), LinkageSpec::Cforall, nullptr, paramType, nullptr );
     382                        cloneAll_if( field->attributes, param->attributes, [](Attribute * attr) { return attr->isValidOnFuncParam(); } );
     383                        memCtorType->parameters.push_back( param );
    383384                        FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting );
    384385                        makeFieldCtorBody( aggregateDecl->members.begin(), aggregateDecl->members.end(), ctor );
  • src/SymTab/FixFunction.cc

    rf9feab8 r90152a4  
    3030                // can't delete function type because it may contain assertions, so transfer ownership to new object
    3131                ObjectDecl *pointer = new ObjectDecl( functionDecl->name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, new PointerType( Type::Qualifiers(), functionDecl->type ), nullptr, functionDecl->attributes );
     32                pointer->location = functionDecl->location;
    3233                functionDecl->attributes.clear();
    3334                functionDecl->type = nullptr;
     
    3637        }
    3738
     39        // xxx - this passes on void[], e.g.
     40        //   void foo(void [10]);
     41        // does not cause an error
     42
    3843        Type * FixFunction::postmutate(ArrayType *arrayType) {
    3944                // need to recursively mutate the base type in order for multi-dimensional arrays to work.
    4045                PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic );
     46                pointerType->location = arrayType->location;
    4147                arrayType->base = nullptr;
    4248                arrayType->dimension = nullptr;
     
    6268        void FixFunction::premutate(ZeroType *) { visit_children = false; }
    6369        void FixFunction::premutate(OneType *) { visit_children = false; }
     70
     71        bool fixFunction( DeclarationWithType *& dwt ) {
     72                PassVisitor<FixFunction> fixer;
     73                dwt = dwt->acceptMutator( fixer );
     74                return fixer.pass.isVoid;
     75        }
    6476} // namespace SymTab
    6577
  • src/SymTab/FixFunction.h

    rf9feab8 r90152a4  
    4747                bool isVoid;
    4848        };
     49
     50        bool fixFunction( DeclarationWithType *& );
    4951} // namespace SymTab
    5052
  • src/SymTab/Indexer.cc

    rf9feab8 r90152a4  
    2626#include "Common/SemanticError.h"  // for SemanticError
    2727#include "Common/utility.h"        // for cloneAll
     28#include "GenPoly/GenPoly.h"
    2829#include "InitTweak/InitTweak.h"   // for isConstructor, isCopyFunction, isC...
    2930#include "Mangler.h"               // for Mangler
     
    105106                if ( ! CodeGen::isCtorDtorAssign( id ) ) return;
    106107
    107                 // helpful data structure
     108                // helpful data structure to organize properties for a type
    108109                struct ValueType {
    109                         struct DeclBall {
     110                        struct DeclBall { // properties for this particular decl
    110111                                IdData decl;
    111                                 bool isUserDefinedFunc; // properties for this particular decl
    112                                 bool isDefaultCtor;
    113                                 bool isDtor;
     112                                bool isUserDefinedFunc;
    114113                                bool isCopyFunc;
    115114                        };
    116115                        // properties for this type
    117                         bool existsUserDefinedFunc = false;    // any user-defined function found
    118                         bool existsUserDefinedCtor = false;    // any user-defined constructor found
    119                         bool existsUserDefinedDtor = false;    // any user-defined destructor found
    120116                        bool existsUserDefinedCopyFunc = false;    // user-defined copy ctor found
    121                         bool existsUserDefinedDefaultCtor = false; // user-defined default ctor found
     117                        BaseSyntaxNode * deleteStmt = nullptr;     // non-null if a user-defined function is found
    122118                        std::list< DeclBall > decls;
    123119
     
    126122                        ValueType & operator+=( IdData data ) {
    127123                                DeclarationWithType * function = data.id;
    128                                 bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->get_linkage() );
    129                                 bool isDefaultCtor = InitTweak::isDefaultConstructor( function );
    130                                 bool isDtor = InitTweak::isDestructor( function );
    131                                 bool isCopyFunc = InitTweak::isCopyFunction( function, function->get_name() );
    132                                 decls.push_back( DeclBall{ data, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } );
    133                                 existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc;
    134                                 existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) );
    135                                 existsUserDefinedDtor = existsUserDefinedDtor || (isUserDefinedFunc && isDtor);
     124                                bool isUserDefinedFunc = ! LinkageSpec::isOverridable( function->linkage );
     125                                bool isCopyFunc = InitTweak::isCopyFunction( function, function->name );
     126                                decls.push_back( DeclBall{ data, isUserDefinedFunc, isCopyFunc } );
    136127                                existsUserDefinedCopyFunc = existsUserDefinedCopyFunc || (isUserDefinedFunc && isCopyFunc);
    137                                 existsUserDefinedDefaultCtor = existsUserDefinedDefaultCtor || (isUserDefinedFunc && isDefaultCtor);
     128                                if ( isUserDefinedFunc && ! deleteStmt ) {
     129                                        // any user-defined function can act as an implicit delete statement for generated constructors.
     130                                        // a delete stmt should not act as an implicit delete statement.
     131                                        deleteStmt = data.id;
     132                                }
    138133                                return *this;
    139134                        }
     
    147142                for ( auto decl : copy ) {
    148143                        if ( FunctionDecl * function = dynamic_cast< FunctionDecl * >( decl.id ) ) {
    149                                 std::list< DeclarationWithType * > & params = function->get_functionType()->get_parameters();
     144                                std::list< DeclarationWithType * > & params = function->type->parameters;
    150145                                assert( ! params.empty() );
    151146                                // use base type of pointer, so that qualifiers on the pointer type aren't considered.
     
    159154
    160155                // if a type contains user defined ctor/dtor/assign, then special rules trigger, which determine
    161                 // the set of ctor/dtor/assign that are seen by the requester. In particular, if the user defines
    162                 // a default ctor, then the generated default ctor should never be seen, likewise for copy ctor
    163                 // and dtor. If the user defines any ctor/dtor, then no generated field ctors should be seen.
    164                 // If the user defines any ctor then the generated default ctor should not be seen (intrinsic default
    165                 // ctor must be overridden exactly).
     156                // the set of ctor/dtor/assign that can be used  by the requester. In particular, if the user defines
     157                // a default ctor, then the generated default ctor is unavailable, likewise for copy ctor
     158                // and dtor. If the user defines any ctor/dtor, then no generated field ctors are available.
     159                // If the user defines any ctor then the generated default ctor is unavailable (intrinsic default
     160                // ctor must be overridden exactly). If the user defines anything that looks like a copy constructor,
     161                // then the generated copy constructor is unavailable, and likewise for the assignment operator.
    166162                for ( std::pair< const std::string, ValueType > & pair : funcMap ) {
    167163                        ValueType & val = pair.second;
    168164                        for ( ValueType::DeclBall ball : val.decls ) {
    169                                 bool noUserDefinedFunc = ! val.existsUserDefinedFunc;
    170                                 bool isUserDefinedFunc = ball.isUserDefinedFunc;
    171                                 bool isAcceptableDefaultCtor = (! val.existsUserDefinedCtor || (! val.existsUserDefinedDefaultCtor && ball.decl.id->get_linkage() == LinkageSpec::Intrinsic)) && ball.isDefaultCtor; // allow default constructors only when no user-defined constructors exist, except in the case of intrinsics, which require exact overrides
    172                                 bool isAcceptableCopyFunc = ! val.existsUserDefinedCopyFunc && ball.isCopyFunc; // handles copy ctor and assignment operator
    173                                 bool isAcceptableDtor = ! val.existsUserDefinedDtor && ball.isDtor;
    174                                 if ( noUserDefinedFunc || isUserDefinedFunc || isAcceptableDefaultCtor || isAcceptableCopyFunc || isAcceptableDtor ) {
    175                                         // decl conforms to the rules described above, so it should be seen by the requester
    176                                         out.push_back( ball.decl );
     165                                bool isNotUserDefinedFunc = ! ball.isUserDefinedFunc && ball.decl.id->linkage != LinkageSpec::Intrinsic;
     166                                bool isCopyFunc = ball.isCopyFunc;
     167                                bool existsUserDefinedCopyFunc = val.existsUserDefinedCopyFunc;
     168
     169                                // only implicitly delete non-user defined functions that are not intrinsic, and are
     170                                // not copy functions (assignment or copy constructor). If a  user-defined copy function exists,
     171                                // do not pass along the non-user-defined copy functions since signatures do not have to match,
     172                                // and the generated functions will often be cheaper.
     173                                if ( isNotUserDefinedFunc ) {
     174                                        if ( isCopyFunc ) {
     175                                                // Skip over non-user-defined copy functions when there is a user-defined copy function.
     176                                                // Since their signatures do not have to be exact, deleting them is the wrong choice.
     177                                                if ( existsUserDefinedCopyFunc ) continue;
     178                                        } else {
     179                                                // delete non-user-defined non-copy functions if applicable.
     180                                                // deleteStmt will be non-null only if a user-defined function is found.
     181                                                ball.decl.deleteStmt = val.deleteStmt;
     182                                        }
    177183                                }
     184                                out.push_back( ball.decl );
    178185                        }
    179186                }
     
    265272        }
    266273
     274        NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const {
     275                return lookupTypeAtScope( id, 0 );
     276        }
     277
     278        StructDecl *Indexer::globalLookupStruct( const std::string &id ) const {
     279                return lookupStructAtScope( id, 0 );
     280        }
     281
     282        UnionDecl *Indexer::globalLookupUnion( const std::string &id ) const {
     283                return lookupUnionAtScope( id, 0 );
     284        }
     285
     286        EnumDecl *Indexer::globalLookupEnum( const std::string &id ) const {
     287                return lookupEnumAtScope( id, 0 );
     288        }
     289
    267290        EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
    268291                if ( ! tables ) return 0;
     
    286309        }
    287310
    288         DeclarationWithType *Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
    289                 if ( ! tables ) return 0;
    290                 if ( tables->scope < scope ) return 0;
     311        const Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
     312                if ( ! tables ) return nullptr;
     313                if ( tables->scope < scope ) return nullptr;
    291314
    292315                IdTable::const_iterator decls = tables->idTable.find( id );
     
    294317                        const MangleTable &mangleTable = decls->second;
    295318                        MangleTable::const_iterator decl = mangleTable.find( mangleName );
    296                         if ( decl != mangleTable.end() ) return decl->second.id;
     319                        if ( decl != mangleTable.end() ) return &decl->second;
    297320                }
    298321
    299322                return tables->base.lookupIdAtScope( id, mangleName, scope );
     323        }
     324
     325        Indexer::IdData * Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) {
     326                return const_cast<IdData *>(const_cast<const Indexer *>(this)->lookupIdAtScope( id, mangleName, scope ));
    300327        }
    301328
     
    336363                if ( ! tables ) return 0;
    337364                if ( tables->scope < scope ) return 0;
     365                if ( tables->scope > scope ) return tables->base.lookupTypeAtScope( id, scope );
    338366
    339367                TypeTable::const_iterator ret = tables->typeTable.find( id );
     
    344372                if ( ! tables ) return 0;
    345373                if ( tables->scope < scope ) return 0;
     374                if ( tables->scope > scope ) return tables->base.lookupStructAtScope( id, scope );
    346375
    347376                StructTable::const_iterator ret = tables->structTable.find( id );
     
    352381                if ( ! tables ) return 0;
    353382                if ( tables->scope < scope ) return 0;
     383                if ( tables->scope > scope ) return tables->base.lookupEnumAtScope( id, scope );
    354384
    355385                EnumTable::const_iterator ret = tables->enumTable.find( id );
     
    360390                if ( ! tables ) return 0;
    361391                if ( tables->scope < scope ) return 0;
     392                if ( tables->scope > scope ) return tables->base.lookupUnionAtScope( id, scope );
    362393
    363394                UnionTable::const_iterator ret = tables->unionTable.find( id );
     
    368399                if ( ! tables ) return 0;
    369400                if ( tables->scope < scope ) return 0;
     401                if ( tables->scope > scope ) return tables->base.lookupTraitAtScope( id, scope );
    370402
    371403                TraitTable::const_iterator ret = tables->traitTable.find( id );
     
    373405        }
    374406
    375         bool addedIdConflicts( DeclarationWithType *existing, DeclarationWithType *added ) {
     407        bool isFunction( DeclarationWithType * decl ) {
     408                return GenPoly::getFunctionType( decl->get_type() );
     409        }
     410
     411        bool isObject( DeclarationWithType * decl ) {
     412                return ! isFunction( decl );
     413        }
     414
     415        bool isDefinition( DeclarationWithType * decl ) {
     416                if ( FunctionDecl * func = dynamic_cast< FunctionDecl * >( decl ) ) {
     417                        // a function is a definition if it has a body
     418                        return func->statements;
     419                } else {
     420                        // an object is a definition if it is not marked extern.
     421                        // both objects must be marked extern
     422                        return ! decl->get_storageClasses().is_extern;
     423                }
     424        }
     425
     426        bool addedIdConflicts( Indexer::IdData & existing, DeclarationWithType *added, BaseSyntaxNode * deleteStmt, Indexer::ConflictFunction handleConflicts ) {
    376427                // if we're giving the same name mangling to things of different types then there is something wrong
    377                 assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing ) )
    378                         || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing ) ) );
    379 
    380                 if ( LinkageSpec::isOverridable( existing->get_linkage() ) ) {
     428                assert( (isObject( added ) && isObject( existing.id ) )
     429                        || ( isFunction( added ) && isFunction( existing.id ) ) );
     430
     431                if ( LinkageSpec::isOverridable( existing.id->get_linkage() ) ) {
    381432                        // new definition shadows the autogenerated one, even at the same scope
    382433                        return false;
    383                 } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) {
    384                         // typesCompatible doesn't really do the right thing here. When checking compatibility of function types,
    385                         // we should ignore outermost pointer qualifiers, except _Atomic?
    386                         FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( added );
    387                         FunctionDecl *oldentry = dynamic_cast< FunctionDecl* >( existing );
    388                         if ( newentry && oldentry ) {
    389                                 if ( newentry->get_statements() && oldentry->get_statements() ) {
    390                                         throw SemanticError( "duplicate function definition for ", added );
    391                                 } // if
    392                         } else {
    393                                 // two objects with the same mangled name defined in the same scope.
    394                                 // both objects must be marked extern or both must be intrinsic for this to be okay
    395                                 // xxx - perhaps it's actually if either is intrinsic then this is okay?
    396                                 //       might also need to be same storage class?
    397                                 ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( added );
    398                                 ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( existing );
    399                                 if ( ! newobj->get_storageClasses().is_extern && ! oldobj->get_storageClasses().is_extern ) {
    400                                         throw SemanticError( "duplicate object definition for ", added );
     434                } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing.id->get_type(), Indexer() ) ) {
     435
     436                        // it is a conflict if one declaration is deleted and the other is not
     437                        if ( deleteStmt && ! existing.deleteStmt ) {
     438                                return handleConflicts( existing, "deletion of defined identifier " );
     439                        } else if ( ! deleteStmt && existing.deleteStmt ) {
     440                                return handleConflicts( existing, "definition of deleted identifier " );
     441                        }
     442
     443                        if ( isDefinition( added ) && isDefinition( existing.id ) ) {
     444                                if ( isFunction( added ) ) {
     445                                        return handleConflicts( existing, "duplicate function definition for " );
     446                                } else {
     447                                        return handleConflicts( existing, "duplicate object definition for " );
    401448                                } // if
    402449                        } // if
    403450                } else {
    404                         throw SemanticError( "duplicate definition for ", added );
     451                        return handleConflicts( existing, "duplicate definition for " );
    405452                } // if
    406453
     
    408455        }
    409456
    410         void Indexer::addId( DeclarationWithType *decl, Expression * baseExpr ) {
     457        void Indexer::addId( DeclarationWithType *decl, ConflictFunction handleConflicts, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) {
     458                if ( decl->name == "" ) return;
    411459                debugPrint( "Adding Id " << decl->name << std::endl );
    412460                makeWritable();
     
    430478                        // isomorphic to C type-compatibility, which it may not be.
    431479                        if ( hasIncompatibleCDecl( name, mangleName, scope ) ) {
    432                                 throw SemanticError( "conflicting overload of C function ", decl );
    433                         }
    434                 } else {
    435                         // Check that a Cforall declaration doesn't overload any C declaration
     480                                SemanticError( decl, "conflicting overload of C function " );
     481                        }
     482                } else {
     483                        // Check that a Cforall declaration doesn't override any C declaration
    436484                        if ( hasCompatibleCDecl( name, mangleName, scope ) ) {
    437                                 throw SemanticError( "Cforall declaration hides C function ", decl );
     485                                SemanticError( decl, "Cforall declaration hides C function " );
    438486                        }
    439487                }
    440488
    441489                // Skip repeat declarations of the same identifier
    442                 DeclarationWithType *existing = lookupIdAtScope( name, mangleName, scope );
    443                 if ( existing && addedIdConflicts( existing, decl ) ) return;
     490                IdData * existing = lookupIdAtScope( name, mangleName, scope );
     491                if ( existing && existing->id && addedIdConflicts( *existing, decl, deleteStmt, handleConflicts ) ) return;
    444492
    445493                // add to indexer
    446                 tables->idTable[ name ][ mangleName ] = { decl, baseExpr };
     494                tables->idTable[ name ][ mangleName ] = IdData{ decl, baseExpr, deleteStmt };
    447495                ++tables->size;
    448496        }
    449497
     498        void Indexer::addId( DeclarationWithType * decl, Expression * baseExpr ) {
     499                // default handling of conflicts is to raise an error
     500                addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, baseExpr, decl->isDeleted ? decl : nullptr );
     501        }
     502
     503        void Indexer::addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ) {
     504                // default handling of conflicts is to raise an error
     505                addId( decl, [decl](IdData &, const std::string & msg) { SemanticError( decl, msg ); return true; }, nullptr, deleteStmt );
     506        }
     507
    450508        bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {
    451                 if ( existing->get_base() == 0 ) {
     509                if ( existing->base == nullptr ) {
    452510                        return false;
    453                 } else if ( added->get_base() == 0 ) {
     511                } else if ( added->base == nullptr ) {
    454512                        return true;
    455513                } else {
    456                         throw SemanticError( "redeclaration of ", added );
    457                 }
     514                        assert( existing->base && added->base );
     515                        // typedef redeclarations are errors only if types are different
     516                        if ( ! ResolvExpr::typesCompatible( existing->base, added->base, Indexer() ) ) {
     517                                SemanticError( added->location, "redeclaration of " + added->name );
     518                        }
     519                }
     520                // does not need to be added to the table if both existing and added have a base that are the same
     521                return true;
    458522        }
    459523
     
    462526                makeWritable();
    463527
    464                 const std::string &id = decl->get_name();
     528                const std::string &id = decl->name;
    465529                TypeTable::iterator existing = tables->typeTable.find( id );
    466530                if ( existing == tables->typeTable.end() ) {
     
    478542
    479543        bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) {
    480                 if ( existing->get_members().empty() ) {
     544                if ( ! existing->body ) {
    481545                        return false;
    482                 } else if ( ! added->get_members().empty() ) {
    483                         throw SemanticError( "redeclaration of ", added );
     546                } else if ( added->body ) {
     547                        SemanticError( added, "redeclaration of " );
    484548                } // if
    485549                return true;
     
    495559                makeWritable();
    496560
    497                 const std::string &id = decl->get_name();
     561                const std::string &id = decl->name;
    498562                StructTable::iterator existing = tables->structTable.find( id );
    499563                if ( existing == tables->structTable.end() ) {
     
    514578                makeWritable();
    515579
    516                 const std::string &id = decl->get_name();
     580                const std::string &id = decl->name;
    517581                EnumTable::iterator existing = tables->enumTable.find( id );
    518582                if ( existing == tables->enumTable.end() ) {
     
    538602                makeWritable();
    539603
    540                 const std::string &id = decl->get_name();
     604                const std::string &id = decl->name;
    541605                UnionTable::iterator existing = tables->unionTable.find( id );
    542606                if ( existing == tables->unionTable.end() ) {
     
    557621                makeWritable();
    558622
    559                 const std::string &id = decl->get_name();
     623                const std::string &id = decl->name;
    560624                TraitTable::iterator existing = tables->traitTable.find( id );
    561625                if ( existing == tables->traitTable.end() ) {
     
    572636        }
    573637
    574         void Indexer::addWith( WithStmt * stmt ) {
    575                 for ( Expression * expr : stmt->exprs ) {
     638        void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction handleConflicts ) {
     639                for ( Declaration * decl : aggr->members ) {
     640                        if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
     641                                addId( dwt, handleConflicts, expr );
     642                                if ( dwt->name == "" ) {
     643                                        Type * t = dwt->get_type()->stripReferences();
     644                                        if ( dynamic_cast< StructInstType * >( t ) || dynamic_cast< UnionInstType * >( t ) ) {
     645                                                Expression * base = expr->clone();
     646                                                ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost?
     647                                                ResolvExpr::referenceToRvalueConversion( base, cost );
     648                                                addMembers( t->getAggr(), new MemberExpr( dwt, base ), handleConflicts );
     649                                        }
     650                                }
     651                        }
     652                }
     653        }
     654
     655        void Indexer::addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt ) {
     656                for ( Expression * expr : withExprs ) {
    576657                        if ( expr->result ) {
    577658                                AggregateDecl * aggr = expr->result->stripReferences()->getAggr();
    578659                                assertf( aggr, "WithStmt expr has non-aggregate type: %s", toString( expr->result ).c_str() );
    579660
    580                                 for ( Declaration * decl : aggr->members ) {
    581                                         if ( DeclarationWithType * dwt = dynamic_cast< DeclarationWithType * >( decl ) ) {
    582                                                 addId( dwt, expr );
    583                                         }
    584                                 }
     661                                addMembers( aggr, expr, [withStmt](IdData & existing, const std::string &) {
     662                                        // on conflict, delete the identifier
     663                                        existing.deleteStmt = withStmt;
     664                                        return true;
     665                                });
    585666                        }
    586667                }
     
    641722
    642723        void Indexer::print( std::ostream &os, int indent ) const {
    643             using std::cerr;
     724                using std::cerr;
    644725
    645726                if ( tables ) {
     
    666747        }
    667748
    668         Expression * Indexer::IdData::combine() const {
     749        Expression * Indexer::IdData::combine( ResolvExpr::Cost & cost ) const {
     750                Expression * ret = nullptr;
    669751                if ( baseExpr ) {
    670752                        Expression * base = baseExpr->clone();
    671                         ResolvExpr::referenceToRvalueConversion( base );
    672                         Expression * ret = new MemberExpr( id, base );
     753                        ResolvExpr::referenceToRvalueConversion( base, cost );
     754                        ret = new MemberExpr( id, base );
    673755                        // xxx - this introduces hidden environments, for now remove them.
    674756                        // std::swap( base->env, ret->env );
    675757                        delete base->env;
    676758                        base->env = nullptr;
    677                         return ret;
    678                 } else {
    679                         return new VariableExpr( id );
    680                 }
     759                } else {
     760                        ret = new VariableExpr( id );
     761                }
     762                if ( deleteStmt ) ret = new DeletedExpr( ret, deleteStmt );
     763                return ret;
    681764        }
    682765} // namespace SymTab
  • src/SymTab/Indexer.h

    rf9feab8 r90152a4  
    1919#include <list>               // for list
    2020#include <string>             // for string
     21#include <functional>         // for function
    2122
    2223#include "SynTree/Visitor.h"  // for Visitor
    2324#include "SynTree/SynTree.h"  // for AST nodes
     25
     26namespace ResolvExpr {
     27class Cost;
     28}
    2429
    2530namespace SymTab {
     
    4045
    4146                struct IdData {
    42                         DeclarationWithType * id;
    43                         Expression * baseExpr; // WithExpr
     47                        DeclarationWithType * id = nullptr;
     48                        Expression * baseExpr = nullptr; // WithExpr
    4449
    45                         Expression * combine() const;
     50                        /// non-null if this declaration is deleted
     51                        BaseSyntaxNode * deleteStmt = nullptr;
     52
     53                        // NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members.
     54                        IdData() = default;
     55                        IdData( DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt ) : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ) {}
     56
     57                        Expression * combine( ResolvExpr::Cost & cost ) const;
    4658                };
    4759
     
    5971                TraitDecl *lookupTrait( const std::string &id ) const;
    6072
     73                /// Gets the type declaration with the given ID at global scope
     74                NamedTypeDecl *globalLookupType( const std::string &id ) const;
     75                /// Gets the struct declaration with the given ID at global scope
     76                StructDecl *globalLookupStruct( const std::string &id ) const;
     77                /// Gets the union declaration with the given ID at global scope
     78                UnionDecl *globalLookupUnion( const std::string &id ) const;
     79                /// Gets the enum declaration with the given ID at global scope
     80                EnumDecl *globalLookupEnum( const std::string &id ) const;
     81
    6182                void print( std::ostream &os, int indent = 0 ) const;
    6283
    6384                /// looks up a specific mangled ID at the given scope
    64                 DeclarationWithType *lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
     85                IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope );
     86                const IdData * lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
    6587                /// returns true if there exists a declaration with C linkage and the given name with a different mangled name
    6688                bool hasIncompatibleCDecl( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
     
    7496                TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const;
    7597
    76                 void addId( DeclarationWithType *decl, Expression * baseExpr = nullptr );
     98                typedef std::function<bool(IdData &, const std::string &)> ConflictFunction;
     99
     100                void addId( DeclarationWithType * decl, Expression * baseExpr = nullptr );
     101                void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt );
     102
    77103                void addType( NamedTypeDecl *decl );
    78104                void addStruct( const std::string &id );
     
    84110
    85111                /// adds all of the IDs from WithStmt exprs
    86                 void addWith( WithStmt * );
     112                void addWith( std::list< Expression * > & withExprs, BaseSyntaxNode * withStmt );
     113
     114                /// adds all of the members of the Aggregate (addWith helper)
     115                void addMembers( AggregateDecl * aggr, Expression * expr, ConflictFunction );
    87116
    88117                /// convenience function for adding a list of Ids to the indexer
     
    114143                /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
    115144                void makeWritable();
     145
     146                /// common code for addId, addDeletedId, etc.
     147                void addId( DeclarationWithType * decl, ConflictFunction, Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr );
    116148        };
    117149} // namespace SymTab
  • src/SymTab/Mangler.cc

    rf9feab8 r90152a4  
    2323
    2424#include "CodeGen/OperatorTable.h"  // for OperatorInfo, operatorLookup
     25#include "Common/PassVisitor.h"
    2526#include "Common/SemanticError.h"   // for SemanticError
    2627#include "Common/utility.h"         // for toString
     
    3132
    3233namespace SymTab {
    33         std::string Mangler::mangleType( Type * ty ) {
    34                 Mangler mangler( false, true, true );
    35                 maybeAccept( ty, mangler );
    36                 return mangler.get_mangleName();
    37         }
    38 
    39         std::string Mangler::mangleConcrete( Type* ty ) {
    40                 Mangler mangler( false, false, false );
    41                 maybeAccept( ty, mangler );
    42                 return mangler.get_mangleName();
    43         }
    44 
    45         Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
    46                 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {}
    47 
    48         Mangler::Mangler( const Mangler &rhs ) : mangleName() {
    49                 varNums = rhs.varNums;
    50                 nextVarNum = rhs.nextVarNum;
    51                 isTopLevel = rhs.isTopLevel;
    52                 mangleOverridable = rhs.mangleOverridable;
    53                 typeMode = rhs.typeMode;
    54         }
    55 
    56         void Mangler::mangleDecl( DeclarationWithType * declaration ) {
    57                 bool wasTopLevel = isTopLevel;
    58                 if ( isTopLevel ) {
    59                         varNums.clear();
    60                         nextVarNum = 0;
    61                         isTopLevel = false;
    62                 } // if
    63                 mangleName << "__";
    64                 CodeGen::OperatorInfo opInfo;
    65                 if ( operatorLookup( declaration->get_name(), opInfo ) ) {
    66                         mangleName << opInfo.outputName;
    67                 } else {
    68                         mangleName << declaration->get_name();
    69                 } // if
    70                 mangleName << "__";
    71                 maybeAccept( declaration->get_type(), *this );
    72                 if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {
    73                         // want to be able to override autogenerated and intrinsic routines,
    74                         // so they need a different name mangling
    75                         if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
    76                                 mangleName << "autogen__";
    77                         } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
    78                                 mangleName << "intrinsic__";
    79                         } else {
    80                                 // if we add another kind of overridable function, this has to change
    81                                 assert( false && "unknown overrideable linkage" );
    82                         } // if
     34        namespace Mangler {
     35                namespace {
     36                        /// Mangles names to a unique C identifier
     37                        struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler>, public WithGuards {
     38                                Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
     39                                Mangler( const Mangler & ) = delete;
     40
     41                                void previsit( BaseSyntaxNode * ) { visit_children = false; }
     42
     43                                void postvisit( ObjectDecl * declaration );
     44                                void postvisit( FunctionDecl * declaration );
     45                                void postvisit( TypeDecl * declaration );
     46
     47                                void postvisit( VoidType * voidType );
     48                                void postvisit( BasicType * basicType );
     49                                void postvisit( PointerType * pointerType );
     50                                void postvisit( ArrayType * arrayType );
     51                                void postvisit( ReferenceType * refType );
     52                                void postvisit( FunctionType * functionType );
     53                                void postvisit( StructInstType * aggregateUseType );
     54                                void postvisit( UnionInstType * aggregateUseType );
     55                                void postvisit( EnumInstType * aggregateUseType );
     56                                void postvisit( TypeInstType * aggregateUseType );
     57                                void postvisit( TraitInstType * inst );
     58                                void postvisit( TupleType * tupleType );
     59                                void postvisit( VarArgsType * varArgsType );
     60                                void postvisit( ZeroType * zeroType );
     61                                void postvisit( OneType * oneType );
     62                                void postvisit( QualifiedType * qualType );
     63
     64                                std::string get_mangleName() { return mangleName.str(); }
     65                          private:
     66                                std::ostringstream mangleName;  ///< Mangled name being constructed
     67                                typedef std::map< std::string, std::pair< int, int > > VarMapType;
     68                                VarMapType varNums;             ///< Map of type variables to indices
     69                                int nextVarNum;                 ///< Next type variable index
     70                                bool isTopLevel;                ///< Is the Mangler at the top level
     71                                bool mangleOverridable;         ///< Specially mangle overridable built-in methods
     72                                bool typeMode;                  ///< Produce a unique mangled name for a type
     73                                bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
     74                                bool inFunctionType = false;    ///< Include type qualifiers if false.
     75                                bool inQualifiedType = false;   ///< Add start/end delimiters around qualified type
     76
     77                                void mangleDecl( DeclarationWithType *declaration );
     78                                void mangleRef( ReferenceToType *refType, std::string prefix );
     79
     80                                void printQualifiers( Type *type );
     81                        }; // Mangler
     82                } // namespace
     83
     84                std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
     85                        PassVisitor<Mangler> mangler( mangleOverridable, typeMode, mangleGenericParams );
     86                        maybeAccept( decl, mangler );
     87                        return mangler.pass.get_mangleName();
    8388                }
    84                 isTopLevel = wasTopLevel;
    85         }
    86 
    87         void Mangler::visit( ObjectDecl * declaration ) {
    88                 mangleDecl( declaration );
    89         }
    90 
    91         void Mangler::visit( FunctionDecl * declaration ) {
    92                 mangleDecl( declaration );
    93         }
    94 
    95         void Mangler::visit( VoidType * voidType ) {
    96                 printQualifiers( voidType );
    97                 mangleName << "v";
    98         }
    99 
    100         void Mangler::visit( BasicType * basicType ) {
    101                 static const char *btLetter[] = {
    102                         "b",    // Bool
    103                         "c",    // Char
    104                         "Sc",   // SignedChar
    105                         "Uc",   // UnsignedChar
    106                         "s",    // ShortSignedInt
    107                         "Us",   // ShortUnsignedInt
    108                         "i",    // SignedInt
    109                         "Ui",   // UnsignedInt
    110                         "l",    // LongSignedInt
    111                         "Ul",   // LongUnsignedInt
    112                         "q",    // LongLongSignedInt
    113                         "Uq",   // LongLongUnsignedInt
    114                         "f",    // Float
    115                         "d",    // Double
    116                         "r",    // LongDouble
    117                         "Xf",   // FloatComplex
    118                         "Xd",   // DoubleComplex
    119                         "Xr",   // LongDoubleComplex
    120                         "If",   // FloatImaginary
    121                         "Id",   // DoubleImaginary
    122                         "Ir",   // LongDoubleImaginary
    123                         "w",    // SignedInt128
    124                         "Uw",   // UnsignedInt128
    125                 };
    126 
    127                 printQualifiers( basicType );
    128                 mangleName << btLetter[ basicType->get_kind() ];
    129         }
    130 
    131         void Mangler::visit( PointerType * pointerType ) {
    132                 printQualifiers( pointerType );
    133                 mangleName << "P";
    134                 maybeAccept( pointerType->get_base(), *this );
    135         }
    136 
    137         void Mangler::visit( ArrayType * arrayType ) {
    138                 // TODO: encode dimension
    139                 printQualifiers( arrayType );
    140                 mangleName << "A0";
    141                 maybeAccept( arrayType->get_base(), *this );
    142         }
    143 
    144         void Mangler::visit( ReferenceType * refType ) {
    145                 printQualifiers( refType );
    146                 mangleName << "R";
    147                 maybeAccept( refType->get_base(), *this );
    148         }
    149 
    150         namespace {
    151                 inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {
    152                         std::list< Type* > ret;
    153                         std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
    154                                                         std::mem_fun( &DeclarationWithType::get_type ) );
    155                         return ret;
     89
     90                std::string mangleType( Type * ty ) {
     91                        PassVisitor<Mangler> mangler( false, true, true );
     92                        maybeAccept( ty, mangler );
     93                        return mangler.pass.get_mangleName();
    15694                }
    157         }
    158 
    159         void Mangler::visit( FunctionType * functionType ) {
    160                 printQualifiers( functionType );
    161                 mangleName << "F";
    162                 std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() );
    163                 acceptAll( returnTypes, *this );
    164                 mangleName << "_";
    165                 std::list< Type* > paramTypes = getTypes( functionType->get_parameters() );
    166                 acceptAll( paramTypes, *this );
    167                 mangleName << "_";
    168         }
    169 
    170         void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
    171                 printQualifiers( refType );
    172 
    173                 mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name();
    174 
    175                 if ( mangleGenericParams ) {
    176                         std::list< Expression* >& params = refType->get_parameters();
    177                         if ( ! params.empty() ) {
     95
     96                std::string mangleConcrete( Type * ty ) {
     97                        PassVisitor<Mangler> mangler( false, false, false );
     98                        maybeAccept( ty, mangler );
     99                        return mangler.pass.get_mangleName();
     100                }
     101
     102                namespace {
     103                        Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams )
     104                                : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {}
     105
     106                        void Mangler::mangleDecl( DeclarationWithType * declaration ) {
     107                                bool wasTopLevel = isTopLevel;
     108                                if ( isTopLevel ) {
     109                                        varNums.clear();
     110                                        nextVarNum = 0;
     111                                        isTopLevel = false;
     112                                } // if
     113                                mangleName << Encoding::manglePrefix;
     114                                CodeGen::OperatorInfo opInfo;
     115                                if ( operatorLookup( declaration->get_name(), opInfo ) ) {
     116                                        mangleName << opInfo.outputName.size() << opInfo.outputName;
     117                                } else {
     118                                        mangleName << declaration->name.size() << declaration->name;
     119                                } // if
     120                                maybeAccept( declaration->get_type(), *visitor );
     121                                if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {
     122                                        // want to be able to override autogenerated and intrinsic routines,
     123                                        // so they need a different name mangling
     124                                        if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {
     125                                                mangleName << Encoding::autogen;
     126                                        } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {
     127                                                mangleName << Encoding::intrinsic;
     128                                        } else {
     129                                                // if we add another kind of overridable function, this has to change
     130                                                assert( false && "unknown overrideable linkage" );
     131                                        } // if
     132                                }
     133                                isTopLevel = wasTopLevel;
     134                        }
     135
     136                        void Mangler::postvisit( ObjectDecl * declaration ) {
     137                                mangleDecl( declaration );
     138                        }
     139
     140                        void Mangler::postvisit( FunctionDecl * declaration ) {
     141                                mangleDecl( declaration );
     142                        }
     143
     144                        void Mangler::postvisit( VoidType * voidType ) {
     145                                printQualifiers( voidType );
     146                                mangleName << Encoding::void_t;
     147                        }
     148
     149                        void Mangler::postvisit( BasicType * basicType ) {
     150                                printQualifiers( basicType );
     151                                assertf( basicType->get_kind() < BasicType::NUMBER_OF_BASIC_TYPES, "Unhandled basic type: %d", basicType->get_kind() );
     152                                mangleName << Encoding::basicTypes[ basicType->get_kind() ];
     153                        }
     154
     155                        void Mangler::postvisit( PointerType * pointerType ) {
     156                                printQualifiers( pointerType );
     157                                // mangle void (*f)() and void f() to the same name to prevent overloading on functions and function pointers
     158                                if ( ! dynamic_cast<FunctionType *>( pointerType->base ) ) mangleName << Encoding::pointer;
     159                                maybeAccept( pointerType->base, *visitor );
     160                        }
     161
     162                        void Mangler::postvisit( ArrayType * arrayType ) {
     163                                // TODO: encode dimension
     164                                printQualifiers( arrayType );
     165                                mangleName << Encoding::array << "0";
     166                                maybeAccept( arrayType->base, *visitor );
     167                        }
     168
     169                        void Mangler::postvisit( ReferenceType * refType ) {
     170                                // don't print prefix (e.g. 'R') for reference types so that references and non-references do not overload.
     171                                // Further, do not print the qualifiers for a reference type (but do run printQualifers because of TypeDecls, etc.),
     172                                // by pretending every reference type is a function parameter.
     173                                GuardValue( inFunctionType );
     174                                inFunctionType = true;
     175                                printQualifiers( refType );
     176                                maybeAccept( refType->base, *visitor );
     177                        }
     178
     179                        namespace {
     180                                inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) {
     181                                        std::list< Type* > ret;
     182                                        std::transform( decls.begin(), decls.end(), std::back_inserter( ret ),
     183                                                                        std::mem_fun( &DeclarationWithType::get_type ) );
     184                                        return ret;
     185                                }
     186                        }
     187
     188                        void Mangler::postvisit( FunctionType * functionType ) {
     189                                printQualifiers( functionType );
     190                                mangleName << Encoding::function;
     191                                // turn on inFunctionType so that printQualifiers does not print most qualifiers for function parameters,
     192                                // since qualifiers on outermost parameter type do not differentiate function types, e.g.,
     193                                // void (*)(const int) and void (*)(int) are the same type, but void (*)(const int *) and void (*)(int *) are different
     194                                GuardValue( inFunctionType );
     195                                inFunctionType = true;
     196                                std::list< Type* > returnTypes = getTypes( functionType->returnVals );
     197                                if (returnTypes.empty()) mangleName << Encoding::void_t;
     198                                else acceptAll( returnTypes, *visitor );
    178199                                mangleName << "_";
    179                                 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
    180                                         TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    181                                         assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str());
    182                                         maybeAccept( paramType->get_type(), *this );
    183                                 }
     200                                std::list< Type* > paramTypes = getTypes( functionType->parameters );
     201                                acceptAll( paramTypes, *visitor );
    184202                                mangleName << "_";
    185203                        }
    186                 }
    187         }
    188 
    189         void Mangler::visit( StructInstType * aggregateUseType ) {
    190                 mangleRef( aggregateUseType, "s" );
    191         }
    192 
    193         void Mangler::visit( UnionInstType * aggregateUseType ) {
    194                 mangleRef( aggregateUseType, "u" );
    195         }
    196 
    197         void Mangler::visit( EnumInstType * aggregateUseType ) {
    198                 mangleRef( aggregateUseType, "e" );
    199         }
    200 
    201         void Mangler::visit( TypeInstType * typeInst ) {
    202                 VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
    203                 if ( varNum == varNums.end() ) {
    204                         mangleRef( typeInst, "t" );
    205                 } else {
    206                         printQualifiers( typeInst );
    207                         std::ostringstream numStream;
    208                         numStream << varNum->second.first;
    209                         switch ( (TypeDecl::Kind )varNum->second.second ) {
    210                           case TypeDecl::Dtype:
    211                                 mangleName << "d";
    212                                 break;
    213                           case TypeDecl::Ftype:
    214                                 mangleName << "f";
    215                                 break;
    216                                 case TypeDecl::Ttype:
    217                                 mangleName << "tVARGS";
    218                                 break;
    219                                 default:
    220                                 assert( false );
    221                         } // switch
    222                         mangleName << numStream.str();
    223                 } // if
    224         }
    225 
    226         void Mangler::visit( TupleType * tupleType ) {
    227                 printQualifiers( tupleType );
    228                 mangleName << "T";
    229                 acceptAll( tupleType->types, *this );
    230                 mangleName << "_";
    231         }
    232 
    233         void Mangler::visit( VarArgsType * varArgsType ) {
    234                 printQualifiers( varArgsType );
    235                 mangleName << "VARGS";
    236         }
    237 
    238         void Mangler::visit( ZeroType * ) {
    239                 mangleName << "Z";
    240         }
    241 
    242         void Mangler::visit( OneType * ) {
    243                 mangleName << "O";
    244         }
    245 
    246         void Mangler::visit( TypeDecl * decl ) {
    247                 static const char *typePrefix[] = { "BT", "BD", "BF" };
    248                 mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name;
    249         }
    250 
    251         void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
    252                 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
    253                         os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
    254                 } // for
    255         }
    256 
    257         void Mangler::printQualifiers( Type * type ) {
    258                 // skip if not including qualifiers
    259                 if ( typeMode ) return;
    260 
    261                 if ( ! type->get_forall().empty() ) {
    262                         std::list< std::string > assertionNames;
    263                         int tcount = 0, dcount = 0, fcount = 0, vcount = 0;
    264                         mangleName << "A";
    265                         for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
    266                                 switch ( (*i)->get_kind() ) {
    267                                   case TypeDecl::Dtype:
    268                                         dcount++;
    269                                         break;
    270                                   case TypeDecl::Ftype:
    271                                         fcount++;
    272                                         break;
    273                                   case TypeDecl::Ttype:
    274                                         vcount++;
    275                                         break;
    276                                   default:
    277                                         assert( false );
    278                                 } // switch
    279                                 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
    280                                 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) {
    281                                         Mangler sub_mangler( mangleOverridable, typeMode, mangleGenericParams );
    282                                         sub_mangler.nextVarNum = nextVarNum;
    283                                         sub_mangler.isTopLevel = false;
    284                                         sub_mangler.varNums = varNums;
    285                                         (*assert)->accept( sub_mangler );
    286                                         assertionNames.push_back( sub_mangler.mangleName.str() );
     204
     205                        void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {
     206                                printQualifiers( refType );
     207
     208                                mangleName << prefix << refType->name.length() << refType->name;
     209
     210                                if ( mangleGenericParams ) {
     211                                        std::list< Expression* >& params = refType->parameters;
     212                                        if ( ! params.empty() ) {
     213                                                mangleName << "_";
     214                                                for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) {
     215                                                        TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     216                                                        assertf(paramType, "Aggregate parameters should be type expressions: %s", toCString(*param));
     217                                                        maybeAccept( paramType->type, *visitor );
     218                                                }
     219                                                mangleName << "_";
     220                                        }
     221                                }
     222                        }
     223
     224                        void Mangler::postvisit( StructInstType * aggregateUseType ) {
     225                                mangleRef( aggregateUseType, Encoding::struct_t );
     226                        }
     227
     228                        void Mangler::postvisit( UnionInstType * aggregateUseType ) {
     229                                mangleRef( aggregateUseType, Encoding::union_t );
     230                        }
     231
     232                        void Mangler::postvisit( EnumInstType * aggregateUseType ) {
     233                                mangleRef( aggregateUseType, Encoding::enum_t );
     234                        }
     235
     236                        void Mangler::postvisit( TypeInstType * typeInst ) {
     237                                VarMapType::iterator varNum = varNums.find( typeInst->get_name() );
     238                                if ( varNum == varNums.end() ) {
     239                                        mangleRef( typeInst, Encoding::type );
     240                                } else {
     241                                        printQualifiers( typeInst );
     242                                        // Note: Can't use name here, since type variable names do not actually disambiguate a function, e.g.
     243                                        //   forall(dtype T) void f(T);
     244                                        //   forall(dtype S) void f(S);
     245                                        // are equivalent and should mangle the same way. This is accomplished by numbering the type variables when they
     246                                        // are first found and prefixing with the appropriate encoding for the type class.
     247                                        assertf( varNum->second.second < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", varNum->second.second );
     248                                        mangleName << Encoding::typeVariables[varNum->second.second] << varNum->second.first;
     249                                } // if
     250                        }
     251
     252                        void Mangler::postvisit( TraitInstType * inst ) {
     253                                printQualifiers( inst );
     254                                mangleName << inst->name.size() << inst->name;
     255                        }
     256
     257                        void Mangler::postvisit( TupleType * tupleType ) {
     258                                printQualifiers( tupleType );
     259                                mangleName << Encoding::tuple << tupleType->types.size();
     260                                acceptAll( tupleType->types, *visitor );
     261                        }
     262
     263                        void Mangler::postvisit( VarArgsType * varArgsType ) {
     264                                printQualifiers( varArgsType );
     265                                static const std::string vargs = "__builtin_va_list";
     266                                mangleName << Encoding::type << vargs.size() << vargs;
     267                        }
     268
     269                        void Mangler::postvisit( ZeroType * ) {
     270                                mangleName << Encoding::zero;
     271                        }
     272
     273                        void Mangler::postvisit( OneType * ) {
     274                                mangleName << Encoding::one;
     275                        }
     276
     277                        void Mangler::postvisit( QualifiedType * qualType ) {
     278                                bool inqual = inQualifiedType;
     279                                if (! inqual ) {
     280                                        // N marks the start of a qualified type
     281                                        inQualifiedType = true;
     282                                        mangleName << Encoding::qualifiedTypeStart;
     283                                }
     284                                maybeAccept( qualType->parent, *visitor );
     285                                maybeAccept( qualType->child, *visitor );
     286                                if ( ! inqual ) {
     287                                        // E marks the end of a qualified type
     288                                        inQualifiedType = false;
     289                                        mangleName << Encoding::qualifiedTypeEnd;
     290                                }
     291                        }
     292
     293                        void Mangler::postvisit( TypeDecl * decl ) {
     294                                // TODO: is there any case where mangling a TypeDecl makes sense? If so, this code needs to be
     295                                // fixed to ensure that two TypeDecls mangle to the same name when they are the same type and vice versa.
     296                                // Note: The current scheme may already work correctly for this case, I have not thought about this deeply
     297                                // and the case has not yet come up in practice. Alternatively, if not then this code can be removed
     298                                // aside from the assert false.
     299                                assertf(false, "Mangler should not visit typedecl: %s", toCString(decl));
     300                                assertf( decl->get_kind() < TypeDecl::NUMBER_OF_KINDS, "Unhandled type variable kind: %d", decl->get_kind() );
     301                                mangleName << Encoding::typeVariables[ decl->get_kind() ] << ( decl->name.length() ) << decl->name;
     302                        }
     303
     304                        __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) {
     305                                for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) {
     306                                        os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl;
    287307                                } // for
    288                         } // for
    289                         mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_";
    290                         std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
    291                         mangleName << "_";
    292                 } // if
    293                 if ( type->get_const() ) {
    294                         mangleName << "C";
    295                 } // if
    296                 if ( type->get_volatile() ) {
    297                         mangleName << "V";
    298                 } // if
    299                 if ( type->get_mutex() ) {
    300                         mangleName << "M";
    301                 } // if
    302                 // Removed due to restrict not affecting function compatibility in GCC
    303 //              if ( type->get_isRestrict() ) {
    304 //                      mangleName << "E";
    305 //              } // if
    306                 if ( type->get_lvalue() ) {
    307                         // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
    308                         mangleName << "L";
    309                 }
    310                 if ( type->get_atomic() ) {
    311                         mangleName << "A";
    312                 } // if
    313         }
     308                        }
     309
     310                        void Mangler::printQualifiers( Type * type ) {
     311                                // skip if not including qualifiers
     312                                if ( typeMode ) return;
     313                                if ( ! type->get_forall().empty() ) {
     314                                        std::list< std::string > assertionNames;
     315                                        int dcount = 0, fcount = 0, vcount = 0, acount = 0;
     316                                        mangleName << Encoding::forall;
     317                                        for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) {
     318                                                switch ( (*i)->get_kind() ) {
     319                                                  case TypeDecl::Dtype:
     320                                                        dcount++;
     321                                                        break;
     322                                                  case TypeDecl::Ftype:
     323                                                        fcount++;
     324                                                        break;
     325                                                  case TypeDecl::Ttype:
     326                                                        vcount++;
     327                                                        break;
     328                                                  default:
     329                                                        assert( false );
     330                                                } // switch
     331                                                varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() );
     332                                                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;
     337                                                        (*assert)->accept( sub_mangler );
     338                                                        assertionNames.push_back( sub_mangler.pass.mangleName.str() );
     339                                                        acount++;
     340                                                } // for
     341                                        } // for
     342                                        mangleName << dcount << "_" << fcount << "_" << vcount << "_" << acount << "_";
     343                                        std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) );
     344                                        mangleName << "_";
     345                                } // if
     346                                if ( ! inFunctionType ) {
     347                                        // these qualifiers do not distinguish the outermost type of a function parameter
     348                                        if ( type->get_const() ) {
     349                                                mangleName << Encoding::qualifiers.at(Type::Const);
     350                                        } // if
     351                                        if ( type->get_volatile() ) {
     352                                                mangleName << Encoding::qualifiers.at(Type::Volatile);
     353                                        } // if
     354                                        // Removed due to restrict not affecting function compatibility in GCC
     355                                        // if ( type->get_isRestrict() ) {
     356                                        //      mangleName << "E";
     357                                        // } // if
     358                                        if ( type->get_atomic() ) {
     359                                                mangleName << Encoding::qualifiers.at(Type::Atomic);
     360                                        } // if
     361                                }
     362                                if ( type->get_mutex() ) {
     363                                        mangleName << Encoding::qualifiers.at(Type::Mutex);
     364                                } // if
     365                                if ( type->get_lvalue() ) {
     366                                        // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues
     367                                        mangleName << Encoding::qualifiers.at(Type::Lvalue);
     368                                }
     369
     370                                if ( inFunctionType ) {
     371                                        // turn off inFunctionType so that types can be differentiated for nested qualifiers
     372                                        GuardValue( inFunctionType );
     373                                        inFunctionType = false;
     374                                }
     375                        }
     376                }       // namespace
     377        } // namespace Mangler
    314378} // namespace SymTab
    315379
  • src/SymTab/Mangler.h

    rf9feab8 r90152a4  
    2424#include "SynTree/Visitor.h"  // for Visitor, maybeAccept
    2525
     26// https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling
     27// The CFA name mangling scheme is based closely on the itanium C++ name mangling scheme, with the following key differences:
     28// * Variable names are also mangled to include type information, not just functions
     29// * CFA does not have template expansion, so the rules for function specialization do not apply.
     30// * CFA instead has to handle type parameters and assertion parameters.
     31// * Currently name compression is not implemented.
     32
    2633namespace SymTab {
    27         /// Mangles names to a unique C identifier
    28         class Mangler : public Visitor {
    29           public:
     34        namespace Mangler {
    3035                /// Mangle syntax tree object; primary interface to clients
    31                 template< typename SynTreeClass >
    32             static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );
     36                std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true );
     37
    3338                /// Mangle a type name; secondary interface
    34                 static std::string mangleType( Type* ty );
     39                std::string mangleType( Type* ty );
    3540                /// Mangle ignoring generic type parameters
    36                 static std::string mangleConcrete( Type* ty );
     41                std::string mangleConcrete( Type* ty );
    3742
     43                namespace Encoding {
     44                        extern const std::string manglePrefix;
     45                        extern const std::string basicTypes[];
     46                        extern const std::map<int, std::string> qualifiers;
    3847
    39                 virtual void visit( ObjectDecl *declaration );
    40                 virtual void visit( FunctionDecl *declaration );
    41                 virtual void visit( TypeDecl *declaration );
     48                        extern const std::string void_t;
     49                        extern const std::string zero;
     50                        extern const std::string one;
    4251
    43                 virtual void visit( VoidType *voidType );
    44                 virtual void visit( BasicType *basicType );
    45                 virtual void visit( PointerType *pointerType );
    46                 virtual void visit( ArrayType *arrayType );
    47                 virtual void visit( ReferenceType *refType );
    48                 virtual void visit( FunctionType *functionType );
    49                 virtual void visit( StructInstType *aggregateUseType );
    50                 virtual void visit( UnionInstType *aggregateUseType );
    51                 virtual void visit( EnumInstType *aggregateUseType );
    52                 virtual void visit( TypeInstType *aggregateUseType );
    53                 virtual void visit( TupleType *tupleType );
    54                 virtual void visit( VarArgsType *varArgsType );
    55                 virtual void visit( ZeroType *zeroType );
    56                 virtual void visit( OneType *oneType );
     52                        extern const std::string function;
     53                        extern const std::string tuple;
     54                        extern const std::string pointer;
     55                        extern const std::string array;
     56                        extern const std::string qualifiedTypeStart;
     57                        extern const std::string qualifiedTypeEnd;
    5758
    58                 std::string get_mangleName() { return mangleName.str(); }
    59           private:
    60                 std::ostringstream mangleName;  ///< Mangled name being constructed
    61                 typedef std::map< std::string, std::pair< int, int > > VarMapType;
    62                 VarMapType varNums;             ///< Map of type variables to indices
    63                 int nextVarNum;                 ///< Next type variable index
    64                 bool isTopLevel;                ///< Is the Mangler at the top level
    65                 bool mangleOverridable;         ///< Specially mangle overridable built-in methods
    66                 bool typeMode;                  ///< Produce a unique mangled name for a type
    67                 bool mangleGenericParams;       ///< Include generic parameters in name mangling if true
     59                        extern const std::string forall;
     60                        extern const std::string typeVariables[];
    6861
    69                 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams );
    70                 Mangler( const Mangler & );
     62                        extern const std::string struct_t;
     63                        extern const std::string union_t;
     64                        extern const std::string enum_t;
     65                        extern const std::string type;
    7166
    72                 void mangleDecl( DeclarationWithType *declaration );
    73                 void mangleRef( ReferenceToType *refType, std::string prefix );
     67                        extern const std::string autogen;
     68                        extern const std::string intrinsic;
     69                };
     70        } // Mangler
     71} // SymTab
    7472
    75                 void printQualifiers( Type *type );
    76         }; // Mangler
    77 
    78         template< typename SynTreeClass >
    79         std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) {
    80                 Mangler mangler( mangleOverridable, typeMode, mangleGenericParams );
    81                 maybeAccept( decl, mangler );
    82                 return mangler.get_mangleName();
    83         }
    84 } // SymTab
     73extern "C" {
     74        char * cforall_demangle(const char *, int);
     75}
    8576
    8677// Local Variables: //
  • src/SymTab/Validate.cc

    rf9feab8 r90152a4  
    4848#include "CodeGen/CodeGenerator.h"     // for genName
    4949#include "CodeGen/OperatorTable.h"     // for isCtorDtor, isCtorDtorAssign
     50#include "ControlStruct/Mutate.h"      // for ForExprMutator
    5051#include "Common/PassVisitor.h"        // for PassVisitor, WithDeclsToAdd
    5152#include "Common/ScopedMap.h"          // for ScopedMap
     
    6061#include "Parser/LinkageSpec.h"        // for C
    6162#include "ResolvExpr/typeops.h"        // for typesCompatible
    62 #include "SymTab/AddVisit.h"           // for addVisit
     63#include "ResolvExpr/Resolver.h"       // for findSingleExpression
     64#include "ResolvExpr/ResolveTypeof.h"  // for resolveTypeof
    6365#include "SymTab/Autogen.h"            // for SizeType
    6466#include "SynTree/Attribute.h"         // for noAttributes, Attribute
     
    7274#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution
    7375#include "SynTree/Visitor.h"           // for Visitor
     76#include "Validate/HandleAttributes.h" // for handleAttributes
    7477
    7578class CompoundStmt;
     
    7780class SwitchStmt;
    7881
    79 
    80 #define debugPrint( x ) if ( doDebug ) { std::cout << x; }
     82#define debugPrint( x ) if ( doDebug ) x
    8183
    8284namespace SymTab {
     85        /// hoists declarations that are difficult to hoist while parsing
     86        struct HoistTypeDecls final : public WithDeclsToAdd {
     87                void previsit( SizeofExpr * );
     88                void previsit( AlignofExpr * );
     89                void previsit( UntypedOffsetofExpr * );
     90                void previsit( CompoundLiteralExpr * );
     91                void handleType( Type * );
     92        };
     93
     94        struct FixQualifiedTypes final : public WithIndexer {
     95                Type * postmutate( QualifiedType * );
     96        };
     97
    8398        struct HoistStruct final : public WithDeclsToAdd, public WithGuards {
    8499                /// Flattens nested struct types
    85100                static void hoistStruct( std::list< Declaration * > &translationUnit );
    86101
    87                 void previsit( EnumInstType * enumInstType );
    88                 void previsit( StructInstType * structInstType );
    89                 void previsit( UnionInstType * unionInstType );
    90102                void previsit( StructDecl * aggregateDecl );
    91103                void previsit( UnionDecl * aggregateDecl );
     104                void previsit( StaticAssertDecl * assertDecl );
     105                void previsit( StructInstType * type );
     106                void previsit( UnionInstType * type );
     107                void previsit( EnumInstType * type );
    92108
    93109          private:
    94110                template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
    95111
    96                 bool inStruct = false;
     112                AggregateDecl * parentAggr = nullptr;
    97113        };
    98114
     
    112128
    113129        /// Associates forward declarations of aggregates with their definitions
    114         struct LinkReferenceToTypes final : public WithIndexer, public WithGuards {
     130        struct LinkReferenceToTypes final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes>, public WithShortCircuiting {
    115131                LinkReferenceToTypes( const Indexer *indexer );
    116132                void postvisit( TypeInstType *typeInst );
     
    120136                void postvisit( UnionInstType *unionInst );
    121137                void postvisit( TraitInstType *traitInst );
     138                void previsit( QualifiedType * qualType );
     139                void postvisit( QualifiedType * qualType );
    122140
    123141                void postvisit( EnumDecl *enumDecl );
     
    148166                void previsit( ObjectDecl * object );
    149167                void previsit( FunctionDecl * func );
     168                void previsit( FunctionType * ftype );
    150169                void previsit( StructDecl * aggrDecl );
    151170                void previsit( UnionDecl * aggrDecl );
     
    164183        };
    165184
    166         struct EliminateTypedef final : public WithVisitorRef<EliminateTypedef>, public WithGuards {
    167                 EliminateTypedef() : scopeLevel( 0 ) {}
     185        struct ReplaceTypedef final : public WithVisitorRef<ReplaceTypedef>, public WithGuards, public WithShortCircuiting, public WithDeclsToAdd {
     186                ReplaceTypedef() : scopeLevel( 0 ) {}
    168187                /// Replaces typedefs by forward declarations
    169                 static void eliminateTypedef( std::list< Declaration * > &translationUnit );
    170 
     188                static void replaceTypedef( std::list< Declaration * > &translationUnit );
     189
     190                void premutate( QualifiedType * );
     191                Type * postmutate( QualifiedType * qualType );
    171192                Type * postmutate( TypeInstType * aggregateUseType );
    172193                Declaration * postmutate( TypedefDecl * typeDecl );
     
    179200
    180201                void premutate( CompoundStmt * compoundStmt );
    181                 CompoundStmt * postmutate( CompoundStmt * compoundStmt );
    182202
    183203                void premutate( StructDecl * structDecl );
    184                 Declaration * postmutate( StructDecl * structDecl );
    185204                void premutate( UnionDecl * unionDecl );
    186                 Declaration * postmutate( UnionDecl * unionDecl );
    187205                void premutate( EnumDecl * enumDecl );
    188                 Declaration * postmutate( EnumDecl * enumDecl );
    189                 Declaration * postmutate( TraitDecl * contextDecl );
     206                void premutate( TraitDecl * );
    190207
    191208                void premutate( FunctionType * ftype );
     
    193210          private:
    194211                template<typename AggDecl>
    195                 AggDecl *handleAggregate( AggDecl * aggDecl );
    196 
    197                 template<typename AggDecl>
    198212                void addImplicitTypedef( AggDecl * aggDecl );
     213                template< typename AggDecl >
     214                void handleAggregate( AggDecl * aggr );
    199215
    200216                typedef std::unique_ptr<TypedefDecl> TypedefDeclPtr;
    201217                typedef ScopedMap< std::string, std::pair< TypedefDeclPtr, int > > TypedefMap;
    202                 typedef std::map< std::string, TypeDecl * > TypeDeclMap;
     218                typedef ScopedMap< std::string, TypeDecl * > TypeDeclMap;
    203219                TypedefMap typedefNames;
    204220                TypeDeclMap typedeclNames;
    205221                int scopeLevel;
    206222                bool inFunctionType = false;
     223        };
     224
     225        struct EliminateTypedef {
     226                /// removes TypedefDecls from the AST
     227                static void eliminateTypedef( std::list< Declaration * > &translationUnit );
     228
     229                template<typename AggDecl>
     230                void handleAggregate( AggDecl *aggregateDecl );
     231
     232                void previsit( StructDecl * aggregateDecl );
     233                void previsit( UnionDecl * aggregateDecl );
     234                void previsit( CompoundStmt * compoundStmt );
    207235        };
    208236
     
    222250        };
    223251
    224         struct ArrayLength {
     252        struct FixObjectType : public WithIndexer {
     253                /// resolves typeof type in object, function, and type declarations
     254                static void fix( std::list< Declaration * > & translationUnit );
     255
     256                void previsit( ObjectDecl * );
     257                void previsit( FunctionDecl * );
     258                void previsit( TypeDecl * );
     259        };
     260
     261        struct ArrayLength : public WithIndexer {
    225262                /// for array types without an explicit length, compute the length and store it so that it
    226263                /// is known to the rest of the phases. For example,
     
    233270
    234271                void previsit( ObjectDecl * objDecl );
     272                void previsit( ArrayType * arrayType );
    235273        };
    236274
     
    262300                PassVisitor<FindSpecialDeclarations> finder;
    263301                PassVisitor<LabelAddressFixer> labelAddrFixer;
    264 
    265                 EliminateTypedef::eliminateTypedef( translationUnit );
    266                 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
     302                PassVisitor<HoistTypeDecls> hoistDecls;
     303                PassVisitor<FixQualifiedTypes> fixQual;
     304
     305                acceptAll( translationUnit, hoistDecls );
     306                ReplaceTypedef::replaceTypedef( translationUnit );
    267307                ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
    268308                acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes because it is an indexer and needs correct types for mangling
    269309                acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
     310                mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes, because aggregate members are accessed
     311                HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
     312                EliminateTypedef::eliminateTypedef( translationUnit ); //
    270313                acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes
    271314                VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
     
    274317                Concurrency::applyKeywords( translationUnit );
    275318                acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
     319                ControlStruct::hoistControlDecls( translationUnit );  // hoist initialization out of for statements; must happen before autogenerateRoutines
    276320                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
    277321                Concurrency::implementMutexFuncs( translationUnit );
    278322                Concurrency::implementThreadStarter( translationUnit );
    279323                mutateAll( translationUnit, compoundliteral );
     324                ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
     325                FixObjectType::fix( translationUnit );
    280326                ArrayLength::computeLength( translationUnit );
    281327                acceptAll( translationUnit, finder ); // xxx - remove this pass soon
    282328                mutateAll( translationUnit, labelAddrFixer );
     329                Validate::handleAttributes( translationUnit );
    283330        }
    284331
     
    292339        }
    293340
     341
     342        void HoistTypeDecls::handleType( Type * type ) {
     343                // some type declarations are buried in expressions and not easy to hoist during parsing; hoist them here
     344                AggregateDecl * aggr = nullptr;
     345                if ( StructInstType * inst = dynamic_cast< StructInstType * >( type ) ) {
     346                        aggr = inst->baseStruct;
     347                } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( type ) ) {
     348                        aggr = inst->baseUnion;
     349                } else if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( type ) ) {
     350                        aggr = inst->baseEnum;
     351                }
     352                if ( aggr && aggr->body ) {
     353                        declsToAddBefore.push_front( aggr );
     354                }
     355        }
     356
     357        void HoistTypeDecls::previsit( SizeofExpr * expr ) {
     358                handleType( expr->type );
     359        }
     360
     361        void HoistTypeDecls::previsit( AlignofExpr * expr ) {
     362                handleType( expr->type );
     363        }
     364
     365        void HoistTypeDecls::previsit( UntypedOffsetofExpr * expr ) {
     366                handleType( expr->type );
     367        }
     368
     369        void HoistTypeDecls::previsit( CompoundLiteralExpr * expr ) {
     370                handleType( expr->result );
     371        }
     372
     373
     374        Type * FixQualifiedTypes::postmutate( QualifiedType * qualType ) {
     375                Type * parent = qualType->parent;
     376                Type * child = qualType->child;
     377                if ( dynamic_cast< GlobalScopeType * >( qualType->parent ) ) {
     378                        // .T => lookup T at global scope
     379                        if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) {
     380                                auto td = indexer.globalLookupType( inst->name );
     381                                if ( ! td ) {
     382                                        SemanticError( qualType->location, toString("Use of undefined global type ", inst->name) );
     383                                }
     384                                auto base = td->base;
     385                                assert( base );
     386                                Type * ret = base->clone();
     387                                ret->get_qualifiers() = qualType->get_qualifiers();
     388                                return ret;
     389                        } else {
     390                                // .T => T is not a type name
     391                                assertf( false, "unhandled global qualified child type: %s", toCString(child) );
     392                        }
     393                } else {
     394                        // S.T => S must be an aggregate type, find the declaration for T in S.
     395                        AggregateDecl * aggr = nullptr;
     396                        if ( StructInstType * inst = dynamic_cast< StructInstType * >( parent ) ) {
     397                                aggr = inst->baseStruct;
     398                        } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * > ( parent ) ) {
     399                                aggr = inst->baseUnion;
     400                        } else {
     401                                SemanticError( qualType->location, toString("Qualified type requires an aggregate on the left, but has: ", parent) );
     402                        }
     403                        assert( aggr ); // TODO: need to handle forward declarations
     404                        for ( Declaration * member : aggr->members ) {
     405                                if ( StructInstType * inst = dynamic_cast< StructInstType * >( child ) ) {
     406                                        if ( StructDecl * aggr = dynamic_cast< StructDecl * >( member ) ) {
     407                                                if ( aggr->name == inst->name ) {
     408                                                        // TODO: is this case, and other non-TypeInstType cases, necessary?
     409                                                        return new StructInstType( qualType->get_qualifiers(), aggr );
     410                                                }
     411                                        }
     412                                } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( child ) ) {
     413                                        if ( UnionDecl * aggr = dynamic_cast< UnionDecl * > ( member ) ) {
     414                                                if ( aggr->name == inst->name ) {
     415                                                        return new UnionInstType( qualType->get_qualifiers(), aggr );
     416                                                }
     417                                        }
     418                                } else if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( child ) ) {
     419                                        if ( EnumDecl * aggr = dynamic_cast< EnumDecl * > ( member ) ) {
     420                                                if ( aggr->name == inst->name ) {
     421                                                        return new EnumInstType( qualType->get_qualifiers(), aggr );
     422                                                }
     423                                        }
     424                                } else if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) {
     425                                        // name on the right is a typedef
     426                                        if ( NamedTypeDecl * aggr = dynamic_cast< NamedTypeDecl * > ( member ) ) {
     427                                                if ( aggr->name == inst->name ) {
     428                                                        assert( aggr->base );
     429                                                        Type * ret = aggr->base->clone();
     430                                                        ret->get_qualifiers() = qualType->get_qualifiers();
     431                                                        return ret;
     432                                                }
     433                                        }
     434                                } else {
     435                                        // S.T - S is not an aggregate => error
     436                                        assertf( false, "unhandled qualified child type: %s", toCString(qualType) );
     437                                }
     438                        }
     439                        // failed to find a satisfying definition of type
     440                        SemanticError( qualType->location, toString("Undefined type in qualified type: ", qualType) );
     441                }
     442
     443                // ... may want to link canonical SUE definition to each forward decl so that it becomes easier to lookup?
     444        }
     445
     446
    294447        void HoistStruct::hoistStruct( std::list< Declaration * > &translationUnit ) {
    295448                PassVisitor<HoistStruct> hoister;
     
    297450        }
    298451
    299         bool isStructOrUnion( Declaration *decl ) {
    300                 return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl );
     452        bool shouldHoist( Declaration *decl ) {
     453                return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl );
     454        }
     455
     456        namespace {
     457                void qualifiedName( AggregateDecl * aggr, std::ostringstream & ss ) {
     458                        if ( aggr->parent ) qualifiedName( aggr->parent, ss );
     459                        ss << "__" << aggr->name;
     460                }
     461
     462                // mangle nested type names using entire parent chain
     463                std::string qualifiedName( AggregateDecl * aggr ) {
     464                        std::ostringstream ss;
     465                        qualifiedName( aggr, ss );
     466                        return ss.str();
     467                }
    301468        }
    302469
    303470        template< typename AggDecl >
    304471        void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
    305                 if ( inStruct ) {
     472                if ( parentAggr ) {
     473                        aggregateDecl->parent = parentAggr;
     474                        aggregateDecl->name = qualifiedName( aggregateDecl );
    306475                        // Add elements in stack order corresponding to nesting structure.
    307476                        declsToAddBefore.push_front( aggregateDecl );
    308477                } else {
    309                         GuardValue( inStruct );
    310                         inStruct = true;
     478                        GuardValue( parentAggr );
     479                        parentAggr = aggregateDecl;
    311480                } // if
    312481                // Always remove the hoisted aggregate from the inner structure.
    313                 GuardAction( [aggregateDecl]() { filter( aggregateDecl->members, isStructOrUnion, false ); } );
    314         }
    315 
    316         void HoistStruct::previsit( EnumInstType * inst ) {
    317                 if ( inst->baseEnum ) {
    318                         declsToAddBefore.push_front( inst->baseEnum );
    319                 }
    320         }
    321 
    322         void HoistStruct::previsit( StructInstType * inst ) {
    323                 if ( inst->baseStruct ) {
    324                         declsToAddBefore.push_front( inst->baseStruct );
    325                 }
    326         }
    327 
    328         void HoistStruct::previsit( UnionInstType * inst ) {
    329                 if ( inst->baseUnion ) {
    330                         declsToAddBefore.push_front( inst->baseUnion );
     482                GuardAction( [aggregateDecl]() { filter( aggregateDecl->members, shouldHoist, false ); } );
     483        }
     484
     485        void HoistStruct::previsit( StaticAssertDecl * assertDecl ) {
     486                if ( parentAggr ) {
     487                        declsToAddBefore.push_back( assertDecl );
    331488                }
    332489        }
     
    340497        }
    341498
     499        void HoistStruct::previsit( StructInstType * type ) {
     500                // need to reset type name after expanding to qualified name
     501                assert( type->baseStruct );
     502                type->name = type->baseStruct->name;
     503        }
     504
     505        void HoistStruct::previsit( UnionInstType * type ) {
     506                assert( type->baseUnion );
     507                type->name = type->baseUnion->name;
     508        }
     509
     510        void HoistStruct::previsit( EnumInstType * type ) {
     511                assert( type->baseEnum );
     512                type->name = type->baseEnum->name;
     513        }
     514
     515
     516        bool isTypedef( Declaration *decl ) {
     517                return dynamic_cast< TypedefDecl * >( decl );
     518        }
     519
     520        void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) {
     521                PassVisitor<EliminateTypedef> eliminator;
     522                acceptAll( translationUnit, eliminator );
     523                filter( translationUnit, isTypedef, true );
     524        }
     525
     526        template< typename AggDecl >
     527        void EliminateTypedef::handleAggregate( AggDecl *aggregateDecl ) {
     528                filter( aggregateDecl->members, isTypedef, true );
     529        }
     530
     531        void EliminateTypedef::previsit( StructDecl * aggregateDecl ) {
     532                handleAggregate( aggregateDecl );
     533        }
     534
     535        void EliminateTypedef::previsit( UnionDecl * aggregateDecl ) {
     536                handleAggregate( aggregateDecl );
     537        }
     538
     539        void EliminateTypedef::previsit( CompoundStmt * compoundStmt ) {
     540                // remove and delete decl stmts
     541                filter( compoundStmt->kids, [](Statement * stmt) {
     542                        if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
     543                                if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) {
     544                                        return true;
     545                                } // if
     546                        } // if
     547                        return false;
     548                }, true);
     549        }
     550
    342551        void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) {
    343552                // Set the type of each member of the enumeration to be EnumConstant
    344                 for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
     553                for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) {
    345554                        ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i );
    346555                        assert( obj );
    347                         obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->get_name() ) );
     556                        obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) );
    348557                } // for
    349558        }
     
    351560        namespace {
    352561                template< typename DWTList >
    353                 void fixFunctionList( DWTList & dwts, FunctionType * func ) {
    354                         // the only case in which "void" is valid is where it is the only one in the list; then it should be removed
    355                         // entirely. other fix ups are handled by the FixFunction class
    356                         typedef typename DWTList::iterator DWTIterator;
    357                         DWTIterator begin( dwts.begin() ), end( dwts.end() );
    358                         if ( begin == end ) return;
    359                         PassVisitor<FixFunction> fixer;
    360                         DWTIterator i = begin;
    361                         *i = (*i)->acceptMutator( fixer );
    362                         if ( fixer.pass.isVoid ) {
    363                                 DWTIterator j = i;
    364                                 ++i;
    365                                 delete *j;
    366                                 dwts.erase( j );
    367                                 if ( i != end ) {
    368                                         throw SemanticError( "invalid type void in function type ", func );
    369                                 } // if
    370                         } else {
    371                                 ++i;
    372                                 for ( ; i != end; ++i ) {
    373                                         PassVisitor<FixFunction> fixer;
    374                                         *i = (*i)->acceptMutator( fixer );
    375                                         if ( fixer.pass.isVoid ) {
    376                                                 throw SemanticError( "invalid type void in function type ", func );
    377                                         } // if
    378                                 } // for
    379                         } // if
     562                void fixFunctionList( DWTList & dwts, bool isVarArgs, FunctionType * func ) {
     563                        auto nvals = dwts.size();
     564                        bool containsVoid = false;
     565                        for ( auto & dwt : dwts ) {
     566                                // fix each DWT and record whether a void was found
     567                                containsVoid |= fixFunction( dwt );
     568                        }
     569
     570                        // the only case in which "void" is valid is where it is the only one in the list
     571                        if ( containsVoid && ( nvals > 1 || isVarArgs ) ) {
     572                                SemanticError( func, "invalid type void in function type " );
     573                        }
     574
     575                        // one void is the only thing in the list; remove it.
     576                        if ( containsVoid ) {
     577                                delete dwts.front();
     578                                dwts.clear();
     579                        }
    380580                }
    381581        }
     
    383583        void EnumAndPointerDecay::previsit( FunctionType *func ) {
    384584                // Fix up parameters and return types
    385                 fixFunctionList( func->get_parameters(), func );
    386                 fixFunctionList( func->get_returnVals(), func );
     585                fixFunctionList( func->parameters, func->isVarArgs, func );
     586                fixFunctionList( func->returnVals, false, func );
    387587        }
    388588
     
    396596
    397597        void LinkReferenceToTypes::postvisit( EnumInstType *enumInst ) {
    398                 EnumDecl *st = local_indexer->lookupEnum( enumInst->get_name() );
     598                EnumDecl *st = local_indexer->lookupEnum( enumInst->name );
    399599                // it's not a semantic error if the enum is not found, just an implicit forward declaration
    400600                if ( st ) {
    401                         //assert( ! enumInst->get_baseEnum() || enumInst->get_baseEnum()->get_members().empty() || ! st->get_members().empty() );
    402                         enumInst->set_baseEnum( st );
    403                 } // if
    404                 if ( ! st || st->get_members().empty() ) {
     601                        enumInst->baseEnum = st;
     602                } // if
     603                if ( ! st || ! st->body ) {
    405604                        // use of forward declaration
    406                         forwardEnums[ enumInst->get_name() ].push_back( enumInst );
     605                        forwardEnums[ enumInst->name ].push_back( enumInst );
    407606                } // if
    408607        }
     
    411610                for ( Expression * param : inst->parameters ) {
    412611                        if ( ! dynamic_cast< TypeExpr * >( param ) ) {
    413                                 throw SemanticError( "Expression parameters for generic types are currently unsupported: ", inst );
     612                                SemanticError( inst, "Expression parameters for generic types are currently unsupported: " );
    414613                        }
    415614                }
     
    417616
    418617        void LinkReferenceToTypes::postvisit( StructInstType *structInst ) {
    419                 StructDecl *st = local_indexer->lookupStruct( structInst->get_name() );
     618                StructDecl *st = local_indexer->lookupStruct( structInst->name );
    420619                // it's not a semantic error if the struct is not found, just an implicit forward declaration
    421620                if ( st ) {
    422                         //assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
    423                         structInst->set_baseStruct( st );
    424                 } // if
    425                 if ( ! st || st->get_members().empty() ) {
     621                        structInst->baseStruct = st;
     622                } // if
     623                if ( ! st || ! st->body ) {
    426624                        // use of forward declaration
    427                         forwardStructs[ structInst->get_name() ].push_back( structInst );
     625                        forwardStructs[ structInst->name ].push_back( structInst );
    428626                } // if
    429627                checkGenericParameters( structInst );
     
    431629
    432630        void LinkReferenceToTypes::postvisit( UnionInstType *unionInst ) {
    433                 UnionDecl *un = local_indexer->lookupUnion( unionInst->get_name() );
     631                UnionDecl *un = local_indexer->lookupUnion( unionInst->name );
    434632                // it's not a semantic error if the union is not found, just an implicit forward declaration
    435633                if ( un ) {
    436                         unionInst->set_baseUnion( un );
    437                 } // if
    438                 if ( ! un || un->get_members().empty() ) {
     634                        unionInst->baseUnion = un;
     635                } // if
     636                if ( ! un || ! un->body ) {
    439637                        // use of forward declaration
    440                         forwardUnions[ unionInst->get_name() ].push_back( unionInst );
     638                        forwardUnions[ unionInst->name ].push_back( unionInst );
    441639                } // if
    442640                checkGenericParameters( unionInst );
     641        }
     642
     643        void LinkReferenceToTypes::previsit( QualifiedType * ) {
     644                visit_children = false;
     645        }
     646
     647        void LinkReferenceToTypes::postvisit( QualifiedType * qualType ) {
     648                // linking only makes sense for the 'oldest ancestor' of the qualified type
     649                qualType->parent->accept( *visitor );
    443650        }
    444651
     
    451658                        DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 );
    452659                        if ( dwt1 && dwt2 ) {
    453                                 if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
     660                                if ( dwt1->name == dwt2->name && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
    454661                                        // std::cerr << "=========== equal:" << std::endl;
    455662                                        // std::cerr << "d1: " << d1 << std::endl;
     
    476683        template< typename Iterator >
    477684        void expandAssertions( TraitInstType * inst, Iterator out ) {
    478                 assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() );
     685                assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toCString( inst ) );
    479686                std::list< DeclarationWithType * > asserts;
    480687                for ( Declaration * decl : inst->baseTrait->members ) {
     
    511718                TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );
    512719                if ( ! traitDecl ) {
    513                         throw SemanticError( "use of undeclared trait " + traitInst->name );
    514                 } // if
    515                 if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
    516                         throw SemanticError( "incorrect number of trait parameters: ", traitInst );
     720                        SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name );
     721                } // if
     722                if ( traitDecl->parameters.size() != traitInst->parameters.size() ) {
     723                        SemanticError( traitInst, "incorrect number of trait parameters: " );
    517724                } // if
    518725                traitInst->baseTrait = traitDecl;
    519726
    520727                // need to carry over the 'sized' status of each decl in the instance
    521                 for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) {
     728                for ( auto p : group_iterate( traitDecl->parameters, traitInst->parameters ) ) {
    522729                        TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) );
    523730                        if ( ! expr ) {
    524                                 throw SemanticError( "Expression parameters for trait instances are currently unsupported: ", std::get<1>(p) );
     731                                SemanticError( std::get<1>(p), "Expression parameters for trait instances are currently unsupported: " );
    525732                        }
    526733                        if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
    527734                                TypeDecl * formalDecl = std::get<0>(p);
    528                                 TypeDecl * instDecl = inst->get_baseType();
     735                                TypeDecl * instDecl = inst->baseType;
    529736                                if ( formalDecl->get_sized() ) instDecl->set_sized( true );
    530737                        }
     
    535742        void LinkReferenceToTypes::postvisit( EnumDecl *enumDecl ) {
    536743                // visit enum members first so that the types of self-referencing members are updated properly
    537                 if ( ! enumDecl->get_members().empty() ) {
    538                         ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->get_name() );
     744                if ( enumDecl->body ) {
     745                        ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->name );
    539746                        if ( fwds != forwardEnums.end() ) {
    540747                                for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    541                                         (*inst )->set_baseEnum( enumDecl );
     748                                        (*inst)->baseEnum = enumDecl;
    542749                                } // for
    543750                                forwardEnums.erase( fwds );
    544751                        } // if
     752
     753                        for ( Declaration * member : enumDecl->members ) {
     754                                ObjectDecl * field = strict_dynamic_cast<ObjectDecl *>( member );
     755                                if ( field->init ) {
     756                                        // need to resolve enumerator initializers early so that other passes that determine if an expression is constexpr have the appropriate information.
     757                                        SingleInit * init = strict_dynamic_cast<SingleInit *>( field->init );
     758                                        ResolvExpr::findSingleExpression( init->value, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), indexer );
     759                                }
     760                        }
    545761                } // if
    546762        }
     
    575791                // visit struct members first so that the types of self-referencing members are updated properly
    576792                // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults)
    577                 if ( ! structDecl->get_members().empty() ) {
    578                         ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
     793                if ( structDecl->body ) {
     794                        ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->name );
    579795                        if ( fwds != forwardStructs.end() ) {
    580796                                for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    581                                         (*inst )->set_baseStruct( structDecl );
     797                                        (*inst)->baseStruct = structDecl;
    582798                                } // for
    583799                                forwardStructs.erase( fwds );
     
    587803
    588804        void LinkReferenceToTypes::postvisit( UnionDecl *unionDecl ) {
    589                 if ( ! unionDecl->get_members().empty() ) {
    590                         ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
     805                if ( unionDecl->body ) {
     806                        ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name );
    591807                        if ( fwds != forwardUnions.end() ) {
    592808                                for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    593                                         (*inst )->set_baseUnion( unionDecl );
     809                                        (*inst)->baseUnion = unionDecl;
    594810                                } // for
    595811                                forwardUnions.erase( fwds );
     
    601817                // ensure generic parameter instances are renamed like the base type
    602818                if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name;
    603                 if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name() ) ) {
     819                if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) {
    604820                        if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
    605821                                typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
     
    626842                        // apply FixFunction to every assertion to check for invalid void type
    627843                        for ( DeclarationWithType *& assertion : type->assertions ) {
    628                                 PassVisitor<FixFunction> fixer;
    629                                 assertion = assertion->acceptMutator( fixer );
    630                                 if ( fixer.pass.isVoid ) {
    631                                         throw SemanticError( "invalid type void in assertion of function ", node );
     844                                bool isVoid = fixFunction( assertion );
     845                                if ( isVoid ) {
     846                                        SemanticError( node, "invalid type void in assertion of function " );
    632847                                } // if
    633848                        } // for
     
    637852
    638853        void ForallPointerDecay::previsit( ObjectDecl *object ) {
    639                 forallFixer( object->type->forall, object );
    640                 if ( PointerType *pointer = dynamic_cast< PointerType * >( object->type ) ) {
    641                         forallFixer( pointer->base->forall, object );
    642                 } // if
     854                // ensure that operator names only apply to functions or function pointers
     855                if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) {
     856                        SemanticError( object->location, toCString( "operator ", object->name.c_str(), " is not a function or function pointer." ) );
     857                }
    643858                object->fixUniqueId();
    644859        }
    645860
    646861        void ForallPointerDecay::previsit( FunctionDecl *func ) {
    647                 forallFixer( func->type->forall, func );
    648862                func->fixUniqueId();
     863        }
     864
     865        void ForallPointerDecay::previsit( FunctionType * ftype ) {
     866                forallFixer( ftype->forall, ftype );
    649867        }
    650868
     
    673891                // were cast to void.
    674892                if ( ! returnStmt->get_expr() && returnVals.size() != 0 ) {
    675                         throw SemanticError( "Non-void function returns no values: " , returnStmt );
    676                 }
    677         }
    678 
    679 
    680         bool isTypedef( Declaration *decl ) {
    681                 return dynamic_cast< TypedefDecl * >( decl );
    682         }
    683 
    684         void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) {
    685                 PassVisitor<EliminateTypedef> eliminator;
     893                        SemanticError( returnStmt, "Non-void function returns no values: " );
     894                }
     895        }
     896
     897
     898        void ReplaceTypedef::replaceTypedef( std::list< Declaration * > &translationUnit ) {
     899                PassVisitor<ReplaceTypedef> eliminator;
    686900                mutateAll( translationUnit, eliminator );
    687901                if ( eliminator.pass.typedefNames.count( "size_t" ) ) {
    688902                        // grab and remember declaration of size_t
    689                         SizeType = eliminator.pass.typedefNames["size_t"].first->get_base()->clone();
     903                        SizeType = eliminator.pass.typedefNames["size_t"].first->base->clone();
    690904                } else {
    691905                        // xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong
     
    693907                        SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    694908                }
    695                 filter( translationUnit, isTypedef, true );
    696         }
    697 
    698         Type * EliminateTypedef::postmutate( TypeInstType * typeInst ) {
     909        }
     910
     911        void ReplaceTypedef::premutate( QualifiedType * ) {
     912                visit_children = false;
     913        }
     914
     915        Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) {
     916                // replacing typedefs only makes sense for the 'oldest ancestor' of the qualified type
     917                qualType->parent = qualType->parent->acceptMutator( *visitor );
     918                return qualType;
     919        }
     920
     921        Type * ReplaceTypedef::postmutate( TypeInstType * typeInst ) {
    699922                // instances of typedef types will come here. If it is an instance
    700923                // of a typdef type, link the instance to its actual type.
    701                 TypedefMap::const_iterator def = typedefNames.find( typeInst->get_name() );
     924                TypedefMap::const_iterator def = typedefNames.find( typeInst->name );
    702925                if ( def != typedefNames.end() ) {
    703926                        Type *ret = def->second.first->base->clone();
     927                        ret->location = typeInst->location;
    704928                        ret->get_qualifiers() |= typeInst->get_qualifiers();
    705929                        // attributes are not carried over from typedef to function parameters/return values
     
    714938                                ReferenceToType *rtt = dynamic_cast<ReferenceToType*>(ret);
    715939                                if ( ! rtt ) {
    716                                         throw SemanticError("Cannot apply type parameters to base type of " + typeInst->name);
     940                                        SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name );
    717941                                }
    718                                 rtt->get_parameters().clear();
     942                                rtt->parameters.clear();
    719943                                cloneAll( typeInst->parameters, rtt->parameters );
    720944                                mutateAll( rtt->parameters, *visitor );  // recursively fix typedefs on parameters
     
    723947                        return ret;
    724948                } else {
    725                         TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
    726                         assertf( base != typedeclNames.end(), "Cannot find typedecl name %s", typeInst->name.c_str() );
     949                        TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->name );
     950                        if ( base == typedeclNames.end() ) {
     951                                SemanticError( typeInst->location, toString("Use of undefined type ", typeInst->name) );
     952                        }
    727953                        typeInst->set_baseType( base->second );
    728                 } // if
    729                 return typeInst;
     954                        return typeInst;
     955                } // if
     956                assert( false );
    730957        }
    731958
     
    744971        }
    745972
    746         Declaration *EliminateTypedef::postmutate( TypedefDecl * tyDecl ) {
    747                 if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
     973        Declaration * ReplaceTypedef::postmutate( TypedefDecl * tyDecl ) {
     974                if ( typedefNames.count( tyDecl->name ) == 1 && typedefNames[ tyDecl->name ].second == scopeLevel ) {
    748975                        // typedef to the same name from the same scope
    749976                        // must be from the same type
    750977
    751                         Type * t1 = tyDecl->get_base();
    752                         Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base();
     978                        Type * t1 = tyDecl->base;
     979                        Type * t2 = typedefNames[ tyDecl->name ].first->base;
    753980                        if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) {
    754                                 throw SemanticError( "Cannot redefine typedef: " + tyDecl->name );
    755                         }
    756                         // cannot redefine VLA typedefs
     981                                SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name );
     982                        }
     983                        // Cannot redefine VLA typedefs. Note: this is slightly incorrect, because our notion of VLAs
     984                        // at this point in the translator is imprecise. In particular, this will disallow redefining typedefs
     985                        // with arrays whose dimension is an enumerator or a cast of a constant/enumerator. The effort required
     986                        // to fix this corner case likely outweighs the utility of allowing it.
    757987                        if ( isVariableLength( t1 ) || isVariableLength( t2 ) ) {
    758                                 throw SemanticError( "Cannot redefine typedef: " + tyDecl->name );
     988                                SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name );
    759989                        }
    760990                } else {
    761                         typedefNames[ tyDecl->get_name() ] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel );
     991                        typedefNames[ tyDecl->name ] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel );
    762992                } // if
    763993
     
    7711001                // Note, qualifiers on the typedef are superfluous for the forward declaration.
    7721002
    773                 Type *designatorType = tyDecl->get_base()->stripDeclarator();
     1003                Type *designatorType = tyDecl->base->stripDeclarator();
    7741004                if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
    775                         return new StructDecl( aggDecl->get_name(), DeclarationNode::Struct, noAttributes, tyDecl->get_linkage() );
     1005                        declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) );
    7761006                } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
    777                         return new UnionDecl( aggDecl->get_name(), noAttributes, tyDecl->get_linkage() );
     1007                        declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) );
    7781008                } else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
    779                         return new EnumDecl( enumDecl->get_name(), noAttributes, tyDecl->get_linkage() );
    780                 } else {
    781                         return tyDecl->clone();
    782                 } // if
    783         }
    784 
    785         void EliminateTypedef::premutate( TypeDecl * typeDecl ) {
    786                 TypedefMap::iterator i = typedefNames.find( typeDecl->get_name() );
     1009                        declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) );
     1010                } // if
     1011                return tyDecl->clone();
     1012        }
     1013
     1014        void ReplaceTypedef::premutate( TypeDecl * typeDecl ) {
     1015                TypedefMap::iterator i = typedefNames.find( typeDecl->name );
    7871016                if ( i != typedefNames.end() ) {
    7881017                        typedefNames.erase( i ) ;
    7891018                } // if
    7901019
    791                 typedeclNames[ typeDecl->get_name() ] = typeDecl;
    792         }
    793 
    794         void EliminateTypedef::premutate( FunctionDecl * ) {
     1020                typedeclNames.insert( typeDecl->name, typeDecl );
     1021        }
     1022
     1023        void ReplaceTypedef::premutate( FunctionDecl * ) {
    7951024                GuardScope( typedefNames );
    796         }
    797 
    798         void EliminateTypedef::premutate( ObjectDecl * ) {
     1025                GuardScope( typedeclNames );
     1026        }
     1027
     1028        void ReplaceTypedef::premutate( ObjectDecl * ) {
    7991029                GuardScope( typedefNames );
    800         }
    801 
    802         DeclarationWithType *EliminateTypedef::postmutate( ObjectDecl * objDecl ) {
    803                 if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->get_type() ) ) { // function type?
     1030                GuardScope( typedeclNames );
     1031        }
     1032
     1033        DeclarationWithType * ReplaceTypedef::postmutate( ObjectDecl * objDecl ) {
     1034                if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type?
    8041035                        // replace the current object declaration with a function declaration
    805                         FunctionDecl * newDecl = new FunctionDecl( objDecl->get_name(), objDecl->get_storageClasses(), objDecl->get_linkage(), funtype, 0, objDecl->get_attributes(), objDecl->get_funcSpec() );
    806                         objDecl->get_attributes().clear();
     1036                        FunctionDecl * newDecl = new FunctionDecl( objDecl->name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() );
     1037                        objDecl->attributes.clear();
    8071038                        objDecl->set_type( nullptr );
    8081039                        delete objDecl;
     
    8121043        }
    8131044
    814         void EliminateTypedef::premutate( CastExpr * ) {
     1045        void ReplaceTypedef::premutate( CastExpr * ) {
    8151046                GuardScope( typedefNames );
    816         }
    817 
    818         void EliminateTypedef::premutate( CompoundStmt * ) {
     1047                GuardScope( typedeclNames );
     1048        }
     1049
     1050        void ReplaceTypedef::premutate( CompoundStmt * ) {
    8191051                GuardScope( typedefNames );
     1052                GuardScope( typedeclNames );
    8201053                scopeLevel += 1;
    8211054                GuardAction( [this](){ scopeLevel -= 1; } );
    8221055        }
    8231056
    824         CompoundStmt *EliminateTypedef::postmutate( CompoundStmt * compoundStmt ) {
    825                 // remove and delete decl stmts
    826                 filter( compoundStmt->kids, [](Statement * stmt) {
    827                         if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
    828                                 if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {
    829                                         return true;
    830                                 } // if
    831                         } // if
    832                         return false;
    833                 }, true);
    834                 return compoundStmt;
    835         }
    836 
    837         // there may be typedefs nested within aggregates. in order for everything to work properly, these should be removed
    838         // as well
    8391057        template<typename AggDecl>
    840         AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) {
    841                 filter( aggDecl->members, isTypedef, true );
    842                 return aggDecl;
    843         }
    844 
    845         template<typename AggDecl>
    846         void EliminateTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
     1058        void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
    8471059                if ( typedefNames.count( aggDecl->get_name() ) == 0 ) {
    8481060                        Type *type = nullptr;
     
    8541066                                type = new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() );
    8551067                        } // if
    856                         TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), Type::StorageClasses(), type, aggDecl->get_linkage() ) );
     1068                        TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type, aggDecl->get_linkage() ) );
    8571069                        typedefNames[ aggDecl->get_name() ] = std::make_pair( std::move( tyDecl ), scopeLevel );
    858                 } // if
    859         }
    860 
    861         void EliminateTypedef::premutate( StructDecl * structDecl ) {
     1070                        // add the implicit typedef to the AST
     1071                        declsToAddBefore.push_back( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type->clone(), aggDecl->get_linkage() ) );
     1072                } // if
     1073        }
     1074
     1075        template< typename AggDecl >
     1076        void ReplaceTypedef::handleAggregate( AggDecl * aggr ) {
     1077                SemanticErrorException errors;
     1078
     1079                ValueGuard< std::list<Declaration * > > oldBeforeDecls( declsToAddBefore );
     1080                ValueGuard< std::list<Declaration * > > oldAfterDecls ( declsToAddAfter  );
     1081                declsToAddBefore.clear();
     1082                declsToAddAfter.clear();
     1083
     1084                GuardScope( typedefNames );
     1085                GuardScope( typedeclNames );
     1086                mutateAll( aggr->parameters, *visitor );
     1087
     1088                // unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body.
     1089                for ( std::list< Declaration * >::iterator i = aggr->members.begin(); i != aggr->members.end(); ++i ) {
     1090                        if ( !declsToAddAfter.empty() ) { aggr->members.splice( i, declsToAddAfter ); }
     1091
     1092                        try {
     1093                                *i = maybeMutate( *i, *visitor );
     1094                        } catch ( SemanticErrorException &e ) {
     1095                                errors.append( e );
     1096                        }
     1097
     1098                        if ( !declsToAddBefore.empty() ) { aggr->members.splice( i, declsToAddBefore ); }
     1099                }
     1100
     1101                if ( !declsToAddAfter.empty() ) { aggr->members.splice( aggr->members.end(), declsToAddAfter ); }
     1102                if ( !errors.isEmpty() ) { throw errors; }
     1103        }
     1104
     1105        void ReplaceTypedef::premutate( StructDecl * structDecl ) {
     1106                visit_children = false;
    8621107                addImplicitTypedef( structDecl );
    863         }
    864 
    865 
    866         Declaration *EliminateTypedef::postmutate( StructDecl * structDecl ) {
    867                 return handleAggregate( structDecl );
    868         }
    869 
    870         void EliminateTypedef::premutate( UnionDecl * unionDecl ) {
     1108                handleAggregate( structDecl );
     1109        }
     1110
     1111        void ReplaceTypedef::premutate( UnionDecl * unionDecl ) {
     1112                visit_children = false;
    8711113                addImplicitTypedef( unionDecl );
    872         }
    873 
    874         Declaration *EliminateTypedef::postmutate( UnionDecl * unionDecl ) {
    875                 return handleAggregate( unionDecl );
    876         }
    877 
    878         void EliminateTypedef::premutate( EnumDecl * enumDecl ) {
     1114                handleAggregate( unionDecl );
     1115        }
     1116
     1117        void ReplaceTypedef::premutate( EnumDecl * enumDecl ) {
    8791118                addImplicitTypedef( enumDecl );
    8801119        }
    8811120
    882         Declaration *EliminateTypedef::postmutate( EnumDecl * enumDecl ) {
    883                 return handleAggregate( enumDecl );
    884         }
    885 
    886         Declaration *EliminateTypedef::postmutate( TraitDecl * traitDecl ) {
    887                 return handleAggregate( traitDecl );
    888         }
    889 
    890         void EliminateTypedef::premutate( FunctionType * ) {
     1121        void ReplaceTypedef::premutate( FunctionType * ) {
    8911122                GuardValue( inFunctionType );
    8921123                inFunctionType = true;
     1124        }
     1125
     1126        void ReplaceTypedef::premutate( TraitDecl * ) {
     1127                GuardScope( typedefNames );
     1128                GuardScope( typedeclNames);
    8931129        }
    8941130
     
    9051141                if ( CodeGen::isCtorDtorAssign( funcDecl->get_name() ) ) { // TODO: also check /=, etc.
    9061142                        if ( params.size() == 0 ) {
    907                                 throw SemanticError( "Constructors, destructors, and assignment functions require at least one parameter ", funcDecl );
     1143                                SemanticError( funcDecl, "Constructors, destructors, and assignment functions require at least one parameter " );
    9081144                        }
    9091145                        ReferenceType * refType = dynamic_cast< ReferenceType * >( params.front()->get_type() );
    9101146                        if ( ! refType ) {
    911                                 throw SemanticError( "First parameter of a constructor, destructor, or assignment function must be a reference ", funcDecl );
     1147                                SemanticError( funcDecl, "First parameter of a constructor, destructor, or assignment function must be a reference " );
    9121148                        }
    9131149                        if ( CodeGen::isCtorDtor( funcDecl->get_name() ) && returnVals.size() != 0 ) {
    914                                 throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl );
     1150                                SemanticError( funcDecl, "Constructors and destructors cannot have explicit return values " );
    9151151                        }
    9161152                }
     
    9471183
    9481184                        sub.apply( inst );
    949                         if ( args.size() < params->size() ) throw SemanticError( "Too few type arguments in generic type ", inst );
    950                         if ( args.size() > params->size() ) throw SemanticError( "Too many type arguments in generic type ", inst );
     1185                        if ( args.size() < params->size() ) SemanticError( inst, "Too few type arguments in generic type " );
     1186                        if ( args.size() > params->size() ) SemanticError( inst, "Too many type arguments in generic type " );
    9511187                }
    9521188        }
     
    10141250        }
    10151251
     1252        void FixObjectType::fix( std::list< Declaration * > & translationUnit ) {
     1253                PassVisitor<FixObjectType> fixer;
     1254                acceptAll( translationUnit, fixer );
     1255        }
     1256
     1257        void FixObjectType::previsit( ObjectDecl * objDecl ) {
     1258                Type *new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer );
     1259                new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type
     1260                objDecl->set_type( new_type );
     1261        }
     1262
     1263        void FixObjectType::previsit( FunctionDecl * funcDecl ) {
     1264                Type *new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );
     1265                new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type
     1266                funcDecl->set_type( new_type );
     1267        }
     1268
     1269        void FixObjectType::previsit( TypeDecl *typeDecl ) {
     1270                if ( typeDecl->get_base() ) {
     1271                        Type *new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );
     1272                        new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type
     1273                        typeDecl->set_base( new_type );
     1274                } // if
     1275        }
     1276
    10161277        void ArrayLength::computeLength( std::list< Declaration * > & translationUnit ) {
    10171278                PassVisitor<ArrayLength> len;
     
    10201281
    10211282        void ArrayLength::previsit( ObjectDecl * objDecl ) {
    1022                 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
    1023                         if ( at->get_dimension() ) return;
    1024                         if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->get_init() ) ) {
    1025                                 at->set_dimension( new ConstantExpr( Constant::from_ulong( init->get_initializers().size() ) ) );
    1026                         }
     1283                if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->type ) ) {
     1284                        if ( at->dimension ) return;
     1285                        if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->init ) ) {
     1286                                at->dimension = new ConstantExpr( Constant::from_ulong( init->initializers.size() ) );
     1287                        }
     1288                }
     1289        }
     1290
     1291        void ArrayLength::previsit( ArrayType * type ) {
     1292                if ( type->dimension ) {
     1293                        // need to resolve array dimensions early so that constructor code can correctly determine
     1294                        // if a type is a VLA (and hence whether its elements need to be constructed)
     1295                        ResolvExpr::findSingleExpression( type->dimension, SymTab::SizeType->clone(), indexer );
     1296
     1297                        // must re-evaluate whether a type is a VLA, now that more information is available
     1298                        // (e.g. the dimension may have been an enumerator, which was unknown prior to this step)
     1299                        type->isVarLen = ! InitTweak::isConstExpr( type->dimension );
    10271300                }
    10281301        }
  • src/SymTab/module.mk

    rf9feab8 r90152a4  
    1717SRC += SymTab/Indexer.cc \
    1818       SymTab/Mangler.cc \
     19       SymTab/ManglerCommon.cc \
    1920       SymTab/Validate.cc \
    2021       SymTab/FixFunction.cc \
Note: See TracChangeset for help on using the changeset viewer.