Changeset c1ed2ee


Ignore:
Timestamp:
Jun 21, 2019, 3:41:36 PM (5 years ago)
Author:
Aaron Moss <a3moss@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
8d61d620
Parents:
9af00d23
Message:

Continued resolver porting

  • mostly initialization and validation
  • added move() and copy() to utility.h
Location:
src
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • src/AST/Stmt.hpp

    r9af00d23 rc1ed2ee  
    143143
    144144        IfStmt( const CodeLocation & loc, const Expr * cond, const Stmt * thenPart,
    145                 Stmt * const elsePart, std::vector<ptr<Stmt>> && inits,
     145                const Stmt * elsePart = nullptr, std::vector<ptr<Stmt>> && inits = {},
    146146                std::vector<Label> && labels = {} )
    147147        : Stmt(loc, std::move(labels)), cond(cond), thenPart(thenPart), elsePart(elsePart),
  • src/Common/utility.h

    r9af00d23 rc1ed2ee  
    3434class Expression;
    3535
     36/// bring std::move into global scope
     37using std::move;
     38
     39/// partner to move that copies any copyable type
     40template<typename T>
     41T copy( const T & x ) { return x; }
     42
    3643template< typename T >
    3744static inline T * maybeClone( const T *orig ) {
  • src/InitTweak/InitTweak.cc

    r9af00d23 rc1ed2ee  
    2222
    2323#include "AST/Expr.hpp"
     24#include "AST/Init.hpp"
    2425#include "AST/Node.hpp"
     26#include "AST/Pass.hpp"
    2527#include "AST/Stmt.hpp"
    2628#include "AST/Type.hpp"
     
    8587                };
    8688
    87                 struct InitFlattener : public WithShortCircuiting {
     89                struct InitFlattener_old : public WithShortCircuiting {
    8890                        void previsit( SingleInit * singleInit ) {
    8991                                visit_children = false;
     
    9395                };
    9496
    95         }
     97                struct InitFlattener_new : public ast::WithShortCircuiting {
     98                        std::vector< ast::ptr< ast::Expr > > argList;
     99
     100                        void previsit( const ast::SingleInit * singleInit ) {
     101                                visit_children = false;
     102                                argList.emplace_back( singleInit->value );
     103                        }
     104                };
     105
     106        } // anonymous namespace
    96107
    97108        std::list< Expression * > makeInitList( Initializer * init ) {
    98                 PassVisitor<InitFlattener> flattener;
     109                PassVisitor<InitFlattener_old> flattener;
    99110                maybeAccept( init, flattener );
    100111                return flattener.pass.argList;
     
    114125
    115126std::vector< ast::ptr< ast::Expr > > makeInitList( const ast::Init * init ) {
    116         #warning unimplmented
    117         (void)init;
    118         assert(false);
    119         return {};
     127        ast::Pass< InitFlattener_new > flattener;
     128        maybe_accept( init, flattener );
     129        return std::move( flattener.pass.argList );
    120130}
    121131
     
    309319        virtual std::vector< ast::ptr< ast::Expr > > next( IndexList & indices ) = 0;
    310320        virtual ast::ptr< ast::Stmt > buildListInit(
    311                 const ast::UntypedExpr * callExpr, IndexList & indices ) = 0;
     321                ast::UntypedExpr * callExpr, IndexList & indices ) = 0;
    312322};
    313323
    314324namespace {
     325        template< typename Out >
     326        void buildCallExpr(
     327                ast::UntypedExpr * callExpr, const ast::Expr * index, const ast::Expr * dimension,
     328                const ast::Init * init, Out & out
     329        ) {
     330                const CodeLocation & loc = init->location;
     331
     332                auto cond = new ast::UntypedExpr{
     333                        loc, new ast::NameExpr{ loc, "?<?" }, { index, dimension } };
     334               
     335                std::vector< ast::ptr< ast::Expr > > args = makeInitList( init );
     336                splice( callExpr->args, args );
     337
     338                out.emplace_back( new ast::IfStmt{ loc, cond, new ast::ExprStmt{ loc, callExpr } } );
     339
     340                out.emplace_back( new ast::ExprStmt{
     341                        loc, new ast::UntypedExpr{ loc, new ast::NameExpr{ loc, "++?" }, { index } } } );
     342        }
     343
     344        template< typename Out >
     345        void build(
     346                ast::UntypedExpr * callExpr, const InitExpander_new::IndexList & indices,
     347                const ast::Init * init, Out & out
     348        ) {
     349                if ( indices.empty() ) return;
     350
     351                unsigned idx = 0;
     352
     353                const ast::Expr * index = indices[idx++];
     354                assert( idx != indices.size() );
     355                const ast::Expr * dimension = indices[idx++];
     356
     357                if ( idx == indices.size() ) {
     358                        if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) {
     359                                for ( const ast::Init * init : *listInit ) {
     360                                        buildCallExpr( callExpr, index, dimension, init, out );
     361                                }
     362                        } else {
     363                                buildCallExpr( callExpr, index, dimension, init, out );
     364                        }
     365                } else {
     366                        const CodeLocation & loc = init->location;
     367
     368                        unsigned long cond = 0;
     369                        auto listInit = dynamic_cast< const ast::ListInit * >( init );
     370                        if ( ! listInit ) { SemanticError( loc, "unbalanced list initializers" ); }
     371
     372                        static UniqueName targetLabel( "L__autogen__" );
     373                        ast::Label switchLabel{
     374                                loc, targetLabel.newName(), { new ast::Attribute{ "unused" } } };
     375                       
     376                        std::vector< ast::ptr< ast::Stmt > > branches;
     377                        for ( const ast::Init * init : *listInit ) {
     378                                auto condition = ast::ConstantExpr::from_ulong( loc, cond );
     379                                ++cond;
     380
     381                                std::vector< ast::ptr< ast::Stmt > > stmts;
     382                                build( callExpr, indices, init, stmts );
     383                                stmts.emplace_back(
     384                                        new ast::BranchStmt{ loc, ast::BranchStmt::Break, switchLabel } );
     385                                branches.emplace_back( new ast::CaseStmt{ loc, condition, std::move( stmts ) } );
     386                        }
     387                        out.emplace_back( new ast::SwitchStmt{ loc, index, std::move( branches ) } );
     388                        out.emplace_back( new ast::NullStmt{ loc, { switchLabel } } );
     389                }
     390        }
     391
    315392        class InitImpl_new final : public InitExpander_new::ExpanderImpl {
    316393                ast::ptr< ast::Init > init;
     
    323400               
    324401                ast::ptr< ast::Stmt > buildListInit(
    325                         const ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices
     402                        ast::UntypedExpr * callExpr, InitExpander_new::IndexList & indices
    326403                ) override {
    327                         #warning unimplemented
    328                         (void)callExpr; (void)indices;
    329                         assert(false);
    330                         return {};
     404                        // If array came with an initializer list, initialize each element. We may have more
     405                        // initializers than elements of the array; need to check at each index that we have
     406                        // not exceeded size. We may have fewer initializers than elements in the array; need
     407                        // to default-construct remaining elements. To accomplish this, generate switch
     408                        // statement consuming all of expander's elements
     409
     410                        if ( ! init ) return {};
     411
     412                        std::list< ast::ptr< ast::Stmt > > stmts;
     413                        build( callExpr, indices, init, stmts );
     414                        if ( stmts.empty() ) {
     415                                return {};
     416                        } else {
     417                                auto block = new ast::CompoundStmt{ init->location, std::move( stmts ) };
     418                                init = nullptr;  // consumed in creating the list init
     419                                return block;
     420                        }
    331421                }
    332422        };
     
    340430                        InitExpander_new::IndexList & indices
    341431                ) override {
    342                         #warning unimplemented
    343                         (void)indices;
    344                         assert(false);
    345                         return {};
     432                        if ( ! arg ) return {};
     433
     434                        const CodeLocation & loc = arg->location;
     435                        const ast::Expr * expr = arg;
     436                        for ( auto it = indices.rbegin(); it != indices.rend(); ++it ) {
     437                                // go through indices and layer on subscript exprs ?[?]
     438                                ++it;
     439                                expr = new ast::UntypedExpr{
     440                                        loc, new ast::NameExpr{ loc, "?[?]" }, { expr, *it } };
     441                        }
     442                        return { expr };
    346443                }
    347444               
    348445                ast::ptr< ast::Stmt > buildListInit(
    349                         const ast::UntypedExpr *, InitExpander_new::IndexList &
     446                        ast::UntypedExpr *, InitExpander_new::IndexList &
    350447                ) override {
    351448                        return {};
     
    369466/// builds statement which has the same semantics as a C-style list initializer (for array
    370467/// initializers) using callExpr as the base expression to perform initialization
    371 ast::ptr< ast::Stmt > InitExpander_new::buildListInit( const ast::UntypedExpr * callExpr ) {
     468ast::ptr< ast::Stmt > InitExpander_new::buildListInit( ast::UntypedExpr * callExpr ) {
    372469        return expander->buildListInit( callExpr, indices );
    373470}
  • src/InitTweak/InitTweak.h

    r9af00d23 rc1ed2ee  
    154154
    155155                /// builds statement which has the same semantics as a C-style list initializer (for array
    156                 /// initializers) using callExpr as the base expression to perform initialization
    157                 ast::ptr< ast::Stmt > buildListInit( const ast::UntypedExpr * callExpr );
     156                /// initializers) using callExpr as the base expression to perform initialization.
     157                /// Mutates callExpr
     158                ast::ptr< ast::Stmt > buildListInit( ast::UntypedExpr * callExpr );
    158159
    159160                void addArrayIndex( const ast::Expr * index, const ast::Expr * dimension );
  • src/ResolvExpr/AlternativeFinder.cc

    r9af00d23 rc1ed2ee  
    5656#define PRINT( text ) if ( resolvep ) { text }
    5757//#define DEBUG_COST
    58 
    59 using std::move;
    60 
    61 /// copies any copyable type
    62 template<typename T>
    63 T copy(const T& x) { return x; }
    6458
    6559namespace ResolvExpr {
  • src/ResolvExpr/CandidateFinder.cpp

    r9af00d23 rc1ed2ee  
    3939#include "AST/SymbolTable.hpp"
    4040#include "AST/Type.hpp"
     41#include "Common/utility.h"       // for move, copy
    4142#include "SymTab/Mangler.h"
    4243#include "SymTab/Validate.h"      // for validateType
     
    4647
    4748namespace ResolvExpr {
    48 
    49 using std::move;
    50 
    51 /// partner to move that copies any copyable type
    52 template<typename T>
    53 T copy( const T & x ) { return x; }
    5449
    5550const ast::Expr * referenceToRvalueConversion( const ast::Expr * expr, Cost & cost ) {
  • src/SymTab/FixFunction.cc

    r9af00d23 rc1ed2ee  
    1818#include <list>                   // for list
    1919
    20 #include "Common/utility.h"       // for maybeClone
     20#include "AST/Decl.hpp"
     21#include "AST/Pass.hpp"
     22#include "AST/Type.hpp"
     23#include "Common/utility.h"       // for maybeClone, copy
    2124#include "SynTree/Declaration.h"  // for FunctionDecl, ObjectDecl, Declarati...
    2225#include "SynTree/Expression.h"   // for Expression
     
    2427
    2528namespace SymTab {
    26         FixFunction::FixFunction() : isVoid( false ) {}
     29        class FixFunction_old : public WithShortCircuiting {
     30                typedef Mutator Parent;
     31          public:
     32                FixFunction_old() : isVoid( false ) {}
    2733
     34                void premutate(FunctionDecl *functionDecl);
     35                DeclarationWithType* postmutate(FunctionDecl *functionDecl);
    2836
    29         DeclarationWithType * FixFunction::postmutate(FunctionDecl *functionDecl) {
     37                Type * postmutate(ArrayType * arrayType);
     38
     39                void premutate(ArrayType * arrayType);
     40                void premutate(VoidType * voidType);
     41                void premutate(BasicType * basicType);
     42                void premutate(PointerType * pointerType);
     43                void premutate(StructInstType * aggregateUseType);
     44                void premutate(UnionInstType * aggregateUseType);
     45                void premutate(EnumInstType * aggregateUseType);
     46                void premutate(TraitInstType * aggregateUseType);
     47                void premutate(TypeInstType * aggregateUseType);
     48                void premutate(TupleType * tupleType);
     49                void premutate(VarArgsType * varArgsType);
     50                void premutate(ZeroType * zeroType);
     51                void premutate(OneType * oneType);
     52
     53                bool isVoid;
     54        };
     55
     56        DeclarationWithType * FixFunction_old::postmutate(FunctionDecl *functionDecl) {
    3057                // can't delete function type because it may contain assertions, so transfer ownership to new object
    3158                ObjectDecl *pointer = new ObjectDecl( functionDecl->name, functionDecl->get_storageClasses(), functionDecl->linkage, nullptr, new PointerType( Type::Qualifiers(), functionDecl->type ), nullptr, functionDecl->attributes );
     
    4168        // does not cause an error
    4269
    43         Type * FixFunction::postmutate(ArrayType *arrayType) {
     70        Type * FixFunction_old::postmutate(ArrayType *arrayType) {
    4471                // need to recursively mutate the base type in order for multi-dimensional arrays to work.
    4572                PointerType *pointerType = new PointerType( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->isVarLen, arrayType->isStatic );
     
    5178        }
    5279
    53         void FixFunction::premutate(VoidType *) {
     80        void FixFunction_old::premutate(VoidType *) {
    5481                isVoid = true;
    5582        }
    5683
    57         void FixFunction::premutate(FunctionDecl *) { visit_children = false; }
    58         void FixFunction::premutate(ArrayType *) { visit_children = false; }
    59         void FixFunction::premutate(BasicType *) { visit_children = false; }
    60         void FixFunction::premutate(PointerType *) { visit_children = false; }
    61         void FixFunction::premutate(StructInstType *) { visit_children = false; }
    62         void FixFunction::premutate(UnionInstType *) { visit_children = false; }
    63         void FixFunction::premutate(EnumInstType *) { visit_children = false; }
    64         void FixFunction::premutate(TraitInstType *) { visit_children = false; }
    65         void FixFunction::premutate(TypeInstType *) { visit_children = false; }
    66         void FixFunction::premutate(TupleType *) { visit_children = false; }
    67         void FixFunction::premutate(VarArgsType *) { visit_children = false; }
    68         void FixFunction::premutate(ZeroType *) { visit_children = false; }
    69         void FixFunction::premutate(OneType *) { visit_children = false; }
     84        void FixFunction_old::premutate(FunctionDecl *) { visit_children = false; }
     85        void FixFunction_old::premutate(ArrayType *) { visit_children = false; }
     86        void FixFunction_old::premutate(BasicType *) { visit_children = false; }
     87        void FixFunction_old::premutate(PointerType *) { visit_children = false; }
     88        void FixFunction_old::premutate(StructInstType *) { visit_children = false; }
     89        void FixFunction_old::premutate(UnionInstType *) { visit_children = false; }
     90        void FixFunction_old::premutate(EnumInstType *) { visit_children = false; }
     91        void FixFunction_old::premutate(TraitInstType *) { visit_children = false; }
     92        void FixFunction_old::premutate(TypeInstType *) { visit_children = false; }
     93        void FixFunction_old::premutate(TupleType *) { visit_children = false; }
     94        void FixFunction_old::premutate(VarArgsType *) { visit_children = false; }
     95        void FixFunction_old::premutate(ZeroType *) { visit_children = false; }
     96        void FixFunction_old::premutate(OneType *) { visit_children = false; }
    7097
    7198        bool fixFunction( DeclarationWithType *& dwt ) {
    72                 PassVisitor<FixFunction> fixer;
     99                PassVisitor<FixFunction_old> fixer;
    73100                dwt = dwt->acceptMutator( fixer );
    74101                return fixer.pass.isVoid;
    75102        }
     103
     104namespace {
     105        struct FixFunction_new final : public ast::WithShortCircuiting {
     106                bool isVoid = false;
     107
     108                void premutate( const ast::FunctionDecl * ) { visit_children = false; }
     109
     110                const ast::DeclWithType * postmutate( const ast::FunctionDecl * func ) {
     111                        return new ast::ObjectDecl{
     112                                func->location, func->name, new ast::PointerType{ func->type }, nullptr,
     113                                func->storage, func->linkage, nullptr, copy( func->attributes ) };
     114                }
     115
     116                void premutate( const ast::ArrayType * ) { visit_children = false; }
     117
     118                const ast::Type * postmutate( const ast::ArrayType * array ) {
     119                        return new ast::PointerType{
     120                                array->base, array->dimension, array->isVarLen, array->isStatic,
     121                                array->qualifiers };
     122                }
     123
     124                void premutate( const ast::VoidType * ) { isVoid = true; }
     125
     126                void premutate( const ast::BasicType * ) { visit_children = false; }
     127                void premutate( const ast::PointerType * ) { visit_children = false; }
     128                void premutate( const ast::StructInstType * ) { visit_children = false; }
     129                void premutate( const ast::UnionInstType * ) { visit_children = false; }
     130                void premutate( const ast::EnumInstType * ) { visit_children = false; }
     131                void premutate( const ast::TraitInstType * ) { visit_children = false; }
     132                void premutate( const ast::TypeInstType * ) { visit_children = false; }
     133                void premutate( const ast::TupleType * ) { visit_children = false; }
     134                void premutate( const ast::VarArgsType * ) { visit_children = false; }
     135                void premutate( const ast::ZeroType * ) { visit_children = false; }
     136                void premutate( const ast::OneType * ) { visit_children = false; }
     137        };
     138} // anonymous namespace
     139
     140const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid ) {
     141        ast::Pass< FixFunction_new > fixer;
     142        dwt = dwt->accept( fixer );
     143        isVoid |= fixer.pass.isVoid;
     144        return dwt;
     145}
     146
    76147} // namespace SymTab
    77148
  • src/SymTab/FixFunction.h

    r9af00d23 rc1ed2ee  
    1919#include "SynTree/SynTree.h"    // for Types
    2020
     21namespace ast {
     22        class DeclWithType;
     23}
     24
    2125namespace SymTab {
    22         /// Replaces function and array types by equivalent pointer types.
    23         class FixFunction : public WithShortCircuiting {
    24                 typedef Mutator Parent;
    25           public:
    26                 FixFunction();
     26        /// Replaces function and array types by equivalent pointer types. Returns true if type is
     27        /// void
     28        bool fixFunction( DeclarationWithType *& );
    2729
    28                 void premutate(FunctionDecl *functionDecl);
    29                 DeclarationWithType* postmutate(FunctionDecl *functionDecl);
    30 
    31                 Type * postmutate(ArrayType * arrayType);
    32 
    33                 void premutate(ArrayType * arrayType);
    34                 void premutate(VoidType * voidType);
    35                 void premutate(BasicType * basicType);
    36                 void premutate(PointerType * pointerType);
    37                 void premutate(StructInstType * aggregateUseType);
    38                 void premutate(UnionInstType * aggregateUseType);
    39                 void premutate(EnumInstType * aggregateUseType);
    40                 void premutate(TraitInstType * aggregateUseType);
    41                 void premutate(TypeInstType * aggregateUseType);
    42                 void premutate(TupleType * tupleType);
    43                 void premutate(VarArgsType * varArgsType);
    44                 void premutate(ZeroType * zeroType);
    45                 void premutate(OneType * oneType);
    46 
    47                 bool isVoid;
    48         };
    49 
    50         bool fixFunction( DeclarationWithType *& );
     30        /// Returns declaration with function and array types replaced by equivalent pointer types.
     31        /// Sets isVoid to true if type is void
     32        const ast::DeclWithType * fixFunction( const ast::DeclWithType * dwt, bool & isVoid );
    5133} // namespace SymTab
    5234
  • src/SymTab/Validate.cc

    r9af00d23 rc1ed2ee  
    4646#include <utility>                     // for pair
    4747
     48#include "AST/Decl.hpp"
     49#include "AST/Node.hpp"
     50#include "AST/Pass.hpp"
     51#include "AST/SymbolTable.hpp"
     52#include "AST/Type.hpp"
    4853#include "CodeGen/CodeGenerator.h"     // for genName
    4954#include "CodeGen/OperatorTable.h"     // for isCtorDtor, isCtorDtorAssign
     
    124129
    125130        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    126         struct EnumAndPointerDecay {
     131        struct EnumAndPointerDecay_old {
    127132                void previsit( EnumDecl *aggregateDecl );
    128133                void previsit( FunctionType *func );
     
    130135
    131136        /// Associates forward declarations of aggregates with their definitions
    132         struct LinkReferenceToTypes final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes>, public WithShortCircuiting {
    133                 LinkReferenceToTypes( const Indexer *indexer );
     137        struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting {
     138                LinkReferenceToTypes_old( const Indexer *indexer );
    134139                void postvisit( TypeInstType *typeInst );
    135140
     
    165170
    166171        /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
    167         struct ForallPointerDecay final {
     172        struct ForallPointerDecay_old final {
    168173                void previsit( ObjectDecl * object );
    169174                void previsit( FunctionDecl * func );
     
    290295
    291296        void validate( std::list< Declaration * > &translationUnit, __attribute__((unused)) bool doDebug ) {
    292                 PassVisitor<EnumAndPointerDecay> epc;
    293                 PassVisitor<LinkReferenceToTypes> lrt( nullptr );
    294                 PassVisitor<ForallPointerDecay> fpd;
     297                PassVisitor<EnumAndPointerDecay_old> epc;
     298                PassVisitor<LinkReferenceToTypes_old> lrt( nullptr );
     299                PassVisitor<ForallPointerDecay_old> fpd;
    295300                PassVisitor<CompoundLiteral> compoundliteral;
    296301                PassVisitor<ValidateGenericParameters> genericParams;
     
    305310                        ReplaceTypedef::replaceTypedef( translationUnit );
    306311                        ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
    307                         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
     312                        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
    308313                }
    309314                {
     
    314319                        });
    315320                        Stats::Time::TimeBlock("Fix Qualified Types", [&]() {
    316                                 mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes, because aggregate members are accessed
     321                                mutateAll( translationUnit, fixQual ); // must happen after LinkReferenceToTypes_old, because aggregate members are accessed
    317322                        });
    318323                        Stats::Time::TimeBlock("Hoist Structs", [&]() {
     
    326331                        Stats::Heap::newPass("validate-C");
    327332                        Stats::Time::BlockGuard guard("validate-C");
    328                         acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes
     333                        acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes_old
    329334                        VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    330335                        ReturnChecker::checkFunctionReturns( translationUnit );
     
    344349                        });
    345350                        Stats::Time::TimeBlock("Generate Autogen routines", [&]() {
    346                                 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
     351                                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay_old
    347352                        });
    348353                }
     
    385390
    386391        void validateType( Type *type, const Indexer *indexer ) {
    387                 PassVisitor<EnumAndPointerDecay> epc;
    388                 PassVisitor<LinkReferenceToTypes> lrt( indexer );
    389                 PassVisitor<ForallPointerDecay> fpd;
     392                PassVisitor<EnumAndPointerDecay_old> epc;
     393                PassVisitor<LinkReferenceToTypes_old> lrt( indexer );
     394                PassVisitor<ForallPointerDecay_old> fpd;
    390395                type->accept( epc );
    391396                type->accept( lrt );
     
    586591        }
    587592
    588         void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) {
     593        void EnumAndPointerDecay_old::previsit( EnumDecl *enumDecl ) {
    589594                // Set the type of each member of the enumeration to be EnumConstant
    590595                for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) {
     
    618623        }
    619624
    620         void EnumAndPointerDecay::previsit( FunctionType *func ) {
     625        void EnumAndPointerDecay_old::previsit( FunctionType *func ) {
    621626                // Fix up parameters and return types
    622627                fixFunctionList( func->parameters, func->isVarArgs, func );
     
    624629        }
    625630
    626         LinkReferenceToTypes::LinkReferenceToTypes( const Indexer *other_indexer ) {
     631        LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer *other_indexer ) {
    627632                if ( other_indexer ) {
    628633                        local_indexer = other_indexer;
     
    632637        }
    633638
    634         void LinkReferenceToTypes::postvisit( EnumInstType *enumInst ) {
     639        void LinkReferenceToTypes_old::postvisit( EnumInstType *enumInst ) {
    635640                EnumDecl *st = local_indexer->lookupEnum( enumInst->name );
    636641                // it's not a semantic error if the enum is not found, just an implicit forward declaration
     
    652657        }
    653658
    654         void LinkReferenceToTypes::postvisit( StructInstType *structInst ) {
     659        void LinkReferenceToTypes_old::postvisit( StructInstType *structInst ) {
    655660                StructDecl *st = local_indexer->lookupStruct( structInst->name );
    656661                // it's not a semantic error if the struct is not found, just an implicit forward declaration
     
    665670        }
    666671
    667         void LinkReferenceToTypes::postvisit( UnionInstType *unionInst ) {
     672        void LinkReferenceToTypes_old::postvisit( UnionInstType *unionInst ) {
    668673                UnionDecl *un = local_indexer->lookupUnion( unionInst->name );
    669674                // it's not a semantic error if the union is not found, just an implicit forward declaration
     
    678683        }
    679684
    680         void LinkReferenceToTypes::previsit( QualifiedType * ) {
     685        void LinkReferenceToTypes_old::previsit( QualifiedType * ) {
    681686                visit_children = false;
    682687        }
    683688
    684         void LinkReferenceToTypes::postvisit( QualifiedType * qualType ) {
     689        void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) {
    685690                // linking only makes sense for the 'oldest ancestor' of the qualified type
    686691                qualType->parent->accept( *visitor );
     
    729734        }
    730735
    731         void LinkReferenceToTypes::postvisit( TraitDecl * traitDecl ) {
     736        void LinkReferenceToTypes_old::postvisit( TraitDecl * traitDecl ) {
    732737                if ( traitDecl->name == "sized" ) {
    733738                        // "sized" is a special trait - flick the sized status on for the type variable
     
    751756        }
    752757
    753         void LinkReferenceToTypes::postvisit( TraitInstType * traitInst ) {
     758        void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) {
    754759                // handle other traits
    755760                TraitDecl *traitDecl = local_indexer->lookupTrait( traitInst->name );
     
    777782        }
    778783
    779         void LinkReferenceToTypes::postvisit( EnumDecl *enumDecl ) {
     784        void LinkReferenceToTypes_old::postvisit( EnumDecl *enumDecl ) {
    780785                // visit enum members first so that the types of self-referencing members are updated properly
    781786                if ( enumDecl->body ) {
     
    799804        }
    800805
    801         void LinkReferenceToTypes::renameGenericParams( std::list< TypeDecl * > & params ) {
     806        void LinkReferenceToTypes_old::renameGenericParams( std::list< TypeDecl * > & params ) {
    802807                // rename generic type parameters uniquely so that they do not conflict with user-defined function forall parameters, e.g.
    803808                //   forall(otype T)
     
    817822        }
    818823
    819         void LinkReferenceToTypes::previsit( StructDecl * structDecl ) {
     824        void LinkReferenceToTypes_old::previsit( StructDecl * structDecl ) {
    820825                renameGenericParams( structDecl->parameters );
    821826        }
    822827
    823         void LinkReferenceToTypes::previsit( UnionDecl * unionDecl ) {
     828        void LinkReferenceToTypes_old::previsit( UnionDecl * unionDecl ) {
    824829                renameGenericParams( unionDecl->parameters );
    825830        }
    826831
    827         void LinkReferenceToTypes::postvisit( StructDecl *structDecl ) {
     832        void LinkReferenceToTypes_old::postvisit( StructDecl *structDecl ) {
    828833                // visit struct members first so that the types of self-referencing members are updated properly
    829834                // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults)
     
    839844        }
    840845
    841         void LinkReferenceToTypes::postvisit( UnionDecl *unionDecl ) {
     846        void LinkReferenceToTypes_old::postvisit( UnionDecl *unionDecl ) {
    842847                if ( unionDecl->body ) {
    843848                        ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name );
     
    851856        }
    852857
    853         void LinkReferenceToTypes::postvisit( TypeInstType *typeInst ) {
     858        void LinkReferenceToTypes_old::postvisit( TypeInstType *typeInst ) {
    854859                // ensure generic parameter instances are renamed like the base type
    855860                if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name;
     
    888893        }
    889894
    890         void ForallPointerDecay::previsit( ObjectDecl *object ) {
     895        void ForallPointerDecay_old::previsit( ObjectDecl *object ) {
    891896                // ensure that operator names only apply to functions or function pointers
    892897                if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) {
     
    896901        }
    897902
    898         void ForallPointerDecay::previsit( FunctionDecl *func ) {
     903        void ForallPointerDecay_old::previsit( FunctionDecl *func ) {
    899904                func->fixUniqueId();
    900905        }
    901906
    902         void ForallPointerDecay::previsit( FunctionType * ftype ) {
     907        void ForallPointerDecay_old::previsit( FunctionType * ftype ) {
    903908                forallFixer( ftype->forall, ftype );
    904909        }
    905910
    906         void ForallPointerDecay::previsit( StructDecl * aggrDecl ) {
     911        void ForallPointerDecay_old::previsit( StructDecl * aggrDecl ) {
    907912                forallFixer( aggrDecl->parameters, aggrDecl );
    908913        }
    909914
    910         void ForallPointerDecay::previsit( UnionDecl * aggrDecl ) {
     915        void ForallPointerDecay_old::previsit( UnionDecl * aggrDecl ) {
    911916                forallFixer( aggrDecl->parameters, aggrDecl );
    912917        }
     
    13681373        }
    13691374
    1370         const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) {
    1371                 #warning unimplemented
    1372                 (void)type; (void)symtab;
    1373                 assert(false);
    1374                 return nullptr;
    1375         }
     1375namespace {
     1376        /// Replaces enum types by int, and function/array types in function parameter and return
     1377        /// lists by appropriate pointers
     1378        struct EnumAndPointerDecay_new {
     1379                const ast::EnumDecl * previsit( const ast::EnumDecl * enumDecl ) {
     1380                        // set the type of each member of the enumeration to be EnumConstant
     1381                        for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) {
     1382                                // build new version of object with EnumConstant
     1383                                ast::ptr< ast::ObjectDecl > obj =
     1384                                        enumDecl->members[i].strict_as< ast::ObjectDecl >();
     1385                                obj.get_and_mutate()->type =
     1386                                        new ast::EnumInstType{ enumDecl->name, ast::CV::Const };
     1387                               
     1388                                // set into decl
     1389                                ast::EnumDecl * mut = mutate( enumDecl );
     1390                                mut->members[i] = obj.get();
     1391                                enumDecl = mut;
     1392                        }
     1393                        return enumDecl;
     1394                }
     1395
     1396                static const ast::FunctionType * fixFunctionList(
     1397                        const ast::FunctionType * func,
     1398                        std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field,
     1399                        ast::ArgumentFlag isVarArgs = ast::FixedArgs
     1400                ) {
     1401                        const auto & dwts = func->*field;
     1402                        unsigned nvals = dwts.size();
     1403                        bool hasVoid = false;
     1404                        for ( unsigned i = 0; i < nvals; ++i ) {
     1405                                func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) );
     1406                        }
     1407                       
     1408                        // the only case in which "void" is valid is where it is the only one in the list
     1409                        if ( hasVoid && ( nvals > 1 || isVarArgs ) ) {
     1410                                SemanticError(
     1411                                        dwts.front()->location, func, "invalid type void in function type" );
     1412                        }
     1413
     1414                        // one void is the only thing in the list, remove it
     1415                        if ( hasVoid ) {
     1416                                func = ast::mutate_field(
     1417                                        func, field, std::vector< ast::ptr< ast::DeclWithType > >{} );
     1418                        }
     1419
     1420                        return func;
     1421                }
     1422
     1423                const ast::FunctionType * previsit( const ast::FunctionType * func ) {
     1424                        func = fixFunctionList( func, &ast::FunctionType::params, func->isVarArgs );
     1425                        return fixFunctionList( func, &ast::FunctionType::returns );
     1426                }
     1427        };
     1428
     1429        /// Associates forward declarations of aggregates with their definitions
     1430        struct LinkReferenceToTypes_new final
     1431        : public ast::WithSymbolTable, public ast::WithGuards, public
     1432          ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting {
     1433               
     1434                const ast::SymbolTable * localSyms;
     1435
     1436                LinkReferenceToTypes_new( const ast::SymbolTable & syms ) : localSyms( &syms ) {}
     1437
     1438                #warning incomplete
     1439        };
     1440
     1441        /// Replaces array and function types in forall lists by appropriate pointer type and assigns
     1442        /// each object and function declaration a unique ID
     1443        struct ForallPointerDecay_new {
     1444                #warning incomplete
     1445        };
     1446} // anonymous namespace
     1447
     1448const ast::Type * validateType( const ast::Type * type, const ast::SymbolTable & symtab ) {
     1449        ast::Pass< EnumAndPointerDecay_new > epc;
     1450        ast::Pass< LinkReferenceToTypes_new > lrt{ symtab };
     1451        ast::Pass< ForallPointerDecay_new > fpd;
     1452
     1453        return type->accept( epc )->accept( lrt )->accept( fpd );
     1454}
     1455
    13761456} // namespace SymTab
    13771457
Note: See TracChangeset for help on using the changeset viewer.