Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    rd24d4e1 rce8c12f  
    3838//   definition occurs later in the input.
    3939
    40 #include <algorithm>
     40#include <list>
    4141#include <iterator>
    42 #include <list>
    43 
    44 #include "CodeGen/CodeGenerator.h"
    45 
    46 #include "Common/PassVisitor.h"
    4742#include "Common/ScopedMap.h"
     43#include "Common/utility.h"
    4844#include "Common/UniqueName.h"
    49 #include "Common/utility.h"
    50 
    5145#include "Concurrency/Keywords.h"
    52 
    53 #include "GenPoly/DeclMutator.h"
    54 
    55 #include "InitTweak/InitTweak.h"
    56 
    57 #include "AddVisit.h"
    58 #include "Autogen.h"
     46#include "Validate.h"
     47#include "SynTree/Visitor.h"
     48#include "SynTree/Mutator.h"
     49#include "SynTree/Type.h"
     50#include "SynTree/Expression.h"
     51#include "SynTree/Statement.h"
     52#include "SynTree/TypeSubstitution.h"
     53#include "Indexer.h"
    5954#include "FixFunction.h"
    6055// #include "ImplementationType.h"
    61 #include "Indexer.h"
     56#include "GenPoly/DeclMutator.h"
     57#include "AddVisit.h"
    6258#include "MakeLibCfa.h"
    6359#include "TypeEquality.h"
    64 #include "Validate.h"
    65 
     60#include "Autogen.h"
    6661#include "ResolvExpr/typeops.h"
    67 
    68 #include "SynTree/Attribute.h"
    69 #include "SynTree/Expression.h"
    70 #include "SynTree/Mutator.h"
    71 #include "SynTree/Statement.h"
    72 #include "SynTree/Type.h"
    73 #include "SynTree/TypeSubstitution.h"
    74 #include "SynTree/Visitor.h"
     62#include <algorithm>
     63#include "InitTweak/InitTweak.h"
     64#include "CodeGen/CodeGenerator.h"
    7565
    7666#define debugPrint( x ) if ( doDebug ) { std::cout << x; }
     
    10696
    10797        /// Fix return types so that every function returns exactly one value
    108         struct ReturnTypeFixer {
     98        class ReturnTypeFixer final : public Visitor {
     99          public:
     100                typedef Visitor Parent;
     101                using Parent::visit;
     102
    109103                static void fix( std::list< Declaration * > &translationUnit );
    110104
    111                 void postvisit( FunctionDecl * functionDecl );
    112                 void postvisit( FunctionType * ftype );
     105                virtual void visit( FunctionDecl * functionDecl );
     106                virtual void visit( FunctionType * ftype );
    113107        };
    114108
    115109        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    116         struct EnumAndPointerDecay {
    117                 void previsit( EnumDecl *aggregateDecl );
    118                 void previsit( FunctionType *func );
     110        class EnumAndPointerDecayPass final : public Visitor {
     111                typedef Visitor Parent;
     112                virtual void visit( EnumDecl *aggregateDecl );
     113                virtual void visit( FunctionType *func );
    119114        };
    120115
     
    124119          public:
    125120                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
     121          private:
    126122                using Parent::visit;
    127123                void visit( EnumInstType *enumInst ) final;
     
    133129                void visit( UnionDecl *unionDecl ) final;
    134130                void visit( TypeInstType *typeInst ) final;
    135           private:
     131
    136132                const Indexer *indexer;
    137133
     
    144140        };
    145141
    146         /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID.
    147         class ForallPointerDecay final : public Indexer {
     142        /// Replaces array and function types in forall lists by appropriate pointer type
     143        class Pass3 final : public Indexer {
    148144                typedef Indexer Parent;
    149145          public:
    150146                using Parent::visit;
    151                 ForallPointerDecay( const Indexer *indexer );
    152 
     147                Pass3( const Indexer *indexer );
     148          private:
    153149                virtual void visit( ObjectDecl *object ) override;
    154150                virtual void visit( FunctionDecl *func ) override;
     
    157153        };
    158154
    159         struct ReturnChecker : public WithGuards {
     155        class ReturnChecker : public Visitor {
     156          public:
    160157                /// Checks that return statements return nothing if their return type is void
    161158                /// and return something if the return type is non-void.
    162159                static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
    163 
    164                 void previsit( FunctionDecl * functionDecl );
    165                 void previsit( ReturnStmt * returnStmt );
    166 
    167                 typedef std::list< DeclarationWithType * > ReturnVals;
    168                 ReturnVals returnVals;
     160          private:
     161                virtual void visit( FunctionDecl * functionDecl );
     162                virtual void visit( ReturnStmt * returnStmt );
     163
     164                std::list< DeclarationWithType * > returnVals;
    169165        };
    170166
     
    202198        };
    203199
    204         struct VerifyCtorDtorAssign {
     200        class VerifyCtorDtorAssign : public Visitor {
     201        public:
    205202                /// ensure that constructors, destructors, and assignment have at least one
    206203                /// parameter, the first of which must be a pointer, and that ctor/dtors have no
     
    208205                static void verify( std::list< Declaration * > &translationUnit );
    209206
    210                 void previsit( FunctionDecl *funcDecl );
     207                virtual void visit( FunctionDecl *funcDecl );
    211208        };
    212209
    213         /// ensure that generic types have the correct number of type arguments
    214         struct ValidateGenericParameters {
    215                 void previsit( StructInstType * inst );
    216                 void previsit( UnionInstType * inst );
    217         };
    218 
    219         struct ArrayLength {
     210        class ArrayLength : public Visitor {
     211        public:
    220212                /// for array types without an explicit length, compute the length and store it so that it
    221213                /// is known to the rest of the phases. For example,
     
    227219                static void computeLength( std::list< Declaration * > & translationUnit );
    228220
    229                 void previsit( ObjectDecl * objDecl );
     221                virtual void visit( ObjectDecl * objDecl );
    230222        };
    231223
    232         struct CompoundLiteral final : public WithDeclsToAdd, public WithVisitorRef<CompoundLiteral> {
     224        class CompoundLiteral final : public GenPoly::DeclMutator {
    233225                Type::StorageClasses storageClasses;
    234226
    235                 void premutate( ObjectDecl *objectDecl );
    236                 Expression * postmutate( CompoundLiteralExpr *compLitExpr );
     227                using GenPoly::DeclMutator::mutate;
     228                DeclarationWithType * mutate( ObjectDecl *objectDecl ) final;
     229                Expression *mutate( CompoundLiteralExpr *compLitExpr ) final;
    237230        };
    238231
    239232        void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
    240                 PassVisitor<EnumAndPointerDecay> epc;
     233                EnumAndPointerDecayPass epc;
    241234                LinkReferenceToTypes lrt( doDebug, 0 );
    242                 ForallPointerDecay fpd( 0 );
    243                 PassVisitor<CompoundLiteral> compoundliteral;
    244                 PassVisitor<ValidateGenericParameters> genericParams;
    245 
     235                Pass3 pass3( 0 );
     236                CompoundLiteral compoundliteral;
     237
     238                HoistStruct::hoistStruct( translationUnit );
    246239                EliminateTypedef::eliminateTypedef( translationUnit );
    247                 HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
    248240                ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
    249241                acceptAll( translationUnit, lrt ); // must happen before autogen, because sized flag needs to propagate to generated functions
    250                 acceptAll( translationUnit, genericParams );  // check as early as possible - can't happen before LinkReferenceToTypes
    251242                acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist
    252243                VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    253244                Concurrency::applyKeywords( translationUnit );
    254                 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
     245                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecayPass
    255246                Concurrency::implementMutexFuncs( translationUnit );
    256247                Concurrency::implementThreadStarter( translationUnit );
    257248                ReturnChecker::checkFunctionReturns( translationUnit );
    258                 mutateAll( translationUnit, compoundliteral );
    259                 acceptAll( translationUnit, fpd );
     249                compoundliteral.mutateDeclarationList( translationUnit );
     250                acceptAll( translationUnit, pass3 );
    260251                ArrayLength::computeLength( translationUnit );
    261252        }
    262253
    263254        void validateType( Type *type, const Indexer *indexer ) {
    264                 PassVisitor<EnumAndPointerDecay> epc;
     255                EnumAndPointerDecayPass epc;
    265256                LinkReferenceToTypes lrt( false, indexer );
    266                 ForallPointerDecay fpd( indexer );
     257                Pass3 pass3( indexer );
    267258                type->accept( epc );
    268259                type->accept( lrt );
    269                 type->accept( fpd );
     260                type->accept( pass3 );
    270261        }
    271262
     
    346337        }
    347338
    348         void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) {
     339        void EnumAndPointerDecayPass::visit( EnumDecl *enumDecl ) {
    349340                // Set the type of each member of the enumeration to be EnumConstant
    350341                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
     
    353344                        obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->get_name() ) );
    354345                } // for
     346                Parent::visit( enumDecl );
    355347        }
    356348
     
    359351                void fixFunctionList( DWTList & dwts, FunctionType * func ) {
    360352                        // the only case in which "void" is valid is where it is the only one in the list; then it should be removed
    361                         // entirely. other fix ups are handled by the FixFunction class
     353                        // entirely other fix ups are handled by the FixFunction class
    362354                        typedef typename DWTList::iterator DWTIterator;
    363355                        DWTIterator begin( dwts.begin() ), end( dwts.end() );
     
    378370                                for ( ; i != end; ++i ) {
    379371                                        FixFunction fixer;
    380                                         *i = (*i)->acceptMutator( fixer );
     372                                        *i = (*i )->acceptMutator( fixer );
    381373                                        if ( fixer.get_isVoid() ) {
    382374                                                throw SemanticError( "invalid type void in function type ", func );
     
    387379        }
    388380
    389         void EnumAndPointerDecay::previsit( FunctionType *func ) {
     381        void EnumAndPointerDecayPass::visit( FunctionType *func ) {
    390382                // Fix up parameters and return types
    391383                fixFunctionList( func->get_parameters(), func );
    392384                fixFunctionList( func->get_returnVals(), func );
     385                Visitor::visit( func );
    393386        }
    394387
     
    503496        void LinkReferenceToTypes::visit( StructDecl *structDecl ) {
    504497                // visit struct members first so that the types of self-referencing members are updated properly
    505                 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and and their defaults)
    506498                Parent::visit( structDecl );
    507499                if ( ! structDecl->get_members().empty() ) {
     
    537529        }
    538530
    539         ForallPointerDecay::ForallPointerDecay( const Indexer *other_indexer ) :  Indexer( false ) {
     531        Pass3::Pass3( const Indexer *other_indexer ) :  Indexer( false ) {
    540532                if ( other_indexer ) {
    541533                        indexer = other_indexer;
     
    575567        }
    576568
    577         void ForallPointerDecay::visit( ObjectDecl *object ) {
     569        void Pass3::visit( ObjectDecl *object ) {
    578570                forallFixer( object->get_type() );
    579571                if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
     
    584576        }
    585577
    586         void ForallPointerDecay::visit( FunctionDecl *func ) {
     578        void Pass3::visit( FunctionDecl *func ) {
    587579                forallFixer( func->get_type() );
    588580                Parent::visit( func );
     
    591583
    592584        void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
    593                 PassVisitor<ReturnChecker> checker;
     585                ReturnChecker checker;
    594586                acceptAll( translationUnit, checker );
    595587        }
    596588
    597         void ReturnChecker::previsit( FunctionDecl * functionDecl ) {
    598                 GuardValue( returnVals );
     589        void ReturnChecker::visit( FunctionDecl * functionDecl ) {
     590                std::list< DeclarationWithType * > oldReturnVals = returnVals;
    599591                returnVals = functionDecl->get_functionType()->get_returnVals();
    600         }
    601 
    602         void ReturnChecker::previsit( ReturnStmt * returnStmt ) {
     592                Visitor::visit( functionDecl );
     593                returnVals = oldReturnVals;
     594        }
     595
     596        void ReturnChecker::visit( ReturnStmt * returnStmt ) {
    603597                // Previously this also checked for the existence of an expr paired with no return values on
    604598                // the  function return type. This is incorrect, since you can have an expression attached to
     
    810804
    811805        void VerifyCtorDtorAssign::verify( std::list< Declaration * > & translationUnit ) {
    812                 PassVisitor<VerifyCtorDtorAssign> verifier;
     806                VerifyCtorDtorAssign verifier;
    813807                acceptAll( translationUnit, verifier );
    814808        }
    815809
    816         void VerifyCtorDtorAssign::previsit( FunctionDecl * funcDecl ) {
     810        void VerifyCtorDtorAssign::visit( FunctionDecl * funcDecl ) {
    817811                FunctionType * funcType = funcDecl->get_functionType();
    818812                std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();
     
    824818                        }
    825819                        PointerType * ptrType = dynamic_cast< PointerType * >( params.front()->get_type() );
    826                         if ( ! ptrType || ptrType->is_array() ) {
     820                        ReferenceType * refType = dynamic_cast< ReferenceType * >( params.front()->get_type() );
     821                        if ( ( ! ptrType && ! refType ) || ( ptrType && ptrType->is_array() ) ) {
    827822                                throw SemanticError( "First parameter of a constructor, destructor, or assignment function must be a pointer ", funcDecl );
    828823                        }
     
    831826                        }
    832827                }
    833         }
    834 
    835         template< typename Aggr >
    836         void validateGeneric( Aggr * inst ) {
    837                 std::list< TypeDecl * > * params = inst->get_baseParameters();
    838                 if ( params != NULL ) {
    839                         std::list< Expression * > & args = inst->get_parameters();
    840 
    841                         // insert defaults arguments when a type argument is missing (currently only supports missing arguments at the end of the list).
    842                         // A substitution is used to ensure that defaults are replaced correctly, e.g.,
    843                         //   forall(otype T, otype alloc = heap_allocator(T)) struct vector;
    844                         //   vector(int) v;
    845                         // after insertion of default values becomes
    846                         //   vector(int, heap_allocator(T))
    847                         // and the substitution is built with T=int so that after substitution, the result is
    848                         //   vector(int, heap_allocator(int))
    849                         TypeSubstitution sub;
    850                         auto paramIter = params->begin();
    851                         for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) {
    852                                 if ( i < args.size() ) {
    853                                         TypeExpr * expr = safe_dynamic_cast< TypeExpr * >( *std::next( args.begin(), i ) );
    854                                         sub.add( (*paramIter)->get_name(), expr->get_type()->clone() );
    855                                 } else if ( i == args.size() ) {
    856                                         Type * defaultType = (*paramIter)->get_init();
    857                                         if ( defaultType ) {
    858                                                 args.push_back( new TypeExpr( defaultType->clone() ) );
    859                                                 sub.add( (*paramIter)->get_name(), defaultType->clone() );
    860                                         }
    861                                 }
    862                         }
    863 
    864                         sub.apply( inst );
    865                         if ( args.size() < params->size() ) throw SemanticError( "Too few type arguments in generic type ", inst );
    866                         if ( args.size() > params->size() ) throw SemanticError( "Too many type arguments in generic type ", inst );
    867                 }
    868         }
    869 
    870         void ValidateGenericParameters::previsit( StructInstType * inst ) {
    871                 validateGeneric( inst );
    872         }
    873 
    874         void ValidateGenericParameters::previsit( UnionInstType * inst ) {
    875                 validateGeneric( inst );
    876         }
    877 
    878         void CompoundLiteral::premutate( ObjectDecl *objectDecl ) {
     828
     829                Visitor::visit( funcDecl );
     830        }
     831
     832        DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {
    879833                storageClasses = objectDecl->get_storageClasses();
    880         }
    881 
    882         Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {
     834                DeclarationWithType * temp = Mutator::mutate( objectDecl );
     835                return temp;
     836        }
     837
     838        Expression *CompoundLiteral::mutate( CompoundLiteralExpr *compLitExpr ) {
    883839                // transform [storage_class] ... (struct S){ 3, ... };
    884840                // into [storage_class] struct S temp =  { 3, ... };
    885841                static UniqueName indexName( "_compLit" );
    886842
    887                 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );
    888                 compLitExpr->set_result( nullptr );
    889                 compLitExpr->set_initializer( nullptr );
     843                ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, 0, compLitExpr->get_result(), compLitExpr->get_initializer() );
     844                compLitExpr->set_result( 0 );
     845                compLitExpr->set_initializer( 0 );
    890846                delete compLitExpr;
    891                 declsToAddBefore.push_back( tempvar );                                  // add modified temporary to current block
    892                 return new VariableExpr( tempvar );
     847                DeclarationWithType * newtempvar = mutate( tempvar );
     848                addDeclaration( newtempvar );                                   // add modified temporary to current block
     849                return new VariableExpr( newtempvar );
    893850        }
    894851
    895852        void ReturnTypeFixer::fix( std::list< Declaration * > &translationUnit ) {
    896                 PassVisitor<ReturnTypeFixer> fixer;
     853                ReturnTypeFixer fixer;
    897854                acceptAll( translationUnit, fixer );
    898855        }
    899856
    900         void ReturnTypeFixer::postvisit( FunctionDecl * functionDecl ) {
     857        void ReturnTypeFixer::visit( FunctionDecl * functionDecl ) {
     858                Parent::visit( functionDecl );
    901859                FunctionType * ftype = functionDecl->get_functionType();
    902860                std::list< DeclarationWithType * > & retVals = ftype->get_returnVals();
     
    909867                                ret->set_name( toString( "_retval_", CodeGen::genName( functionDecl ) ) );
    910868                        }
    911                         ret->get_attributes().push_back( new Attribute( "unused" ) );
    912                 }
    913         }
    914 
    915         void ReturnTypeFixer::postvisit( FunctionType * ftype ) {
     869                }
     870        }
     871
     872        void ReturnTypeFixer::visit( FunctionType * ftype ) {
    916873                // xxx - need to handle named return values - this information needs to be saved somehow
    917874                // so that resolution has access to the names.
     
    931888
    932889        void ArrayLength::computeLength( std::list< Declaration * > & translationUnit ) {
    933                 PassVisitor<ArrayLength> len;
     890                ArrayLength len;
    934891                acceptAll( translationUnit, len );
    935892        }
    936893
    937         void ArrayLength::previsit( ObjectDecl * objDecl ) {
     894        void ArrayLength::visit( ObjectDecl * objDecl ) {
    938895                if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
    939896                        if ( at->get_dimension() != nullptr ) return;
Note: See TracChangeset for help on using the changeset viewer.