⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 defarg.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        }
    }
    return( expr );
}

boolean AddDefaultArgs(            // ADD DEFAULT ARGUMENTS, AS REQ'D
/*********************/
    SYMBOL func,                // - symbol being called
    PTREE expr )                // - expression for call
{
    SCOPE defarg_temps;         // scope containing defarg temps
    PTREE *args;                // addr( call arguments )
    PTREE init_node;            // node to setup function symbol
    PTREE func_node;            // node for function symbol
    PTREE arg;                  // new argument
    PTREE arg_locn;             // expr used to give locn for CO_LIST node
    TYPE arg_type;              // argument type in prototype
    arg_list *proto_without;    // function arg list without default arg
    arg_list *proto_with;       // function arg list with arg for def arg's value
    PTREE defarg_expr;          // expression for current default arg
    SYMBOL curr;                // loop variable
    SYMBOL stop;                // for loop stop condition
    RELOC_LIST *reloc_list;     // relocation list being built
    RELOC_LIST *reloc_elem;     // current relocation list element
    PTREE defarg_info;          // PTREE containing the expr and scope

    if( expr == NULL || expr->op == PT_ERROR ) {
        return TRUE;
    }
    arg_locn = expr;
    init_node = expr->u.subtree[0];
    func_node = init_node->u.subtree[0];
    if( func_node->op != PT_SYMBOL ) {
        /* virtual function calls (e.g., p->foo(1); ) */
        func_node = NULL;
    } else {
        /* normal named calls (e.g., foo(1); ) */
        func = func_node->u.symcg.symbol;
    }
    if( func->id == SC_DEFAULT ) {
        args = PTreeRefRight( expr );
        while( *args != NULL ) {
            args = PTreeRefLeft( *args );
        }
        arg = NULL;
        do {
            defarg_expr = NULL;
            reloc_list = NULL;
            defarg_info = retrieveIfDebug( func->u.defarg_info );
            if( NULL == defarg_info
             || defarg_info->u.type.next->op == PT_ERROR ) {
                PTreeErrorNode( expr );
                return FALSE;
            }
            defarg_temps = defarg_info->u.type.scope;
            if( defarg_temps != NULL && defarg_temps->ordered != NULL ) {
                curr = NULL;
                stop = ScopeOrderedStart( defarg_temps );
                for(;;) {
                    curr = ScopeOrderedNext( stop, curr );
                    if( curr == NULL ) break;

                    // build reloc-list
                    // that is, list of: [curr, dest]
                    // pass this list to copyRtn so that all references
                    // to curr can be changed to dest
                    reloc_elem = RingCarveAlloc( carveRELOC_LIST, &reloc_list );
                    reloc_elem->orig = curr;
                    // copy temps to CurrScope
                    reloc_elem->dest = SymCreateCurrScope( curr->sym_type
                                                         , curr->id
                                                         , curr->flag
                                                         , NameDummy() );
                    DbgAssert( reloc_elem->dest != NULL );
                }
            }
            // make copy of expr to use
            defarg_expr = PTreeCopyPrefix( defarg_info->u.type.next
                                         , &copyRtn
                                         , (void *)reloc_list );
            defarg_expr = PTreeCopySrcLocation( defarg_expr, arg_locn );
            if( reloc_list != NULL ) {
                RingCarveFree( carveRELOC_LIST, &reloc_list );
            }
            // coded like this to handle: foo( int = 0, ... )
            proto_without = TypeArgList( func->sym_type );
            proto_with = TypeArgList( func->thread->sym_type );
            arg_type = proto_with->type_list[ proto_without->num_args + 1 - 1 ];
            if( ! NodeConvertArgument( &defarg_expr, arg_type ) ) {
                PTreeErrorNode( defarg_expr );
                break;
            }
            defarg_expr = NodeArg( defarg_expr );
            *args = defarg_expr;
            args = &defarg_expr->u.subtree[0]; // used if more than one defarg
            func->flag |= SF_REFERENCED;
            func = func->thread;
        } while( func->id == SC_DEFAULT );
        SymSetNvReferenced( func );
        if( func_node != NULL ) {
            func_node->u.symcg.symbol = func; // put symbol without defargs at start of list
            func_node->type = func->sym_type;
            init_node->type = func->sym_type;
        }
    }
    return TRUE;
}

