Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/SymTab/Validate.cc

    rce8c12f rd24d4e1  
    3838//   definition occurs later in the input.
    3939
     40#include <algorithm>
     41#include <iterator>
    4042#include <list>
    41 #include <iterator>
     43
     44#include "CodeGen/CodeGenerator.h"
     45
     46#include "Common/PassVisitor.h"
    4247#include "Common/ScopedMap.h"
     48#include "Common/UniqueName.h"
    4349#include "Common/utility.h"
    44 #include "Common/UniqueName.h"
     50
    4551#include "Concurrency/Keywords.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"
     52
     53#include "GenPoly/DeclMutator.h"
     54
     55#include "InitTweak/InitTweak.h"
     56
     57#include "AddVisit.h"
     58#include "Autogen.h"
    5459#include "FixFunction.h"
    5560// #include "ImplementationType.h"
    56 #include "GenPoly/DeclMutator.h"
    57 #include "AddVisit.h"
     61#include "Indexer.h"
    5862#include "MakeLibCfa.h"
    5963#include "TypeEquality.h"
    60 #include "Autogen.h"
     64#include "Validate.h"
     65
    6166#include "ResolvExpr/typeops.h"
    62 #include <algorithm>
    63 #include "InitTweak/InitTweak.h"
    64 #include "CodeGen/CodeGenerator.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"
    6575
    6676#define debugPrint( x ) if ( doDebug ) { std::cout << x; }
     
    96106
    97107        /// Fix return types so that every function returns exactly one value
    98         class ReturnTypeFixer final : public Visitor {
    99           public:
    100                 typedef Visitor Parent;
    101                 using Parent::visit;
    102 
     108        struct ReturnTypeFixer {
    103109                static void fix( std::list< Declaration * > &translationUnit );
    104110
    105                 virtual void visit( FunctionDecl * functionDecl );
    106                 virtual void visit( FunctionType * ftype );
     111                void postvisit( FunctionDecl * functionDecl );
     112                void postvisit( FunctionType * ftype );
    107113        };
    108114
    109115        /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers.
    110         class EnumAndPointerDecayPass final : public Visitor {
    111                 typedef Visitor Parent;
    112                 virtual void visit( EnumDecl *aggregateDecl );
    113                 virtual void visit( FunctionType *func );
     116        struct EnumAndPointerDecay {
     117                void previsit( EnumDecl *aggregateDecl );
     118                void previsit( FunctionType *func );
    114119        };
    115120
     
    119124          public:
    120125                LinkReferenceToTypes( bool doDebug, const Indexer *indexer );
    121           private:
    122126                using Parent::visit;
    123127                void visit( EnumInstType *enumInst ) final;
     
    129133                void visit( UnionDecl *unionDecl ) final;
    130134                void visit( TypeInstType *typeInst ) final;
    131 
     135          private:
    132136                const Indexer *indexer;
    133137
     
    140144        };
    141145
    142         /// Replaces array and function types in forall lists by appropriate pointer type
    143         class Pass3 final : public Indexer {
     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 {
    144148                typedef Indexer Parent;
    145149          public:
    146150                using Parent::visit;
    147                 Pass3( const Indexer *indexer );
    148           private:
     151                ForallPointerDecay( const Indexer *indexer );
     152
    149153                virtual void visit( ObjectDecl *object ) override;
    150154                virtual void visit( FunctionDecl *func ) override;
     
    153157        };
    154158
    155         class ReturnChecker : public Visitor {
    156           public:
     159        struct ReturnChecker : public WithGuards {
    157160                /// Checks that return statements return nothing if their return type is void
    158161                /// and return something if the return type is non-void.
    159162                static void checkFunctionReturns( std::list< Declaration * > & translationUnit );
    160           private:
    161                 virtual void visit( FunctionDecl * functionDecl );
    162                 virtual void visit( ReturnStmt * returnStmt );
    163 
    164                 std::list< DeclarationWithType * > returnVals;
     163
     164                void previsit( FunctionDecl * functionDecl );
     165                void previsit( ReturnStmt * returnStmt );
     166
     167                typedef std::list< DeclarationWithType * > ReturnVals;
     168                ReturnVals returnVals;
    165169        };
    166170
     
    198202        };
    199203
    200         class VerifyCtorDtorAssign : public Visitor {
    201         public:
     204        struct VerifyCtorDtorAssign {
    202205                /// ensure that constructors, destructors, and assignment have at least one
    203206                /// parameter, the first of which must be a pointer, and that ctor/dtors have no
     
    205208                static void verify( std::list< Declaration * > &translationUnit );
    206209
    207                 virtual void visit( FunctionDecl *funcDecl );
    208         };
    209 
    210         class ArrayLength : public Visitor {
    211         public:
     210                void previsit( FunctionDecl *funcDecl );
     211        };
     212
     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 {
    212220                /// for array types without an explicit length, compute the length and store it so that it
    213221                /// is known to the rest of the phases. For example,
     
    219227                static void computeLength( std::list< Declaration * > & translationUnit );
    220228
    221                 virtual void visit( ObjectDecl * objDecl );
    222         };
    223 
    224         class CompoundLiteral final : public GenPoly::DeclMutator {
     229                void previsit( ObjectDecl * objDecl );
     230        };
     231
     232        struct CompoundLiteral final : public WithDeclsToAdd, public WithVisitorRef<CompoundLiteral> {
    225233                Type::StorageClasses storageClasses;
    226234
    227                 using GenPoly::DeclMutator::mutate;
    228                 DeclarationWithType * mutate( ObjectDecl *objectDecl ) final;
    229                 Expression *mutate( CompoundLiteralExpr *compLitExpr ) final;
     235                void premutate( ObjectDecl *objectDecl );
     236                Expression * postmutate( CompoundLiteralExpr *compLitExpr );
    230237        };
    231238
    232239        void validate( std::list< Declaration * > &translationUnit, bool doDebug ) {
    233                 EnumAndPointerDecayPass epc;
     240                PassVisitor<EnumAndPointerDecay> epc;
    234241                LinkReferenceToTypes lrt( doDebug, 0 );
    235                 Pass3 pass3( 0 );
    236                 CompoundLiteral compoundliteral;
    237 
    238                 HoistStruct::hoistStruct( translationUnit );
     242                ForallPointerDecay fpd( 0 );
     243                PassVisitor<CompoundLiteral> compoundliteral;
     244                PassVisitor<ValidateGenericParameters> genericParams;
     245
    239246                EliminateTypedef::eliminateTypedef( translationUnit );
     247                HoistStruct::hoistStruct( translationUnit ); // must happen after EliminateTypedef, so that aggregate typedefs occur in the correct order
    240248                ReturnTypeFixer::fix( translationUnit ); // must happen before autogen
    241249                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
    242251                acceptAll( translationUnit, epc ); // must happen before VerifyCtorDtorAssign, because void return objects should not exist
    243252                VerifyCtorDtorAssign::verify( translationUnit );  // must happen before autogen, because autogen examines existing ctor/dtors
    244253                Concurrency::applyKeywords( translationUnit );
    245                 autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecayPass
     254                autogenerateRoutines( translationUnit ); // moved up, used to be below compoundLiteral - currently needs EnumAndPointerDecay
    246255                Concurrency::implementMutexFuncs( translationUnit );
    247256                Concurrency::implementThreadStarter( translationUnit );
    248257                ReturnChecker::checkFunctionReturns( translationUnit );
    249                 compoundliteral.mutateDeclarationList( translationUnit );
    250                 acceptAll( translationUnit, pass3 );
     258                mutateAll( translationUnit, compoundliteral );
     259                acceptAll( translationUnit, fpd );
    251260                ArrayLength::computeLength( translationUnit );
    252261        }
    253262
    254263        void validateType( Type *type, const Indexer *indexer ) {
    255                 EnumAndPointerDecayPass epc;
     264                PassVisitor<EnumAndPointerDecay> epc;
    256265                LinkReferenceToTypes lrt( false, indexer );
    257                 Pass3 pass3( indexer );
     266                ForallPointerDecay fpd( indexer );
    258267                type->accept( epc );
    259268                type->accept( lrt );
    260                 type->accept( pass3 );
     269                type->accept( fpd );
    261270        }
    262271
     
    337346        }
    338347
    339         void EnumAndPointerDecayPass::visit( EnumDecl *enumDecl ) {
     348        void EnumAndPointerDecay::previsit( EnumDecl *enumDecl ) {
    340349                // Set the type of each member of the enumeration to be EnumConstant
    341350                for ( std::list< Declaration * >::iterator i = enumDecl->get_members().begin(); i != enumDecl->get_members().end(); ++i ) {
     
    344353                        obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->get_name() ) );
    345354                } // for
    346                 Parent::visit( enumDecl );
    347355        }
    348356
     
    351359                void fixFunctionList( DWTList & dwts, FunctionType * func ) {
    352360                        // the only case in which "void" is valid is where it is the only one in the list; then it should be removed
    353                         // entirely other fix ups are handled by the FixFunction class
     361                        // entirely. other fix ups are handled by the FixFunction class
    354362                        typedef typename DWTList::iterator DWTIterator;
    355363                        DWTIterator begin( dwts.begin() ), end( dwts.end() );
     
    370378                                for ( ; i != end; ++i ) {
    371379                                        FixFunction fixer;
    372                                         *i = (*i )->acceptMutator( fixer );
     380                                        *i = (*i)->acceptMutator( fixer );
    373381                                        if ( fixer.get_isVoid() ) {
    374382                                                throw SemanticError( "invalid type void in function type ", func );
     
    379387        }
    380388
    381         void EnumAndPointerDecayPass::visit( FunctionType *func ) {
     389        void EnumAndPointerDecay::previsit( FunctionType *func ) {
    382390                // Fix up parameters and return types
    383391                fixFunctionList( func->get_parameters(), func );
    384392                fixFunctionList( func->get_returnVals(), func );
    385                 Visitor::visit( func );
    386393        }
    387394
     
    496503        void LinkReferenceToTypes::visit( StructDecl *structDecl ) {
    497504                // 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)
    498506                Parent::visit( structDecl );
    499507                if ( ! structDecl->get_members().empty() ) {
     
    529537        }
    530538
    531         Pass3::Pass3( const Indexer *other_indexer ) :  Indexer( false ) {
     539        ForallPointerDecay::ForallPointerDecay( const Indexer *other_indexer ) :  Indexer( false ) {
    532540                if ( other_indexer ) {
    533541                        indexer = other_indexer;
     
    567575        }
    568576
    569         void Pass3::visit( ObjectDecl *object ) {
     577        void ForallPointerDecay::visit( ObjectDecl *object ) {
    570578                forallFixer( object->get_type() );
    571579                if ( PointerType *pointer = dynamic_cast< PointerType * >( object->get_type() ) ) {
     
    576584        }
    577585
    578         void Pass3::visit( FunctionDecl *func ) {
     586        void ForallPointerDecay::visit( FunctionDecl *func ) {
    579587                forallFixer( func->get_type() );
    580588                Parent::visit( func );
     
    583591
    584592        void ReturnChecker::checkFunctionReturns( std::list< Declaration * > & translationUnit ) {
    585                 ReturnChecker checker;
     593                PassVisitor<ReturnChecker> checker;
    586594                acceptAll( translationUnit, checker );
    587595        }
    588596
    589         void ReturnChecker::visit( FunctionDecl * functionDecl ) {
    590                 std::list< DeclarationWithType * > oldReturnVals = returnVals;
     597        void ReturnChecker::previsit( FunctionDecl * functionDecl ) {
     598                GuardValue( returnVals );
    591599                returnVals = functionDecl->get_functionType()->get_returnVals();
    592                 Visitor::visit( functionDecl );
    593                 returnVals = oldReturnVals;
    594         }
    595 
    596         void ReturnChecker::visit( ReturnStmt * returnStmt ) {
     600        }
     601
     602        void ReturnChecker::previsit( ReturnStmt * returnStmt ) {
    597603                // Previously this also checked for the existence of an expr paired with no return values on
    598604                // the  function return type. This is incorrect, since you can have an expression attached to
     
    804810
    805811        void VerifyCtorDtorAssign::verify( std::list< Declaration * > & translationUnit ) {
    806                 VerifyCtorDtorAssign verifier;
     812                PassVisitor<VerifyCtorDtorAssign> verifier;
    807813                acceptAll( translationUnit, verifier );
    808814        }
    809815
    810         void VerifyCtorDtorAssign::visit( FunctionDecl * funcDecl ) {
     816        void VerifyCtorDtorAssign::previsit( FunctionDecl * funcDecl ) {
    811817                FunctionType * funcType = funcDecl->get_functionType();
    812818                std::list< DeclarationWithType * > &returnVals = funcType->get_returnVals();
     
    818824                        }
    819825                        PointerType * ptrType = dynamic_cast< PointerType * >( params.front()->get_type() );
    820                         ReferenceType * refType = dynamic_cast< ReferenceType * >( params.front()->get_type() );
    821                         if ( ( ! ptrType && ! refType ) || ( ptrType && ptrType->is_array() ) ) {
     826                        if ( ! ptrType || ptrType->is_array() ) {
    822827                                throw SemanticError( "First parameter of a constructor, destructor, or assignment function must be a pointer ", funcDecl );
    823828                        }
     
    826831                        }
    827832                }
    828 
    829                 Visitor::visit( funcDecl );
    830         }
    831 
    832         DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {
     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 ) {
    833879                storageClasses = objectDecl->get_storageClasses();
    834                 DeclarationWithType * temp = Mutator::mutate( objectDecl );
    835                 return temp;
    836         }
    837 
    838         Expression *CompoundLiteral::mutate( CompoundLiteralExpr *compLitExpr ) {
     880        }
     881
     882        Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {
    839883                // transform [storage_class] ... (struct S){ 3, ... };
    840884                // into [storage_class] struct S temp =  { 3, ... };
    841885                static UniqueName indexName( "_compLit" );
    842886
    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 );
     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 );
    846890                delete compLitExpr;
    847                 DeclarationWithType * newtempvar = mutate( tempvar );
    848                 addDeclaration( newtempvar );                                   // add modified temporary to current block
    849                 return new VariableExpr( newtempvar );
     891                declsToAddBefore.push_back( tempvar );                                  // add modified temporary to current block
     892                return new VariableExpr( tempvar );
    850893        }
    851894
    852895        void ReturnTypeFixer::fix( std::list< Declaration * > &translationUnit ) {
    853                 ReturnTypeFixer fixer;
     896                PassVisitor<ReturnTypeFixer> fixer;
    854897                acceptAll( translationUnit, fixer );
    855898        }
    856899
    857         void ReturnTypeFixer::visit( FunctionDecl * functionDecl ) {
    858                 Parent::visit( functionDecl );
     900        void ReturnTypeFixer::postvisit( FunctionDecl * functionDecl ) {
    859901                FunctionType * ftype = functionDecl->get_functionType();
    860902                std::list< DeclarationWithType * > & retVals = ftype->get_returnVals();
     
    867909                                ret->set_name( toString( "_retval_", CodeGen::genName( functionDecl ) ) );
    868910                        }
    869                 }
    870         }
    871 
    872         void ReturnTypeFixer::visit( FunctionType * ftype ) {
     911                        ret->get_attributes().push_back( new Attribute( "unused" ) );
     912                }
     913        }
     914
     915        void ReturnTypeFixer::postvisit( FunctionType * ftype ) {
    873916                // xxx - need to handle named return values - this information needs to be saved somehow
    874917                // so that resolution has access to the names.
     
    888931
    889932        void ArrayLength::computeLength( std::list< Declaration * > & translationUnit ) {
    890                 ArrayLength len;
     933                PassVisitor<ArrayLength> len;
    891934                acceptAll( translationUnit, len );
    892935        }
    893936
    894         void ArrayLength::visit( ObjectDecl * objDecl ) {
     937        void ArrayLength::previsit( ObjectDecl * objDecl ) {
    895938                if ( ArrayType * at = dynamic_cast< ArrayType * >( objDecl->get_type() ) ) {
    896939                        if ( at->get_dimension() != nullptr ) return;
Note: See TracChangeset for help on using the changeset viewer.