Ignore:
Timestamp:
Feb 19, 2017, 10:20:13 AM (7 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
e7cc8cb
Parents:
317450e
Message:

add documentation to routine buildKRFunction

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/TypeData.cc

    r317450e ra7c4921  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Feb 16 15:06:59 2017
    13 // Update Count     : 455
     12// Last Modified On : Sun Feb 19 09:49:33 2017
     13// Update Count     : 467
    1414//
    1515
     
    776776} // buildFunction
    777777
     778// Transform KR routine declarations into C99 routine declarations:
     779//
     780//    rtn( a, b, c ) int a, c; double b {}  =>  int rtn( int a, double c, int b ) {}
     781//
     782// The type information for each post-declaration is moved to the corresponding pre-parameter and the post-declaration
     783// is deleted. Note, the order of the parameter names may not be the same as the declaration names. Duplicate names and
     784// extra names are disallowed.
     785//
     786// Note, there is no KR routine-prototype syntax:
     787//
     788//    rtn( a, b, c ) int a, c; double b; // invalid KR prototype
     789//    rtn(); // valid KR prototype
     790
    778791void buildKRFunction( const TypeData::Function_t & function ) {
    779792        assert( ! function.params );
    780         for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = dynamic_cast< DeclarationNode* >( decl->get_next() ) ) {
     793        // loop over declaration first as it is easier to spot errors
     794        for ( DeclarationNode * decl = function.oldDeclList; decl != nullptr; decl = dynamic_cast< DeclarationNode * >( decl->get_next() ) ) {
     795                // scan ALL parameter names for each declaration name to check for duplicates
    781796                for ( DeclarationNode * param = function.idList; param != nullptr; param = dynamic_cast< DeclarationNode* >( param->get_next() ) ) {
    782797                        if ( *decl->name == *param->name ) {
     798                                // type set => parameter name already transformed by a declaration names so there is a duplicate
     799                                // declaration name attempting a second transformation
    783800                                if ( param->type ) throw SemanticError( string( "duplicate declaration name " ) + *param->name );
     801                                // declaration type reset => declaration already transformed by a parameter name so there is a duplicate
     802                                // parameter name attempting a second transformation
    784803                                if ( ! decl->type ) throw SemanticError( string( "duplicate parameter name " ) + *param->name );
    785                                 param->type = decl->type;
    786                                 decl->type = nullptr;
    787                                 param->attributes.splice( param->attributes.end(), decl->attributes );
     804                                param->type = decl->type;                               // set copy declaration type to parameter type
     805                                decl->type = nullptr;                                   // reset declaration type
     806                                param->attributes.splice( param->attributes.end(), decl->attributes ); // copy and reset attributes from declaration to parameter
    788807                        } // if
    789808                } // for
     809                // declaration type still set => type not moved to a matching parameter so there is a missing parameter name
    790810                if ( decl->type ) throw SemanticError( string( "missing name in parameter list " ) + *decl->name );
    791811        } // for
     812
     813        // Parameter names without a declaration default to type int:
     814        //
     815        //    rtb( a, b, c ) const char * b; {} => int rtn( int a, const char * b, int c ) {}
     816
    792817        for ( DeclarationNode * param = function.idList; param != nullptr; param = dynamic_cast< DeclarationNode* >( param->get_next() ) ) {
    793                 if ( ! param->type ) {
     818                if ( ! param->type ) {                                                  // generate type int for empty parameters
    794819                        param->type = new TypeData( TypeData::Basic );
    795820                        param->type->basictype = DeclarationNode::Int;
     
    797822        } // for
    798823
    799         function.params = function.idList;
    800         function.idList = nullptr;
    801         delete function.oldDeclList;
    802         function.oldDeclList = nullptr;
     824        function.params = function.idList;                                      // newly modified idList becomes parameters
     825        function.idList = nullptr;                                                      // idList now empty
     826        delete function.oldDeclList;                                            // deletes entire list
     827        function.oldDeclList = nullptr;                                         // reset
    803828} // buildKRFunction
    804829
Note: See TracChangeset for help on using the changeset viewer.