Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    rb4f8808 r25fcb84  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Aug  7 6:42:00 2019
    13 // Update Count     : 360
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Mon Aug 28 13:47:23 2017
     13// Update Count     : 359
    1414//
    1515
     
    4444#include <list>                        // for list
    4545#include <string>                      // for string
    46 #include <unordered_map>               // for unordered_map
    4746#include <utility>                     // for pair
    4847
    49 #include "AST/Chain.hpp"
    50 #include "AST/Decl.hpp"
    51 #include "AST/Node.hpp"
    52 #include "AST/Pass.hpp"
    53 #include "AST/SymbolTable.hpp"
    54 #include "AST/Type.hpp"
    55 #include "AST/TypeSubstitution.hpp"
    5648#include "CodeGen/CodeGenerator.h"     // for genName
    5749#include "CodeGen/OperatorTable.h"     // for isCtorDtor, isCtorDtorAssign
    5850#include "ControlStruct/Mutate.h"      // for ForExprMutator
    59 #include "Common/CodeLocation.h"       // for CodeLocation
    60 #include "Common/Stats.h"              // for Stats::Heap
    6151#include "Common/PassVisitor.h"        // for PassVisitor, WithDeclsToAdd
    6252#include "Common/ScopedMap.h"          // for ScopedMap
     
    7161#include "Parser/LinkageSpec.h"        // for C
    7262#include "ResolvExpr/typeops.h"        // for typesCompatible
    73 #include "ResolvExpr/Resolver.h"       // for findSingleExpression
    74 #include "ResolvExpr/ResolveTypeof.h"  // for resolveTypeof
    7563#include "SymTab/Autogen.h"            // for SizeType
    7664#include "SynTree/Attribute.h"         // for noAttributes, Attribute
     
    8472#include "SynTree/TypeSubstitution.h"  // for TypeSubstitution
    8573#include "SynTree/Visitor.h"           // for Visitor
    86 #include "Validate/HandleAttributes.h" // for handleAttributes
    87 #include "Validate/FindSpecialDecls.h" // for FindSpecialDecls
    8874
    8975class CompoundStmt;
     
    9177class SwitchStmt;
    9278
    93 #define debugPrint( x ) if ( doDebug ) x
     79#define debugPrint( x ) if ( doDebug ) { std::cout << x; }
    9480
    9581namespace SymTab {
    96         /// hoists declarations that are difficult to hoist while parsing
    97         struct HoistTypeDecls final : public WithDeclsToAdd {
    98                 void previsit( SizeofExpr * );
    99                 void previsit( AlignofExpr * );
    100                 void previsit( UntypedOffsetofExpr * );
    101                 void previsit( CompoundLiteralExpr * );
    102                 void handleType( Type * );
    103         };
    104 
    105         struct FixQualifiedTypes final : public WithIndexer {
    106                 Type * postmutate( QualifiedType * );
    107         };
    108 
    10982        struct HoistStruct final : public WithDeclsToAdd, public WithGuards {
    11083                /// Flattens nested struct types
    11184                static void hoistStruct( std::list< Declaration * > &translationUnit );
    11285
     86                void previsit( EnumInstType * enumInstType );
     87                void previsit( StructInstType * structInstType );
     88                void previsit( UnionInstType * unionInstType );
    11389                void previsit( StructDecl * aggregateDecl );
    11490                void previsit( UnionDecl * aggregateDecl );
    11591                void previsit( StaticAssertDecl * assertDecl );
    116                 void previsit( StructInstType * type );
    117                 void previsit( UnionInstType * type );
    118                 void previsit( EnumInstType * type );
    11992
    12093          private:
    121                 template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl );
     94                template< typename AggDecl > void handleAggregate( AggDecl *aggregateDecl );
    12295
    12396                AggregateDecl * parentAggr = nullptr;
     
    133106
    134107        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    135         struct EnumAndPointerDecay_old {
    136                 void previsit( EnumDecl * aggregateDecl );
    137                 void previsit( FunctionType * func );
     108        struct EnumAndPointerDecay {
     109                void previsit( EnumDecl *aggregateDecl );
     110                void previsit( FunctionType *func );
    138111        };
    139112
    140113        /// Associates forward declarations of aggregates with their definitions
    141         struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting {
    142                 LinkReferenceToTypes_old( const Indexer * indexer );
    143                 void postvisit( TypeInstType * typeInst );
    144 
    145                 void postvisit( EnumInstType * enumInst );
    146                 void postvisit( StructInstType * structInst );
    147                 void postvisit( UnionInstType * unionInst );
    148                 void postvisit( TraitInstType * traitInst );
    149                 void previsit( QualifiedType * qualType );
    150                 void postvisit( QualifiedType * qualType );
    151 
    152                 void postvisit( EnumDecl * enumDecl );
    153                 void postvisit( StructDecl * structDecl );
    154                 void postvisit( UnionDecl * unionDecl );
     114        struct LinkReferenceToTypes final : public WithIndexer, public WithGuards {
     115                LinkReferenceToTypes( const Indexer *indexer );
     116                void postvisit( TypeInstType *typeInst );
     117
     118                void postvisit( EnumInstType *enumInst );
     119                void postvisit( StructInstType *structInst );
     120                void postvisit( UnionInstType *unionInst );
     121                void postvisit( TraitInstType *traitInst );
     122
     123                void postvisit( EnumDecl *enumDecl );
     124                void postvisit( StructDecl *structDecl );
     125                void postvisit( UnionDecl *unionDecl );
    155126                void postvisit( TraitDecl * traitDecl );
    156127
    157                 void previsit( StructDecl * structDecl );
    158                 void previsit( UnionDecl * unionDecl );
     128                void previsit( StructDecl *structDecl );
     129                void previsit( UnionDecl *unionDecl );
    159130
    160131                void renameGenericParams( std::list< TypeDecl * > & params );
    161132
    162133          private:
    163                 const Indexer * local_indexer;
     134                const Indexer *local_indexer;
    164135
    165136                typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType;
     
    174145
    175146        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
    176         struct ForallPointerDecay_old final {
     147        struct ForallPointerDecay final {
    177148                void previsit( ObjectDecl * object );
    178149                void previsit( FunctionDecl * func );
     
    194165        };
    195166
    196         struct ReplaceTypedef final : public WithVisitorRef<ReplaceTypedef>, public WithGuards, public WithShortCircuiting, public WithDeclsToAdd {
    197                 ReplaceTypedef() : scopeLevel( 0 ) {}
     167        struct EliminateTypedef final : public WithVisitorRef<EliminateTypedef>, public WithGuards {
     168                EliminateTypedef() : scopeLevel( 0 ) {}
    198169                /// Replaces typedefs by forward declarations
    199                 static void replaceTypedef( std::list< Declaration * > &translationUnit );
    200 
    201                 void premutate( QualifiedType * );
    202                 Type * postmutate( QualifiedType * qualType );
     170                static void eliminateTypedef( std::list< Declaration * > &translationUnit );
     171
    203172                Type * postmutate( TypeInstType * aggregateUseType );
    204173                Declaration * postmutate( TypedefDecl * typeDecl );
     
    211180
    212181                void premutate( CompoundStmt * compoundStmt );
     182                CompoundStmt * postmutate( CompoundStmt * compoundStmt );
    213183
    214184                void premutate( StructDecl * structDecl );
     185                Declaration * postmutate( StructDecl * structDecl );
    215186                void premutate( UnionDecl * unionDecl );
     187                Declaration * postmutate( UnionDecl * unionDecl );
    216188                void premutate( EnumDecl * enumDecl );
    217                 void premutate( TraitDecl * );
     189                Declaration * postmutate( EnumDecl * enumDecl );
     190                Declaration * postmutate( TraitDecl * contextDecl );
    218191
    219192                void premutate( FunctionType * ftype );
     
    221194          private:
    222195                template<typename AggDecl>
     196                AggDecl *handleAggregate( AggDecl * aggDecl );
     197
     198                template<typename AggDecl>
    223199                void addImplicitTypedef( AggDecl * aggDecl );
    224                 template< typename AggDecl >
    225                 void handleAggregate( AggDecl * aggr );
    226200
    227201                typedef std::unique_ptr<TypedefDecl> TypedefDeclPtr;
    228202                typedef ScopedMap< std::string, std::pair< TypedefDeclPtr, int > > TypedefMap;
    229                 typedef ScopedMap< std::string, TypeDecl * > TypeDeclMap;
     203                typedef std::map< std::string, TypeDecl * > TypeDeclMap;
    230204                TypedefMap typedefNames;
    231205                TypeDeclMap typedeclNames;
    232206                int scopeLevel;
    233207                bool inFunctionType = false;
    234         };
    235 
    236         struct EliminateTypedef {
    237                 /// removes TypedefDecls from the AST
    238                 static void eliminateTypedef( std::list< Declaration * > &translationUnit );
    239 
    240                 template<typename AggDecl>
    241                 void handleAggregate( AggDecl * aggregateDecl );
    242 
    243                 void previsit( StructDecl * aggregateDecl );
    244                 void previsit( UnionDecl * aggregateDecl );
    245                 void previsit( CompoundStmt * compoundStmt );
    246208        };
    247209
     
    252214                static void verify( std::list< Declaration * > &translationUnit );
    253215
    254                 void previsit( FunctionDecl * funcDecl );
     216                void previsit( FunctionDecl *funcDecl );
    255217        };
    256218
     
    261223        };
    262224
    263         struct FixObjectType : public WithIndexer {
    264                 /// resolves typeof type in object, function, and type declarations
    265                 static void fix( std::list< Declaration * > & translationUnit );
    266 
    267                 void previsit( ObjectDecl * );
    268                 void previsit( FunctionDecl * );
    269                 void previsit( TypeDecl * );
    270         };
    271 
    272         struct ArrayLength : public WithIndexer {
     225        struct ArrayLength {
    273226                /// for array types without an explicit length, compute the length and store it so that it
    274227                /// is known to the rest of the phases. For example,
     
    281234
    282235                void previsit( ObjectDecl * objDecl );
    283                 void previsit( ArrayType * arrayType );
    284236        };
    285237
     
    287239                Type::StorageClasses storageClasses;
    288240
    289                 void premutate( ObjectDecl * objectDecl );
    290                 Expression * postmutate( CompoundLiteralExpr * compLitExpr );
     241                void premutate( ObjectDecl *objectDecl );
     242                Expression * postmutate( CompoundLiteralExpr *compLitExpr );
    291243        };
    292244
     
    298250        };
    299251
     252        FunctionDecl * dereferenceOperator = nullptr;
     253        struct FindSpecialDeclarations final {
     254                void previsit( FunctionDecl * funcDecl );
     255        };
     256
    300257        void validate( std::list< Declaration * > &translationUnit, __attribute__((unused)) bool doDebug ) {
    301                 PassVisitor<EnumAndPointerDecay_old> epc;
    302                 PassVisitor<LinkReferenceToTypes_old> lrt( nullptr );
    303                 PassVisitor<ForallPointerDecay_old> fpd;
     258                PassVisitor<EnumAndPointerDecay> epc;
     259                PassVisitor<LinkReferenceToTypes> lrt( nullptr );
     260                PassVisitor<ForallPointerDecay> fpd;
    304261                PassVisitor<CompoundLiteral> compoundliteral;
    305262                PassVisitor<ValidateGenericParameters> genericParams;
     263                PassVisitor<FindSpecialDeclarations> finder;
    306264                PassVisitor<LabelAddressFixer> labelAddrFixer;
    307                 PassVisitor<HoistTypeDecls> hoistDecls;
    308                 PassVisitor<FixQualifiedTypes> fixQual;
    309 
    310                 {
    311                         Stats::Heap::newPass("validate-A");
    312                         Stats::Time::BlockGuard guard("validate-A");
    313                         acceptAll( translationUnit, hoistDecls );
    314                         ReplaceTypedef::replaceTypedef( translationUnit );
    315                         ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
    316                         acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist; before LinkReferenceToTypes_old because it is an indexer and needs correct types for mangling
    317                 }
    318                 {
    319                         Stats::Heap::newPass("validate-B");
    320                         Stats::Time::BlockGuard guard("validate-B");
    321                         Stats::Time::TimeBlock("Link Reference To Types", [&]() {
    322                                 acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
    323                         });
    324                         Stats::Time::TimeBlock("Fix Qualified Types", [&]() {
    325                                 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed
    326                         });
    327                         Stats::Time::TimeBlock("Hoist Structs", [&]() {
    328                                 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
    329                         });
    330                         Stats::Time::TimeBlock("Eliminate Typedefs", [&]() {
    331                                 EliminateTypedef::eliminateTypedef( translationUnit ); //
    332                         });
    333                 }
    334                 {
    335                         Stats::Heap::newPass("validate-C");
    336                         Stats::Time::BlockGuard guard("validate-C");
    337                         acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes_old
    338                         VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    339                         ReturnChecker::checkFunctionReturns( translationUnit );
    340                         InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen
    341                 }
    342                 {
    343                         Stats::Heap::newPass("validate-D");
    344                         Stats::Time::BlockGuard guard("validate-D");
    345                         Stats::Time::TimeBlock("Apply Concurrent Keywords", [&]() {
    346                                 Concurrency::applyKeywords( translationUnit );
    347                         });
    348                         Stats::Time::TimeBlock("Forall Pointer Decay", [&]() {
    349                                 acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
    350                         });
    351                         Stats::Time::TimeBlock("Hoist Control Declarations", [&]() {
    352                                 ControlStruct::hoistControlDecls( translationUnit );  // hoist initialization out of for statements; must happen before autogenerateRoutines
    353                         });
    354                         Stats::Time::TimeBlock("Generate Autogen routines", [&]() {
    355                                 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay_old
    356                         });
    357                 }
    358                 {
    359                         Stats::Heap::newPass("validate-E");
    360                         Stats::Time::BlockGuard guard("validate-E");
    361                         Stats::Time::TimeBlock("Implement Mutex Func", [&]() {
    362                                 Concurrency::implementMutexFuncs( translationUnit );
    363                         });
    364                         Stats::Time::TimeBlock("Implement Thread Start", [&]() {
    365                                 Concurrency::implementThreadStarter( translationUnit );
    366                         });
    367                         Stats::Time::TimeBlock("Compound Literal", [&]() {
    368                                 mutateAll( translationUnit, compoundliteral );
    369                         });
    370                         Stats::Time::TimeBlock("Resolve With Expressions", [&]() {
    371                                 ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables
    372                         });
    373                 }
    374                 {
    375                         Stats::Heap::newPass("validate-F");
    376                         Stats::Time::BlockGuard guard("validate-F");
    377                         Stats::Time::TimeBlock("Fix Object Type", [&]() {
    378                                 FixObjectType::fix( translationUnit );
    379                         });
    380                         Stats::Time::TimeBlock("Array Length", [&]() {
    381                                 ArrayLength::computeLength( translationUnit );
    382                         });
    383                         Stats::Time::TimeBlock("Find Special Declarations", [&]() {
    384                                 Validate::findSpecialDecls( translationUnit );
    385                         });
    386                         Stats::Time::TimeBlock("Fix Label Address", [&]() {
    387                                 mutateAll( translationUnit, labelAddrFixer );
    388                         });
    389                         Stats::Time::TimeBlock("Handle Attributes", [&]() {
    390                                 Validate::handleAttributes( translationUnit );
    391                         });
    392                 }
    393         }
    394 
    395         void validateType( Type * type, const Indexer * indexer ) {
    396                 PassVisitor<EnumAndPointerDecay_old> epc;
    397                 PassVisitor<LinkReferenceToTypes_old> lrt( indexer );
    398                 PassVisitor<ForallPointerDecay_old> fpd;
     265
     266                EliminateTypedef::eliminateTypedef( translationUnit );
     267                HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
     268                ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
     269                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
     270                acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
     271                acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes
     272                VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
     273                ReturnChecker::checkFunctionReturns( translationUnit );
     274                InitTweak::fixReturnStatements( translationUnit ); // must happen before autogen
     275                Concurrency::applyKeywords( translationUnit );
     276                acceptAll( translationUnit, fpd ); // must happen before autogenerateRoutines, after Concurrency::applyKeywords because uniqueIds must be set on declaration before resolution
     277                ControlStruct::hoistControlDecls( translationUnit );  // hoist initialization out of for statements; must happen before autogenerateRoutines
     278                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
     279                Concurrency::implementMutexFuncs( translationUnit );
     280                Concurrency::implementThreadStarter( translationUnit );
     281                mutateAll( translationUnit, compoundliteral );
     282                ArrayLength::computeLength( translationUnit );
     283                acceptAll( translationUnit, finder ); // xxx - remove this pass soon
     284                mutateAll( translationUnit, labelAddrFixer );
     285        }
     286
     287        void validateType( Type *type, const Indexer *indexer ) {
     288                PassVisitor<EnumAndPointerDecay> epc;
     289                PassVisitor<LinkReferenceToTypes> lrt( indexer );
     290                PassVisitor<ForallPointerDecay> fpd;
    399291                type->accept( epc );
    400292                type->accept( lrt );
     
    402294        }
    403295
    404 
    405         void HoistTypeDecls::handleType( Type * type ) {
    406                 // some type declarations are buried in expressions and not easy to hoist during parsing; hoist them here
    407                 AggregateDecl * aggr = nullptr;
    408                 if ( StructInstType * inst = dynamic_cast< StructInstType * >( type ) ) {
    409                         aggr = inst->baseStruct;
    410                 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( type ) ) {
    411                         aggr = inst->baseUnion;
    412                 } else if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( type ) ) {
    413                         aggr = inst->baseEnum;
    414                 }
    415                 if ( aggr && aggr->body ) {
    416                         declsToAddBefore.push_front( aggr );
    417                 }
    418         }
    419 
    420         void HoistTypeDecls::previsit( SizeofExpr * expr ) {
    421                 handleType( expr->type );
    422         }
    423 
    424         void HoistTypeDecls::previsit( AlignofExpr * expr ) {
    425                 handleType( expr->type );
    426         }
    427 
    428         void HoistTypeDecls::previsit( UntypedOffsetofExpr * expr ) {
    429                 handleType( expr->type );
    430         }
    431 
    432         void HoistTypeDecls::previsit( CompoundLiteralExpr * expr ) {
    433                 handleType( expr->result );
    434         }
    435 
    436 
    437         Type * FixQualifiedTypes::postmutate( QualifiedType * qualType ) {
    438                 Type * parent = qualType->parent;
    439                 Type * child = qualType->child;
    440                 if ( dynamic_cast< GlobalScopeType * >( qualType->parent ) ) {
    441                         // .T => lookup T at global scope
    442                         if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) {
    443                                 auto td = indexer.globalLookupType( inst->name );
    444                                 if ( ! td ) {
    445                                         SemanticError( qualType->location, toString("Use of undefined global type ", inst->name) );
    446                                 }
    447                                 auto base = td->base;
    448                                 assert( base );
    449                                 Type * ret = base->clone();
    450                                 ret->get_qualifiers() = qualType->get_qualifiers();
    451                                 return ret;
    452                         } else {
    453                                 // .T => T is not a type name
    454                                 assertf( false, "unhandled global qualified child type: %s", toCString(child) );
    455                         }
    456                 } else {
    457                         // S.T => S must be an aggregate type, find the declaration for T in S.
    458                         AggregateDecl * aggr = nullptr;
    459                         if ( StructInstType * inst = dynamic_cast< StructInstType * >( parent ) ) {
    460                                 aggr = inst->baseStruct;
    461                         } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * > ( parent ) ) {
    462                                 aggr = inst->baseUnion;
    463                         } else {
    464                                 SemanticError( qualType->location, toString("Qualified type requires an aggregate on the left, but has: ", parent) );
    465                         }
    466                         assert( aggr ); // TODO: need to handle forward declarations
    467                         for ( Declaration * member : aggr->members ) {
    468                                 if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) {
    469                                         // name on the right is a typedef
    470                                         if ( NamedTypeDecl * aggr = dynamic_cast< NamedTypeDecl * > ( member ) ) {
    471                                                 if ( aggr->name == inst->name ) {
    472                                                         assert( aggr->base );
    473                                                         Type * ret = aggr->base->clone();
    474                                                         ret->get_qualifiers() = qualType->get_qualifiers();
    475                                                         TypeSubstitution sub = parent->genericSubstitution();
    476                                                         sub.apply(ret);
    477                                                         return ret;
    478                                                 }
    479                                         }
    480                                 } else {
    481                                         // S.T - S is not an aggregate => error
    482                                         assertf( false, "unhandled qualified child type: %s", toCString(qualType) );
    483                                 }
    484                         }
    485                         // failed to find a satisfying definition of type
    486                         SemanticError( qualType->location, toString("Undefined type in qualified type: ", qualType) );
    487                 }
    488 
    489                 // ... may want to link canonical SUE definition to each forward decl so that it becomes easier to lookup?
    490         }
    491 
    492 
    493296        void HoistStruct::hoistStruct( std::list< Declaration * > &translationUnit ) {
    494297                PassVisitor<HoistStruct> hoister;
     
    496299        }
    497300
    498         bool shouldHoist( Declaration * decl ) {
     301        bool shouldHoist( Declaration *decl ) {
    499302                return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl );
    500303        }
    501304
    502         namespace {
    503                 void qualifiedName( AggregateDecl * aggr, std::ostringstream & ss ) {
    504                         if ( aggr->parent ) qualifiedName( aggr->parent, ss );
    505                         ss << "__" << aggr->name;
    506                 }
    507 
    508                 // mangle nested type names using entire parent chain
    509                 std::string qualifiedName( AggregateDecl * aggr ) {
    510                         std::ostringstream ss;
    511                         qualifiedName( aggr, ss );
    512                         return ss.str();
    513                 }
    514         }
    515 
    516305        template< typename AggDecl >
    517         void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) {
     306        void HoistStruct::handleAggregate( AggDecl *aggregateDecl ) {
    518307                if ( parentAggr ) {
    519                         aggregateDecl->parent = parentAggr;
    520                         aggregateDecl->name = qualifiedName( aggregateDecl );
    521308                        // Add elements in stack order corresponding to nesting structure.
    522309                        declsToAddBefore.push_front( aggregateDecl );
     
    529316        }
    530317
     318        void HoistStruct::previsit( EnumInstType * inst ) {
     319                if ( inst->baseEnum && inst->baseEnum->body ) {
     320                        declsToAddBefore.push_front( inst->baseEnum );
     321                }
     322        }
     323
     324        void HoistStruct::previsit( StructInstType * inst ) {
     325                if ( inst->baseStruct && inst->baseStruct->body ) {
     326                        declsToAddBefore.push_front( inst->baseStruct );
     327                }
     328        }
     329
     330        void HoistStruct::previsit( UnionInstType * inst ) {
     331                if ( inst->baseUnion && inst->baseUnion->body ) {
     332                        declsToAddBefore.push_front( inst->baseUnion );
     333                }
     334        }
     335
    531336        void HoistStruct::previsit( StaticAssertDecl * assertDecl ) {
    532337                if ( parentAggr ) {
     
    543348        }
    544349
    545         void HoistStruct::previsit( StructInstType * type ) {
    546                 // need to reset type name after expanding to qualified name
    547                 assert( type->baseStruct );
    548                 type->name = type->baseStruct->name;
    549         }
    550 
    551         void HoistStruct::previsit( UnionInstType * type ) {
    552                 assert( type->baseUnion );
    553                 type->name = type->baseUnion->name;
    554         }
    555 
    556         void HoistStruct::previsit( EnumInstType * type ) {
    557                 assert( type->baseEnum );
    558                 type->name = type->baseEnum->name;
    559         }
    560 
    561 
    562         bool isTypedef( Declaration * decl ) {
    563                 return dynamic_cast< TypedefDecl * >( decl );
    564         }
    565 
    566         void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) {
    567                 PassVisitor<EliminateTypedef> eliminator;
    568                 acceptAll( translationUnit, eliminator );
    569                 filter( translationUnit, isTypedef, true );
    570         }
    571 
    572         template< typename AggDecl >
    573         void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) {
    574                 filter( aggregateDecl->members, isTypedef, true );
    575         }
    576 
    577         void EliminateTypedef::previsit( StructDecl * aggregateDecl ) {
    578                 handleAggregate( aggregateDecl );
    579         }
    580 
    581         void EliminateTypedef::previsit( UnionDecl * aggregateDecl ) {
    582                 handleAggregate( aggregateDecl );
    583         }
    584 
    585         void EliminateTypedef::previsit( CompoundStmt * compoundStmt ) {
    586                 // remove and delete decl stmts
    587                 filter( compoundStmt->kids, [](Statement * stmt) {
    588                         if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
    589                                 if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) {
    590                                         return true;
    591                                 } // if
    592                         } // if
    593                         return false;
    594                 }, true);
    595         }
    596 
    597         void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) {
     350        void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) {
    598351                // Set the type of each member of the enumeration to be EnumConstant
    599                 for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) {
    600                         ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i );
     352                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
     353                        ObjectDecl * obj = dynamic_cast< ObjectDecl * >( *i );
    601354                        assert( obj );
    602                         obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) );
     355                        obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->get_name() ) );
    603356                } // for
    604357        }
     
    627380        }
    628381
    629         void EnumAndPointerDecay_old::previsit( FunctionType * func ) {
     382        void EnumAndPointerDecay::previsit( FunctionType *func ) {
    630383                // Fix up parameters and return types
    631384                fixFunctionList( func->parameters, func->isVarArgs, func );
     
    633386        }
    634387
    635         LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) {
     388        LinkReferenceToTypes::LinkReferenceToTypes( const Indexer *other_indexer ) {
    636389                if ( other_indexer ) {
    637390                        local_indexer = other_indexer;
     
    641394        }
    642395
    643         void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) {
    644                 const EnumDecl * st = local_indexer->lookupEnum( enumInst->name );
     396        void LinkReferenceToTypes::postvisit( EnumInstType *enumInst ) {
     397                EnumDecl *st = local_indexer->lookupEnum( enumInst->get_name() );
    645398                // it's not a semantic error if the enum is not found, just an implicit forward declaration
    646399                if ( st ) {
    647                         enumInst->baseEnum = const_cast<EnumDecl *>(st); // Just linking in the node
    648                 } // if
    649                 if ( ! st || ! st->body ) {
     400                        //assert( ! enumInst->get_baseEnum() || enumInst->get_baseEnum()->get_members().empty() || ! st->get_members().empty() );
     401                        enumInst->set_baseEnum( st );
     402                } // if
     403                if ( ! st || st->get_members().empty() ) {
    650404                        // use of forward declaration
    651                         forwardEnums[ enumInst->name ].push_back( enumInst );
     405                        forwardEnums[ enumInst->get_name() ].push_back( enumInst );
    652406                } // if
    653407        }
     
    661415        }
    662416
    663         void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) {
    664                 const StructDecl * st = local_indexer->lookupStruct( structInst->name );
     417        void LinkReferenceToTypes::postvisit( StructInstType *structInst ) {
     418                StructDecl *st = local_indexer->lookupStruct( structInst->get_name() );
    665419                // it's not a semantic error if the struct is not found, just an implicit forward declaration
    666420                if ( st ) {
    667                         structInst->baseStruct = const_cast<StructDecl *>(st); // Just linking in the node
    668                 } // if
    669                 if ( ! st || ! st->body ) {
     421                        //assert( ! structInst->get_baseStruct() || structInst->get_baseStruct()->get_members().empty() || ! st->get_members().empty() );
     422                        structInst->set_baseStruct( st );
     423                } // if
     424                if ( ! st || st->get_members().empty() ) {
    670425                        // use of forward declaration
    671                         forwardStructs[ structInst->name ].push_back( structInst );
     426                        forwardStructs[ structInst->get_name() ].push_back( structInst );
    672427                } // if
    673428                checkGenericParameters( structInst );
    674429        }
    675430
    676         void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) {
    677                 const UnionDecl * un = local_indexer->lookupUnion( unionInst->name );
     431        void LinkReferenceToTypes::postvisit( UnionInstType *unionInst ) {
     432                UnionDecl *un = local_indexer->lookupUnion( unionInst->get_name() );
    678433                // it's not a semantic error if the union is not found, just an implicit forward declaration
    679434                if ( un ) {
    680                         unionInst->baseUnion = const_cast<UnionDecl *>(un); // Just linking in the node
    681                 } // if
    682                 if ( ! un || ! un->body ) {
     435                        unionInst->set_baseUnion( un );
     436                } // if
     437                if ( ! un || un->get_members().empty() ) {
    683438                        // use of forward declaration
    684                         forwardUnions[ unionInst->name ].push_back( unionInst );
     439                        forwardUnions[ unionInst->get_name() ].push_back( unionInst );
    685440                } // if
    686441                checkGenericParameters( unionInst );
    687         }
    688 
    689         void LinkReferenceToTypes_old::previsit( QualifiedType * ) {
    690                 visit_children = false;
    691         }
    692 
    693         void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) {
    694                 // linking only makes sense for the 'oldest ancestor' of the qualified type
    695                 qualType->parent->accept( * visitor );
    696442        }
    697443
     
    704450                        DeclarationWithType * dwt2 = dynamic_cast<DeclarationWithType *>( d2 );
    705451                        if ( dwt1 && dwt2 ) {
    706                                 if ( dwt1->name == dwt2->name && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
     452                                if ( dwt1->get_name() == dwt2->get_name() && ResolvExpr::typesCompatible( dwt1->get_type(), dwt2->get_type(), SymTab::Indexer() ) ) {
    707453                                        // std::cerr << "=========== equal:" << std::endl;
    708454                                        // std::cerr << "d1: " << d1 << std::endl;
     
    729475        template< typename Iterator >
    730476        void expandAssertions( TraitInstType * inst, Iterator out ) {
    731                 assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toCString( inst ) );
     477                assertf( inst->baseTrait, "Trait instance not linked to base trait: %s", toString( inst ).c_str() );
    732478                std::list< DeclarationWithType * > asserts;
    733479                for ( Declaration * decl : inst->baseTrait->members ) {
     
    738484        }
    739485
    740         void LinkReferenceToTypes_old::postvisit( TraitDecl * traitDecl ) {
     486        void LinkReferenceToTypes::postvisit( TraitDecl * traitDecl ) {
    741487                if ( traitDecl->name == "sized" ) {
    742488                        // "sized" is a special trait - flick the sized status on for the type variable
     
    760506        }
    761507
    762         void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) {
     508        void LinkReferenceToTypes::postvisit( TraitInstType * traitInst ) {
    763509                // handle other traits
    764                 const TraitDecl * traitDecl = local_indexer->lookupTrait( traitInst->name );
     510                TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );
    765511                if ( ! traitDecl ) {
    766512                        SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name );
    767513                } // if
    768                 if ( traitDecl->parameters.size() != traitInst->parameters.size() ) {
     514                if ( traitDecl->get_parameters().size() != traitInst->get_parameters().size() ) {
    769515                        SemanticError( traitInst, "incorrect number of trait parameters: " );
    770516                } // if
    771                 traitInst->baseTrait = const_cast<TraitDecl *>(traitDecl); // Just linking in the node
     517                traitInst->baseTrait = traitDecl;
    772518
    773519                // need to carry over the 'sized' status of each decl in the instance
    774                 for ( auto p : group_iterate( traitDecl->parameters, traitInst->parameters ) ) {
     520                for ( auto p : group_iterate( traitDecl->get_parameters(), traitInst->get_parameters() ) ) {
    775521                        TypeExpr * expr = dynamic_cast< TypeExpr * >( std::get<1>(p) );
    776522                        if ( ! expr ) {
     
    779525                        if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( expr->get_type() ) ) {
    780526                                TypeDecl * formalDecl = std::get<0>(p);
    781                                 TypeDecl * instDecl = inst->baseType;
     527                                TypeDecl * instDecl = inst->get_baseType();
    782528                                if ( formalDecl->get_sized() ) instDecl->set_sized( true );
    783529                        }
     
    786532        }
    787533
    788         void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) {
     534        void LinkReferenceToTypes::postvisit( EnumDecl *enumDecl ) {
    789535                // visit enum members first so that the types of self-referencing members are updated properly
    790                 if ( enumDecl->body ) {
    791                         ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->name );
     536                if ( ! enumDecl->get_members().empty() ) {
     537                        ForwardEnumsType::iterator fwds = forwardEnums.find( enumDecl->get_name() );
    792538                        if ( fwds != forwardEnums.end() ) {
    793539                                for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    794                                         (* inst)->baseEnum = enumDecl;
     540                                        (*inst )->set_baseEnum( enumDecl );
    795541                                } // for
    796542                                forwardEnums.erase( fwds );
    797543                        } // if
    798 
    799                         for ( Declaration * member : enumDecl->members ) {
    800                                 ObjectDecl * field = strict_dynamic_cast<ObjectDecl *>( member );
    801                                 if ( field->init ) {
    802                                         // need to resolve enumerator initializers early so that other passes that determine if an expression is constexpr have the appropriate information.
    803                                         SingleInit * init = strict_dynamic_cast<SingleInit *>( field->init );
    804                                         ResolvExpr::findSingleExpression( init->value, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), indexer );
    805                                 }
    806                         }
    807                 } // if
    808         }
    809 
    810         void LinkReferenceToTypes_old::renameGenericParams( std::list< TypeDecl * > & params ) {
     544                } // if
     545        }
     546
     547        void LinkReferenceToTypes::renameGenericParams( std::list< TypeDecl * > & params ) {
    811548                // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g.
    812549                //   forall(otype T)
     
    826563        }
    827564
    828         void LinkReferenceToTypes_old::previsit( StructDecl * structDecl ) {
     565        void LinkReferenceToTypes::previsit( StructDecl * structDecl ) {
    829566                renameGenericParams( structDecl->parameters );
    830567        }
    831568
    832         void LinkReferenceToTypes_old::previsit( UnionDecl * unionDecl ) {
     569        void LinkReferenceToTypes::previsit( UnionDecl * unionDecl ) {
    833570                renameGenericParams( unionDecl->parameters );
    834571        }
    835572
    836         void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) {
     573        void LinkReferenceToTypes::postvisit( StructDecl *structDecl ) {
    837574                // visit struct members first so that the types of self-referencing members are updated properly
    838575                // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults)
    839                 if ( structDecl->body ) {
    840                         ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->name );
     576                if ( ! structDecl->get_members().empty() ) {
     577                        ForwardStructsType::iterator fwds = forwardStructs.find( structDecl->get_name() );
    841578                        if ( fwds != forwardStructs.end() ) {
    842579                                for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    843                                         (* inst)->baseStruct = structDecl;
     580                                        (*inst )->set_baseStruct( structDecl );
    844581                                } // for
    845582                                forwardStructs.erase( fwds );
     
    848585        }
    849586
    850         void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) {
    851                 if ( unionDecl->body ) {
    852                         ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name );
     587        void LinkReferenceToTypes::postvisit( UnionDecl *unionDecl ) {
     588                if ( ! unionDecl->get_members().empty() ) {
     589                        ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->get_name() );
    853590                        if ( fwds != forwardUnions.end() ) {
    854591                                for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) {
    855                                         (* inst)->baseUnion = unionDecl;
     592                                        (*inst )->set_baseUnion( unionDecl );
    856593                                } // for
    857594                                forwardUnions.erase( fwds );
     
    860597        }
    861598
    862         void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) {
     599        void LinkReferenceToTypes::postvisit( TypeInstType *typeInst ) {
    863600                // ensure generic parameter instances are renamed like the base type
    864601                if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name;
    865                 if ( const NamedTypeDecl * namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) {
    866                         if ( const TypeDecl * typeDecl = dynamic_cast< const TypeDecl * >( namedTypeDecl ) ) {
    867                                 typeInst->set_isFtype( typeDecl->kind == TypeDecl::Ftype );
     602                if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->get_name() ) ) {
     603                        if ( TypeDecl *typeDecl = dynamic_cast< TypeDecl * >( namedTypeDecl ) ) {
     604                                typeInst->set_isFtype( typeDecl->get_kind() == TypeDecl::Ftype );
    868605                        } // if
    869606                } // if
     
    877614                        // expand trait instances into their members
    878615                        for ( DeclarationWithType * assertion : asserts ) {
    879                                 if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
     616                                if ( TraitInstType *traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {
    880617                                        // expand trait instance into all of its members
    881618                                        expandAssertions( traitInst, back_inserter( type->assertions ) );
     
    897634        }
    898635
    899         void ForallPointerDecay_old::previsit( ObjectDecl * object ) {
     636        void ForallPointerDecay::previsit( ObjectDecl *object ) {
    900637                // ensure that operator names only apply to functions or function pointers
    901638                if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) {
     
    905642        }
    906643
    907         void ForallPointerDecay_old::previsit( FunctionDecl * func ) {
     644        void ForallPointerDecay::previsit( FunctionDecl *func ) {
    908645                func->fixUniqueId();
    909646        }
    910647
    911         void ForallPointerDecay_old::previsit( FunctionType * ftype ) {
     648        void ForallPointerDecay::previsit( FunctionType * ftype ) {
    912649                forallFixer( ftype->forall, ftype );
    913650        }
    914651
    915         void ForallPointerDecay_old::previsit( StructDecl * aggrDecl ) {
     652        void ForallPointerDecay::previsit( StructDecl * aggrDecl ) {
    916653                forallFixer( aggrDecl->parameters, aggrDecl );
    917654        }
    918655
    919         void ForallPointerDecay_old::previsit( UnionDecl * aggrDecl ) {
     656        void ForallPointerDecay::previsit( UnionDecl * aggrDecl ) {
    920657                forallFixer( aggrDecl->parameters, aggrDecl );
    921658        }
     
    942679
    943680
    944         void ReplaceTypedef::replaceTypedef( std::list< Declaration * > &translationUnit ) {
    945                 PassVisitor<ReplaceTypedef> eliminator;
     681        bool isTypedef( Declaration *decl ) {
     682                return dynamic_cast< TypedefDecl * >( decl );
     683        }
     684
     685        void EliminateTypedef::eliminateTypedef( std::list< Declaration * > &translationUnit ) {
     686                PassVisitor<EliminateTypedef> eliminator;
    946687                mutateAll( translationUnit, eliminator );
    947688                if ( eliminator.pass.typedefNames.count( "size_t" ) ) {
    948689                        // grab and remember declaration of size_t
    949                         Validate::SizeType = eliminator.pass.typedefNames["size_t"].first->base->clone();
     690                        SizeType = eliminator.pass.typedefNames["size_t"].first->get_base()->clone();
    950691                } else {
    951692                        // xxx - missing global typedef for size_t - default to long unsigned int, even though that may be wrong
    952693                        // eventually should have a warning for this case.
    953                         Validate::SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    954                 }
    955         }
    956 
    957         void ReplaceTypedef::premutate( QualifiedType * ) {
    958                 visit_children = false;
    959         }
    960 
    961         Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) {
    962                 // replacing typedefs only makes sense for the 'oldest ancestor' of the qualified type
    963                 qualType->parent = qualType->parent->acceptMutator( * visitor );
    964                 return qualType;
    965         }
    966 
    967         Type * ReplaceTypedef::postmutate( TypeInstType * typeInst ) {
     694                        SizeType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
     695                }
     696                filter( translationUnit, isTypedef, true );
     697        }
     698
     699        Type * EliminateTypedef::postmutate( TypeInstType * typeInst ) {
    968700                // instances of typedef types will come here. If it is an instance
    969701                // of a typdef type, link the instance to its actual type.
    970                 TypedefMap::const_iterator def = typedefNames.find( typeInst->name );
     702                TypedefMap::const_iterator def = typedefNames.find( typeInst->get_name() );
    971703                if ( def != typedefNames.end() ) {
    972                         Type * ret = def->second.first->base->clone();
    973                         ret->location = typeInst->location;
     704                        Type *ret = def->second.first->base->clone();
    974705                        ret->get_qualifiers() |= typeInst->get_qualifiers();
    975706                        // attributes are not carried over from typedef to function parameters/return values
     
    982713                        // place instance parameters on the typedef'd type
    983714                        if ( ! typeInst->parameters.empty() ) {
    984                                 ReferenceToType * rtt = dynamic_cast<ReferenceToType *>(ret);
     715                                ReferenceToType *rtt = dynamic_cast<ReferenceToType*>(ret);
    985716                                if ( ! rtt ) {
    986717                                        SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name );
    987718                                }
    988                                 rtt->parameters.clear();
     719                                rtt->get_parameters().clear();
    989720                                cloneAll( typeInst->parameters, rtt->parameters );
    990                                 mutateAll( rtt->parameters, * visitor );  // recursively fix typedefs on parameters
     721                                mutateAll( rtt->parameters, *visitor );  // recursively fix typedefs on parameters
    991722                        } // if
    992723                        delete typeInst;
    993724                        return ret;
    994725                } else {
    995                         TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->name );
    996                         if ( base == typedeclNames.end() ) {
    997                                 SemanticError( typeInst->location, toString("Use of undefined type ", typeInst->name) );
    998                         }
     726                        TypeDeclMap::const_iterator base = typedeclNames.find( typeInst->get_name() );
     727                        assertf( base != typedeclNames.end(), "Cannot find typedecl name %s", typeInst->name.c_str() );
    999728                        typeInst->set_baseType( base->second );
    1000                         return typeInst;
    1001                 } // if
    1002                 assert( false );
     729                } // if
     730                return typeInst;
    1003731        }
    1004732
     
    1017745        }
    1018746
    1019         Declaration * ReplaceTypedef::postmutate( TypedefDecl * tyDecl ) {
    1020                 if ( typedefNames.count( tyDecl->name ) == 1 && typedefNames[ tyDecl->name ].second == scopeLevel ) {
     747        Declaration *EliminateTypedef::postmutate( TypedefDecl * tyDecl ) {
     748                if ( typedefNames.count( tyDecl->get_name() ) == 1 && typedefNames[ tyDecl->get_name() ].second == scopeLevel ) {
    1021749                        // typedef to the same name from the same scope
    1022750                        // must be from the same type
    1023751
    1024                         Type * t1 = tyDecl->base;
    1025                         Type * t2 = typedefNames[ tyDecl->name ].first->base;
     752                        Type * t1 = tyDecl->get_base();
     753                        Type * t2 = typedefNames[ tyDecl->get_name() ].first->get_base();
    1026754                        if ( ! ResolvExpr::typesCompatible( t1, t2, Indexer() ) ) {
    1027755                                SemanticError( tyDecl->location, "Cannot redefine typedef: " + tyDecl->name );
     
    1035763                        }
    1036764                } else {
    1037                         typedefNames[ tyDecl->name ] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel );
     765                        typedefNames[ tyDecl->get_name() ] = std::make_pair( TypedefDeclPtr( tyDecl ), scopeLevel );
    1038766                } // if
    1039767
     
    1043771                //    struct screen;
    1044772                // because the expansion of the typedef is:
    1045                 //    void rtn( SCREEN * p ) => void rtn( struct screen * p )
     773                //    void rtn( SCREEN *p ) => void rtn( struct screen *p )
    1046774                // hence the type-name "screen" must be defined.
    1047775                // Note, qualifiers on the typedef are superfluous for the forward declaration.
    1048776
    1049                 Type * designatorType = tyDecl->base->stripDeclarator();
    1050                 if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
    1051                         declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) );
    1052                 } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
    1053                         declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) );
    1054                 } else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
    1055                         declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) );
    1056                 } // if
    1057                 return tyDecl->clone();
    1058         }
    1059 
    1060         void ReplaceTypedef::premutate( TypeDecl * typeDecl ) {
    1061                 TypedefMap::iterator i = typedefNames.find( typeDecl->name );
     777                Type *designatorType = tyDecl->get_base()->stripDeclarator();
     778                if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
     779                        return new StructDecl( aggDecl->get_name(), DeclarationNode::Struct, noAttributes, tyDecl->get_linkage() );
     780                } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
     781                        return new UnionDecl( aggDecl->get_name(), noAttributes, tyDecl->get_linkage() );
     782                } else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
     783                        return new EnumDecl( enumDecl->get_name(), noAttributes, tyDecl->get_linkage() );
     784                } else {
     785                        return tyDecl->clone();
     786                } // if
     787        }
     788
     789        void EliminateTypedef::premutate( TypeDecl * typeDecl ) {
     790                TypedefMap::iterator i = typedefNames.find( typeDecl->get_name() );
    1062791                if ( i != typedefNames.end() ) {
    1063792                        typedefNames.erase( i ) ;
    1064793                } // if
    1065794
    1066                 typedeclNames.insert( typeDecl->name, typeDecl );
    1067         }
    1068 
    1069         void ReplaceTypedef::premutate( FunctionDecl * ) {
     795                typedeclNames[ typeDecl->get_name() ] = typeDecl;
     796        }
     797
     798        void EliminateTypedef::premutate( FunctionDecl * ) {
    1070799                GuardScope( typedefNames );
    1071                 GuardScope( typedeclNames );
    1072         }
    1073 
    1074         void ReplaceTypedef::premutate( ObjectDecl * ) {
     800        }
     801
     802        void EliminateTypedef::premutate( ObjectDecl * ) {
    1075803                GuardScope( typedefNames );
    1076                 GuardScope( typedeclNames );
    1077         }
    1078 
    1079         DeclarationWithType * ReplaceTypedef::postmutate( ObjectDecl * objDecl ) {
    1080                 if ( FunctionType * funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type?
     804        }
     805
     806        DeclarationWithType *EliminateTypedef::postmutate( ObjectDecl * objDecl ) {
     807                if ( FunctionType *funtype = dynamic_cast<FunctionType *>( objDecl->get_type() ) ) { // function type?
    1081808                        // replace the current object declaration with a function declaration
    1082                         FunctionDecl * newDecl = new FunctionDecl( objDecl->name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() );
    1083                         objDecl->attributes.clear();
     809                        FunctionDecl * newDecl = new FunctionDecl( objDecl->get_name(), objDecl->get_storageClasses(), objDecl->get_linkage(), funtype, 0, objDecl->get_attributes(), objDecl->get_funcSpec() );
     810                        objDecl->get_attributes().clear();
    1084811                        objDecl->set_type( nullptr );
    1085812                        delete objDecl;
     
    1089816        }
    1090817
    1091         void ReplaceTypedef::premutate( CastExpr * ) {
     818        void EliminateTypedef::premutate( CastExpr * ) {
    1092819                GuardScope( typedefNames );
    1093                 GuardScope( typedeclNames );
    1094         }
    1095 
    1096         void ReplaceTypedef::premutate( CompoundStmt * ) {
     820        }
     821
     822        void EliminateTypedef::premutate( CompoundStmt * ) {
    1097823                GuardScope( typedefNames );
    1098                 GuardScope( typedeclNames );
    1099824                scopeLevel += 1;
    1100825                GuardAction( [this](){ scopeLevel -= 1; } );
    1101826        }
    1102827
     828        CompoundStmt *EliminateTypedef::postmutate( CompoundStmt * compoundStmt ) {
     829                // remove and delete decl stmts
     830                filter( compoundStmt->kids, [](Statement * stmt) {
     831                        if ( DeclStmt *declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {
     832                                if ( dynamic_cast< TypedefDecl * >( declStmt->get_decl() ) ) {
     833                                        return true;
     834                                } // if
     835                        } // if
     836                        return false;
     837                }, true);
     838                return compoundStmt;
     839        }
     840
     841        // there may be typedefs nested within aggregates. in order for everything to work properly, these should be removed
     842        // as well
    1103843        template<typename AggDecl>
    1104         void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
     844        AggDecl *EliminateTypedef::handleAggregate( AggDecl * aggDecl ) {
     845                filter( aggDecl->members, isTypedef, true );
     846                return aggDecl;
     847        }
     848
     849        template<typename AggDecl>
     850        void EliminateTypedef::addImplicitTypedef( AggDecl * aggDecl ) {
    1105851                if ( typedefNames.count( aggDecl->get_name() ) == 0 ) {
    1106                         Type * type = nullptr;
     852                        Type *type = nullptr;
    1107853                        if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( aggDecl ) ) {
    1108854                                type = new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() );
     
    1114860                        TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type, aggDecl->get_linkage() ) );
    1115861                        typedefNames[ aggDecl->get_name() ] = std::make_pair( std::move( tyDecl ), scopeLevel );
    1116                         // add the implicit typedef to the AST
    1117                         declsToAddBefore.push_back( new TypedefDecl( aggDecl->get_name(), aggDecl->location, Type::StorageClasses(), type->clone(), aggDecl->get_linkage() ) );
    1118                 } // if
    1119         }
    1120 
    1121         template< typename AggDecl >
    1122         void ReplaceTypedef::handleAggregate( AggDecl * aggr ) {
    1123                 SemanticErrorException errors;
    1124 
    1125                 ValueGuard< std::list<Declaration * > > oldBeforeDecls( declsToAddBefore );
    1126                 ValueGuard< std::list<Declaration * > > oldAfterDecls ( declsToAddAfter  );
    1127                 declsToAddBefore.clear();
    1128                 declsToAddAfter.clear();
    1129 
    1130                 GuardScope( typedefNames );
    1131                 GuardScope( typedeclNames );
    1132                 mutateAll( aggr->parameters, * visitor );
    1133 
    1134                 // unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body.
    1135                 for ( std::list< Declaration * >::iterator i = aggr->members.begin(); i != aggr->members.end(); ++i ) {
    1136                         if ( !declsToAddAfter.empty() ) { aggr->members.splice( i, declsToAddAfter ); }
    1137 
    1138                         try {
    1139                                 * i = maybeMutate( * i, * visitor );
    1140                         } catch ( SemanticErrorException &e ) {
    1141                                 errors.append( e );
    1142                         }
    1143 
    1144                         if ( !declsToAddBefore.empty() ) { aggr->members.splice( i, declsToAddBefore ); }
    1145                 }
    1146 
    1147                 if ( !declsToAddAfter.empty() ) { aggr->members.splice( aggr->members.end(), declsToAddAfter ); }
    1148                 if ( !errors.isEmpty() ) { throw errors; }
    1149         }
    1150 
    1151         void ReplaceTypedef::premutate( StructDecl * structDecl ) {
    1152                 visit_children = false;
     862                } // if
     863        }
     864
     865        void EliminateTypedef::premutate( StructDecl * structDecl ) {
    1153866                addImplicitTypedef( structDecl );
    1154                 handleAggregate( structDecl );
    1155         }
    1156 
    1157         void ReplaceTypedef::premutate( UnionDecl * unionDecl ) {
    1158                 visit_children = false;
     867        }
     868
     869
     870        Declaration *EliminateTypedef::postmutate( StructDecl * structDecl ) {
     871                return handleAggregate( structDecl );
     872        }
     873
     874        void EliminateTypedef::premutate( UnionDecl * unionDecl ) {
    1159875                addImplicitTypedef( unionDecl );
    1160                 handleAggregate( unionDecl );
    1161         }
    1162 
    1163         void ReplaceTypedef::premutate( EnumDecl * enumDecl ) {
     876        }
     877
     878        Declaration *EliminateTypedef::postmutate( UnionDecl * unionDecl ) {
     879                return handleAggregate( unionDecl );
     880        }
     881
     882        void EliminateTypedef::premutate( EnumDecl * enumDecl ) {
    1164883                addImplicitTypedef( enumDecl );
    1165884        }
    1166885
    1167         void ReplaceTypedef::premutate( FunctionType * ) {
     886        Declaration *EliminateTypedef::postmutate( EnumDecl * enumDecl ) {
     887                return handleAggregate( enumDecl );
     888        }
     889
     890        Declaration *EliminateTypedef::postmutate( TraitDecl * traitDecl ) {
     891                return handleAggregate( traitDecl );
     892        }
     893
     894        void EliminateTypedef::premutate( FunctionType * ) {
    1168895                GuardValue( inFunctionType );
    1169896                inFunctionType = true;
    1170         }
    1171 
    1172         void ReplaceTypedef::premutate( TraitDecl * ) {
    1173                 GuardScope( typedefNames );
    1174                 GuardScope( typedeclNames);
    1175897        }
    1176898
     
    1217939                        for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) {
    1218940                                if ( i < args.size() ) {
    1219                                         TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) );
    1220                                         sub.add( (* paramIter)->get_name(), expr->get_type()->clone() );
     941                                        TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( *std::next( args.begin(), i ) );
     942                                        sub.add( (*paramIter)->get_name(), expr->get_type()->clone() );
    1221943                                } else if ( i == args.size() ) {
    1222                                         Type * defaultType = (* paramIter)->get_init();
     944                                        Type * defaultType = (*paramIter)->get_init();
    1223945                                        if ( defaultType ) {
    1224946                                                args.push_back( new TypeExpr( defaultType->clone() ) );
    1225                                                 sub.add( (* paramIter)->get_name(), defaultType->clone() );
     947                                                sub.add( (*paramIter)->get_name(), defaultType->clone() );
    1226948                                        }
    1227949                                }
     
    1242964        }
    1243965
    1244         void CompoundLiteral::premutate( ObjectDecl * objectDecl ) {
     966        void CompoundLiteral::premutate( ObjectDecl *objectDecl ) {
    1245967                storageClasses = objectDecl->get_storageClasses();
    1246968        }
    1247969
    1248         Expression * CompoundLiteral::postmutate( CompoundLiteralExpr * compLitExpr ) {
     970        Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {
    1249971                // transform [storage_class] ... (struct S){ 3, ... };
    1250972                // into [storage_class] struct S temp =  { 3, ... };
    1251973                static UniqueName indexName( "_compLit" );
    1252974
    1253                 ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
     975                ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
    1254976                compLitExpr->set_result( nullptr );
    1255977                compLitExpr->set_initializer( nullptr );
     
    12891011                        TupleType * tupleType = strict_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) );
    12901012                        // ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false.
    1291                         ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) );
     1013                        ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer*>(), noDesignators, false ) );
    12921014                        deleteAll( retVals );
    12931015                        retVals.clear();
     
    12961018        }
    12971019
    1298         void FixObjectType::fix( std::list< Declaration * > & translationUnit ) {
    1299                 PassVisitor<FixObjectType> fixer;
    1300                 acceptAll( translationUnit, fixer );
    1301         }
    1302 
    1303         void FixObjectType::previsit( ObjectDecl * objDecl ) {
    1304                 Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer );
    1305                 objDecl->set_type( new_type );
    1306         }
    1307 
    1308         void FixObjectType::previsit( FunctionDecl * funcDecl ) {
    1309                 Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );
    1310                 funcDecl->set_type( new_type );
    1311         }
    1312 
    1313         void FixObjectType::previsit( TypeDecl * typeDecl ) {
    1314                 if ( typeDecl->get_base() ) {
    1315                         Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );
    1316                         typeDecl->set_base( new_type );
    1317                 } // if
    1318         }
    1319 
    13201020        void ArrayLength::computeLength( std::list< Declaration * > & translationUnit ) {
    13211021                PassVisitor<ArrayLength> len;
     
    13241024
    13251025        void ArrayLength::previsit( ObjectDecl * objDecl ) {
    1326                 if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->type ) ) {
    1327                         if ( at->dimension ) return;
    1328                         if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->init ) ) {
    1329                                 at->dimension = new ConstantExpr( Constant::from_ulong( init->initializers.size() ) );
    1330                         }
    1331                 }
    1332         }
    1333 
    1334         void ArrayLength::previsit( ArrayType * type ) {
    1335                 if ( type->dimension ) {
    1336                         // need to resolve array dimensions early so that constructor code can correctly determine
    1337                         // if a type is a VLA (and hence whether its elements need to be constructed)
    1338                         ResolvExpr::findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer );
    1339 
    1340                         // must re-evaluate whether a type is a VLA, now that more information is available
    1341                         // (e.g. the dimension may have been an enumerator, which was unknown prior to this step)
    1342                         type->isVarLen = ! InitTweak::isConstExpr( type->dimension );
     1026                if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
     1027                        if ( at->get_dimension() ) return;
     1028                        if ( ListInit * init = dynamic_cast< ListInit * >( objDecl->get_init() ) ) {
     1029                                at->set_dimension( new ConstantExpr( Constant::from_ulong( init->get_initializers().size() ) ) );
     1030                        }
    13431031                }
    13441032        }
     
    13741062        }
    13751063
    1376 namespace {
    1377         /// Replaces enum types by int, and function/array types in function parameter and return
    1378         /// lists by appropriate pointers
    1379         struct EnumAndPointerDecay_new {
    1380                 const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) {
    1381                         // set the type of each member of the enumeration to be EnumConstant
    1382                         for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) {
    1383                                 // build new version of object with EnumConstant
    1384                                 ast::ptr< ast::ObjectDecl > obj =
    1385                                         enumDecl->members[i].strict_as< ast::ObjectDecl >();
    1386                                 obj.get_and_mutate()->type =
    1387                                         new ast::EnumInstType{ enumDecl->name, ast::CV::Const };
    1388 
    1389                                 // set into decl
    1390                                 ast::EnumDecl * mut = mutate( enumDecl );
    1391                                 mut->members[i] = obj.get();
    1392                                 enumDecl = mut;
    1393                         }
    1394                         return enumDecl;
    1395                 }
    1396 
    1397                 static const ast::FunctionType * fixFunctionList(
    1398                         const ast::FunctionType * func,
    1399                         std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field,
    1400                         ast::ArgumentFlag isVarArgs = ast::FixedArgs
    1401                 ) {
    1402                         const auto & dwts = func->* field;
    1403                         unsigned nvals = dwts.size();
    1404                         bool hasVoid = false;
    1405                         for ( unsigned i = 0; i < nvals; ++i ) {
    1406                                 func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) );
    1407                         }
    1408 
    1409                         // the only case in which "void" is valid is where it is the only one in the list
    1410                         if ( hasVoid && ( nvals > 1 || isVarArgs ) ) {
    1411                                 SemanticError(
    1412                                         dwts.front()->location, func, "invalid type void in function type" );
    1413                         }
    1414 
    1415                         // one void is the only thing in the list, remove it
    1416                         if ( hasVoid ) {
    1417                                 func = ast::mutate_field(
    1418                                         func, field, std::vector< ast::ptr< ast::DeclWithType > >{} );
    1419                         }
    1420 
    1421                         return func;
    1422                 }
    1423 
    1424                 const ast::FunctionType * previsit( const ast::FunctionType * func ) {
    1425                         func = fixFunctionList( func, &ast::FunctionType::params, func->isVarArgs );
    1426                         return fixFunctionList( func, &ast::FunctionType::returns );
    1427                 }
    1428         };
    1429 
    1430         /// expand assertions from a trait instance, performing appropriate type variable substitutions
    1431         void expandAssertions(
    1432                 const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out
    1433         ) {
    1434                 assertf( inst->base, "Trait instance not linked to base trait: %s", toCString( inst ) );
    1435 
    1436                 // build list of trait members, substituting trait decl parameters for instance parameters
    1437                 ast::TypeSubstitution sub{
    1438                         inst->base->params.begin(), inst->base->params.end(), inst->params.begin() };
    1439                 // deliberately take ast::ptr by-value to ensure this does not mutate inst->base
    1440                 for ( ast::ptr< ast::Decl > decl : inst->base->members ) {
    1441                         auto member = decl.strict_as< ast::DeclWithType >();
    1442                         sub.apply( member );
    1443                         out.emplace_back( member );
    1444                 }
    1445         }
    1446 
    1447         /// Associates forward declarations of aggregates with their definitions
    1448         class LinkReferenceToTypes_new final
    1449         : public ast::WithSymbolTable, public ast::WithGuards, public
    1450           ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting {
    1451 
    1452                 // these maps of uses of forward declarations of types need to have the actual type
    1453                 // declaration switched in * after * they have been traversed. To enable this in the
    1454                 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it
    1455                 // before it is placed in the map, properly updating its parents in the usual traversal,
    1456                 // then can have the actual mutation applied later
    1457                 using ForwardEnumsType = std::unordered_multimap< std::string, ast::EnumInstType * >;
    1458                 using ForwardStructsType = std::unordered_multimap< std::string, ast::StructInstType * >;
    1459                 using ForwardUnionsType = std::unordered_multimap< std::string, ast::UnionInstType * >;
    1460 
    1461                 const CodeLocation & location;
    1462                 const ast::SymbolTable * localSymtab;
    1463 
    1464                 ForwardEnumsType forwardEnums;
    1465                 ForwardStructsType forwardStructs;
    1466                 ForwardUnionsType forwardUnions;
    1467 
    1468                 /// true if currently in a generic type body, so that type parameter instances can be
    1469                 /// renamed appropriately
    1470                 bool inGeneric = false;
    1471 
    1472         public:
    1473                 /// contstruct using running symbol table
    1474                 LinkReferenceToTypes_new( const CodeLocation & loc )
    1475                 : location( loc ), localSymtab( &symtab ) {}
    1476 
    1477                 /// construct using provided symbol table
    1478                 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms )
    1479                 : location( loc ), localSymtab( &syms ) {}
    1480 
    1481                 const ast::Type * postvisit( const ast::TypeInstType * typeInst ) {
    1482                         // ensure generic parameter instances are renamed like the base type
    1483                         if ( inGeneric && typeInst->base ) {
    1484                                 typeInst = ast::mutate_field(
    1485                                         typeInst, &ast::TypeInstType::name, typeInst->base->name );
    1486                         }
    1487 
    1488                         if (
    1489                                 auto typeDecl = dynamic_cast< const ast::TypeDecl * >(
    1490                                         localSymtab->lookupType( typeInst->name ) )
    1491                         ) {
    1492                                 typeInst = ast::mutate_field( typeInst, &ast::TypeInstType::kind, typeDecl->kind );
    1493                         }
    1494 
    1495                         return typeInst;
    1496                 }
    1497 
    1498                 const ast::Type * postvisit( const ast::EnumInstType * inst ) {
    1499                         const ast::EnumDecl * decl = localSymtab->lookupEnum( inst->name );
    1500                         // not a semantic error if the enum is not found, just an implicit forward declaration
    1501                         if ( decl ) {
    1502                                 inst = ast::mutate_field( inst, &ast::EnumInstType::base, decl );
    1503                         }
    1504                         if ( ! decl || ! decl->body ) {
    1505                                 // forward declaration
    1506                                 auto mut = mutate( inst );
    1507                                 forwardEnums.emplace( inst->name, mut );
    1508                                 inst = mut;
    1509                         }
    1510                         return inst;
    1511                 }
    1512 
    1513                 void checkGenericParameters( const ast::ReferenceToType * inst ) {
    1514                         for ( const ast::Expr * param : inst->params ) {
    1515                                 if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) {
    1516                                         SemanticError(
    1517                                                 location, inst, "Expression parameters for generic types are currently "
    1518                                                 "unsupported: " );
     1064        void FindSpecialDeclarations::previsit( FunctionDecl * funcDecl ) {
     1065                if ( ! dereferenceOperator ) {
     1066                        if ( funcDecl->get_name() == "*?" && funcDecl->get_linkage() == LinkageSpec::Intrinsic ) {
     1067                                FunctionType * ftype = funcDecl->get_functionType();
     1068                                if ( ftype->get_parameters().size() == 1 && ftype->get_parameters().front()->get_type()->get_qualifiers() == Type::Qualifiers() ) {
     1069                                        dereferenceOperator = funcDecl;
    15191070                                }
    15201071                        }
    15211072                }
    1522 
    1523                 const ast::StructInstType * postvisit( const ast::StructInstType * inst ) {
    1524                         const ast::StructDecl * decl = localSymtab->lookupStruct( inst->name );
    1525                         // not a semantic error if the struct is not found, just an implicit forward declaration
    1526                         if ( decl ) {
    1527                                 inst = ast::mutate_field( inst, &ast::StructInstType::base, decl );
    1528                         }
    1529                         if ( ! decl || ! decl->body ) {
    1530                                 // forward declaration
    1531                                 auto mut = mutate( inst );
    1532                                 forwardStructs.emplace( inst->name, mut );
    1533                                 inst = mut;
    1534                         }
    1535                         checkGenericParameters( inst );
    1536                         return inst;
    1537                 }
    1538 
    1539                 const ast::UnionInstType * postvisit( const ast::UnionInstType * inst ) {
    1540                         const ast::UnionDecl * decl = localSymtab->lookupUnion( inst->name );
    1541                         // not a semantic error if the struct is not found, just an implicit forward declaration
    1542                         if ( decl ) {
    1543                                 inst = ast::mutate_field( inst, &ast::UnionInstType::base, decl );
    1544                         }
    1545                         if ( ! decl || ! decl->body ) {
    1546                                 // forward declaration
    1547                                 auto mut = mutate( inst );
    1548                                 forwardUnions.emplace( inst->name, mut );
    1549                                 inst = mut;
    1550                         }
    1551                         checkGenericParameters( inst );
    1552                         return inst;
    1553                 }
    1554 
    1555                 const ast::Type * postvisit( const ast::TraitInstType * traitInst ) {
    1556                         // handle other traits
    1557                         const ast::TraitDecl * traitDecl = localSymtab->lookupTrait( traitInst->name );
    1558                         if ( ! traitDecl )       {
    1559                                 SemanticError( location, "use of undeclared trait " + traitInst->name );
    1560                         }
    1561                         if ( traitDecl->params.size() != traitInst->params.size() ) {
    1562                                 SemanticError( location, traitInst, "incorrect number of trait parameters: " );
    1563                         }
    1564                         traitInst = ast::mutate_field( traitInst, &ast::TraitInstType::base, traitDecl );
    1565 
    1566                         // need to carry over the "sized" status of each decl in the instance
    1567                         for ( unsigned i = 0; i < traitDecl->params.size(); ++i ) {
    1568                                 auto expr = traitInst->params[i].as< ast::TypeExpr >();
    1569                                 if ( ! expr ) {
    1570                                         SemanticError(
    1571                                                 traitInst->params[i].get(), "Expression parameters for trait instances "
    1572                                                 "are currently unsupported: " );
    1573                                 }
    1574 
    1575                                 if ( auto inst = expr->type.as< ast::TypeInstType >() ) {
    1576                                         if ( traitDecl->params[i]->sized && ! inst->base->sized ) {
    1577                                                 // traitInst = ast::mutate_field_index(
    1578                                                 //      traitInst, &ast::TraitInstType::params, i,
    1579                                                 //      ...
    1580                                                 // );
    1581                                                 ast::TraitInstType * mut = ast::mutate( traitInst );
    1582                                                 ast::chain_mutate( mut->params[i] )
    1583                                                         ( &ast::TypeExpr::type )
    1584                                                                 ( &ast::TypeInstType::base )->sized = true;
    1585                                                 traitInst = mut;
    1586                                         }
    1587                                 }
    1588                         }
    1589 
    1590                         return traitInst;
    1591                 }
    1592 
    1593                 void previsit( const ast::QualifiedType * ) { visit_children = false; }
    1594 
    1595                 const ast::Type * postvisit( const ast::QualifiedType * qualType ) {
    1596                         // linking only makes sense for the "oldest ancestor" of the qualified type
    1597                         return ast::mutate_field(
    1598                                 qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) );
    1599                 }
    1600 
    1601                 const ast::Decl * postvisit( const ast::EnumDecl * enumDecl ) {
    1602                         // visit enum members first so that the types of self-referencing members are updated
    1603                         // properly
    1604                         if ( ! enumDecl->body ) return enumDecl;
    1605 
    1606                         // update forward declarations to point here
    1607                         auto fwds = forwardEnums.equal_range( enumDecl->name );
    1608                         if ( fwds.first != fwds.second ) {
    1609                                 auto inst = fwds.first;
    1610                                 do {
    1611                                         // forward decl is stored * mutably * in map, can thus be updated
    1612                                         inst->second->base = enumDecl;
    1613                                 } while ( ++inst != fwds.second );
    1614                                 forwardEnums.erase( fwds.first, fwds.second );
    1615                         }
    1616 
    1617                         // ensure that enumerator initializers are properly set
    1618                         for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) {
    1619                                 auto field = enumDecl->members[i].strict_as< ast::ObjectDecl >();
    1620                                 if ( field->init ) {
    1621                                         // need to resolve enumerator initializers early so that other passes that
    1622                                         // determine if an expression is constexpr have appropriate information
    1623                                         auto init = field->init.strict_as< ast::SingleInit >();
    1624 
    1625                                         enumDecl = ast::mutate_field_index(
    1626                                                 enumDecl, &ast::EnumDecl::members, i,
    1627                                                 ast::mutate_field( field, &ast::ObjectDecl::init,
    1628                                                         ast::mutate_field( init, &ast::SingleInit::value,
    1629                                                                 ResolvExpr::findSingleExpression(
    1630                                                                         init->value, new ast::BasicType{ ast::BasicType::SignedInt },
    1631                                                                         symtab ) ) ) );
    1632                                 }
    1633                         }
    1634 
    1635                         return enumDecl;
    1636                 }
    1637 
    1638                 /// rename generic type parameters uniquely so that they do not conflict with user defined
    1639                 /// function forall parameters, e.g. the T in Box and the T in f, below
    1640                 ///   forall(otype T)
    1641                 ///   struct Box {
    1642                 ///     T x;
    1643                 ///   };
    1644                 ///   forall(otype T)
    1645                 ///   void f(Box(T) b) {
    1646                 ///     ...
    1647                 ///   }
    1648                 template< typename AggrDecl >
    1649                 const AggrDecl * renameGenericParams( const AggrDecl * aggr ) {
    1650                         GuardValue( inGeneric );
    1651                         inGeneric = ! aggr->params.empty();
    1652 
    1653                         for ( unsigned i = 0; i < aggr->params.size(); ++i ) {
    1654                                 const ast::TypeDecl * td = aggr->params[i];
    1655 
    1656                                 aggr = ast::mutate_field_index(
    1657                                         aggr, &AggrDecl::params, i,
    1658                                         ast::mutate_field( td, &ast::TypeDecl::name, "__" + td->name + "_generic_" ) );
    1659                         }
    1660                         return aggr;
    1661                 }
    1662 
    1663                 const ast::StructDecl * previsit( const ast::StructDecl * structDecl ) {
    1664                         return renameGenericParams( structDecl );
    1665                 }
    1666 
    1667                 void postvisit( const ast::StructDecl * structDecl ) {
    1668                         // visit struct members first so that the types of self-referencing members are
    1669                         // updated properly
    1670                         if ( ! structDecl->body ) return;
    1671 
    1672                         // update forward declarations to point here
    1673                         auto fwds = forwardStructs.equal_range( structDecl->name );
    1674                         if ( fwds.first != fwds.second ) {
    1675                                 auto inst = fwds.first;
    1676                                 do {
    1677                                         // forward decl is stored * mutably * in map, can thus be updated
    1678                                         inst->second->base = structDecl;
    1679                                 } while ( ++inst != fwds.second );
    1680                                 forwardStructs.erase( fwds.first, fwds.second );
    1681                         }
    1682                 }
    1683 
    1684                 const ast::UnionDecl * previsit( const ast::UnionDecl * unionDecl ) {
    1685                         return renameGenericParams( unionDecl );
    1686                 }
    1687 
    1688                 void postvisit( const ast::UnionDecl * unionDecl ) {
    1689                         // visit union members first so that the types of self-referencing members are updated
    1690                         // properly
    1691                         if ( ! unionDecl->body ) return;
    1692 
    1693                         // update forward declarations to point here
    1694                         auto fwds = forwardUnions.equal_range( unionDecl->name );
    1695                         if ( fwds.first != fwds.second ) {
    1696                                 auto inst = fwds.first;
    1697                                 do {
    1698                                         // forward decl is stored * mutably * in map, can thus be updated
    1699                                         inst->second->base = unionDecl;
    1700                                 } while ( ++inst != fwds.second );
    1701                                 forwardUnions.erase( fwds.first, fwds.second );
    1702                         }
    1703                 }
    1704 
    1705                 const ast::Decl * postvisit( const ast::TraitDecl * traitDecl ) {
    1706                         // set the "sized" status for the special "sized" trait
    1707                         if ( traitDecl->name == "sized" ) {
    1708                                 assertf( traitDecl->params.size() == 1, "Built-in trait 'sized' has incorrect "
    1709                                         "number of parameters: %zd", traitDecl->params.size() );
    1710 
    1711                                 traitDecl = ast::mutate_field_index(
    1712                                         traitDecl, &ast::TraitDecl::params, 0,
    1713                                         ast::mutate_field(
    1714                                                 traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) );
    1715                         }
    1716 
    1717                         // move assertions from type parameters into the body of the trait
    1718                         std::vector< ast::ptr< ast::DeclWithType > > added;
    1719                         for ( const ast::TypeDecl * td : traitDecl->params ) {
    1720                                 for ( const ast::DeclWithType * assn : td->assertions ) {
    1721                                         auto inst = dynamic_cast< const ast::TraitInstType * >( assn->get_type() );
    1722                                         if ( inst ) {
    1723                                                 expandAssertions( inst, added );
    1724                                         } else {
    1725                                                 added.emplace_back( assn );
    1726                                         }
    1727                                 }
    1728                         }
    1729                         if ( ! added.empty() ) {
    1730                                 auto mut = mutate( traitDecl );
    1731                                 for ( const ast::DeclWithType * decl : added ) {
    1732                                         mut->members.emplace_back( decl );
    1733                                 }
    1734                                 traitDecl = mut;
    1735                         }
    1736 
    1737                         return traitDecl;
    1738                 }
    1739         };
    1740 
    1741         /// Replaces array and function types in forall lists by appropriate pointer type and assigns
    1742         /// each object and function declaration a unique ID
    1743         class ForallPointerDecay_new {
    1744                 const CodeLocation & location;
    1745         public:
    1746                 ForallPointerDecay_new( const CodeLocation & loc ) : location( loc ) {}
    1747 
    1748                 const ast::ObjectDecl * previsit( const ast::ObjectDecl * obj ) {
    1749                         // ensure that operator names only apply to functions or function pointers
    1750                         if (
    1751                                 CodeGen::isOperator( obj->name )
    1752                                 && ! dynamic_cast< const ast::FunctionType * >( obj->type->stripDeclarator() )
    1753                         ) {
    1754                                 SemanticError( obj->location, toCString( "operator ", obj->name.c_str(), " is not "
    1755                                         "a function or function pointer." )  );
    1756                         }
    1757 
    1758                         // ensure object has unique ID
    1759                         if ( obj->uniqueId ) return obj;
    1760                         auto mut = mutate( obj );
    1761                         mut->fixUniqueId();
    1762                         return mut;
    1763                 }
    1764 
    1765                 const ast::FunctionDecl * previsit( const ast::FunctionDecl * func ) {
    1766                         // ensure function has unique ID
    1767                         if ( func->uniqueId ) return func;
    1768                         auto mut = mutate( func );
    1769                         mut->fixUniqueId();
    1770                         return mut;
    1771                 }
    1772 
    1773                 /// Fix up assertions -- flattens assertion lists, removing all trait instances
    1774                 template< typename node_t, typename parent_t >
    1775                 static const node_t * forallFixer(
    1776                         const CodeLocation & loc, const node_t * node,
    1777                         ast::ParameterizedType::ForallList parent_t::* forallField
    1778                 ) {
    1779                         for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) {
    1780                                 const ast::TypeDecl * type = (node->* forallField)[i];
    1781                                 if ( type->assertions.empty() ) continue;
    1782 
    1783                                 std::vector< ast::ptr< ast::DeclWithType > > asserts;
    1784                                 asserts.reserve( type->assertions.size() );
    1785 
    1786                                 // expand trait instances into their members
    1787                                 for ( const ast::DeclWithType * assn : type->assertions ) {
    1788                                         auto traitInst =
    1789                                                 dynamic_cast< const ast::TraitInstType * >( assn->get_type() );
    1790                                         if ( traitInst ) {
    1791                                                 // expand trait instance to all its members
    1792                                                 expandAssertions( traitInst, asserts );
    1793                                         } else {
    1794                                                 // pass other assertions through
    1795                                                 asserts.emplace_back( assn );
    1796                                         }
    1797                                 }
    1798 
    1799                                 // apply FixFunction to every assertion to check for invalid void type
    1800                                 for ( ast::ptr< ast::DeclWithType > & assn : asserts ) {
    1801                                         bool isVoid = false;
    1802                                         assn = fixFunction( assn, isVoid );
    1803                                         if ( isVoid ) {
    1804                                                 SemanticError( loc, node, "invalid type void in assertion of function " );
    1805                                         }
    1806                                 }
    1807 
    1808                                 // place mutated assertion list in node
    1809                                 auto mut = mutate( type );
    1810                                 mut->assertions = move( asserts );
    1811                                 node = ast::mutate_field_index( node, forallField, i, mut );
    1812                         }
    1813                         return node;
    1814                 }
    1815 
    1816                 const ast::FunctionType * previsit( const ast::FunctionType * ftype ) {
    1817                         return forallFixer( location, ftype, &ast::FunctionType::forall );
    1818                 }
    1819 
    1820                 const ast::StructDecl * previsit( const ast::StructDecl * aggrDecl ) {
    1821                         return forallFixer( aggrDecl->location, aggrDecl, &ast::StructDecl::params );
    1822                 }
    1823 
    1824                 const ast::UnionDecl * previsit( const ast::UnionDecl * aggrDecl ) {
    1825                         return forallFixer( aggrDecl->location, aggrDecl, &ast::UnionDecl::params );
    1826                 }
    1827         };
    1828 } // anonymous namespace
    1829 
    1830 const ast::Type * validateType(
    1831                 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) {
    1832         ast::Pass< EnumAndPointerDecay_new > epc;
    1833         ast::Pass< LinkReferenceToTypes_new > lrt{ loc, symtab };
    1834         ast::Pass< ForallPointerDecay_new > fpd{ loc };
    1835 
    1836         return type->accept( epc )->accept( lrt )->accept( fpd );
    1837 }
    1838 
     1073        }
    18391074} // namespace SymTab
    18401075
Note: See TracChangeset for help on using the changeset viewer.