static void analyseDefaultExpr( // ANALYSE A DEFAULT ARGUMENT EXPRESSION
/*****************************/
    DECL_INFO *arg_dinfo )      // -declaration information
{
    TYPE type_ret;              // type to convert defarg expression to
    PTREE expr;                 // expression given for default argument
    PTREE defarg_info;          // default argument info (expr and scope)
    SYMBOL func;                // function with default arguments
    FUNCTION_DATA fn_data;

    expr = arg_dinfo->defarg_expr;
    type_ret = arg_dinfo->type;
    func = arg_dinfo->proto_sym;

    ExtraRptIncrementCtr( ctr_defargs );

    defarg_info = PTreeType( NULL );
    func->u.defarg_info = storeIfDebug(defarg_info);

    defarg_info->u.type.scope = ScopeBegin( SCOPE_FUNCTION );
    FunctionBodyDefargStartup(func, &fn_data);

    expr = AnalyseRawExpr( expr );
    if( expr->op != PT_ERROR ) {
        expr = CastImplicit( expr, type_ret, CNV_FUNC_DARG, &diagDefarg );
    }

#ifndef NDEBUG
    if( expr != NULL && expr->op != PT_ERROR ) {
        int complex = 1;
        switch( expr->op ) {
        case PT_INT_CONSTANT:
            ExtraRptIncrementCtr( ctr_defargs_intconst );
            complex = 0;
            break;
        case PT_FLOATING_CONSTANT:
            ExtraRptIncrementCtr( ctr_defargs_fpconst );
            complex = 0;
            break;
        default:
            if( NodeIsUnaryOp( expr, CO_FETCH ) ) {
                PTREE sub = expr->u.subtree[0];
                if( sub->op == PT_SYMBOL ) {
                    ExtraRptIncrementCtr( ctr_defargs_symbol );
                    complex = 0;
                }
            }
        }
        if( complex ) {
            ExtraRptIncrementCtr( ctr_defargs_complex );
        }
    }
#endif

    defarg_info->u.type.next = PTreeTraversePostfix( expr, &symCheck );

    FunctionBodyDefargShutdown(&fn_data);
    defarg_info->u.type.scope = ScopeEnd( SCOPE_FUNCTION );
}


void DefineDefaultValues( DECL_INFO *dinfo )
/******************************************/
{
    DECL_INFO *curr;

    RingIterBeg( dinfo->parms, curr ) {
        if( curr->type->id == TYP_DOT_DOT_DOT ) break;
        if( curr->has_defarg ) {
            DbgAssert( curr->defarg_expr != NULL );
            DbgAssert( curr->defarg_rewrite == NULL );
            analyseDefaultExpr( curr );
            curr->defarg_expr = NULL;
        }
    } RingIterEnd( curr )
}


void ProcessDefArgs( DECL_INFO *dinfo )
/*************************************/
{
    SCOPE save_scope;
    SCOPE scope;

    scope = SymScope( dinfo->sym );
    save_scope = GetCurrScope();
    SetCurrScope(scope);
    DefineDefaultValues( dinfo );
    FreeDeclInfo( dinfo );
    SetCurrScope(save_scope);
}


static void init(               // INITIALIZATION
    INITFINI* defn )            // - definition
{
    defn = defn;
    ExtraRptRegisterCtr( &ctr_defargs, "# defargs defined" );
    ExtraRptRegisterCtr( &ctr_defargs_intconst, "# defargs that are integral constants" );
    ExtraRptRegisterCtr( &ctr_defargs_fpconst, "# defargs that are floating point constants" );
    ExtraRptRegisterCtr( &ctr_defargs_symbol, "# defargs that are symbols" );
    ExtraRptRegisterCtr( &ctr_defargs_complex, "# defargs that are more complex" );
    DbgStmt( DefargList = NULL );
    carveRELOC_LIST = CarveCreate( sizeof( RELOC_LIST ), BLOCK_RELOC_LIST );
}

static void fini(               // COMPLETION
    INITFINI* defn )            // - definition
{
    defn = defn;
    DbgStmt( defargFreePtrees() );
    DbgStmt( CarveVerifyAllGone( carveRELOC_LIST, "RELOC_LIST" ) );
    CarveDestroy( carveRELOC_LIST );
    if( carveRELOC_LIST != NULL ) {
        carveRELOC_LIST = NULL;
    }
}

INITDEFN( defarg, init, fini );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -