static int _FinalizeClassMethods()

in LCM/codec/mof/parser/types.c [3412:3599]


static int _FinalizeClassMethods(
    void * mofstate,
    MI_ClassDecl* cd)
{
    size_t i, k;
    MOF_MethodList methodList = PTRARRAY_INITIALIZER;
    MOF_State * state = (MOF_State *)mofstate;

    /* First inherit methods from finalized super class */
    if (cd->superClass)
    {
        const MI_ClassDecl* super;
        
        /* Retrieve the super class */
        super = FindClassDecl(state, cd->superClass);

        if (!super)
        {
            yyerrorf(state->errhandler, ID_UNDEFINED_CLASS,
                "", 
                tcs(cd->superClass));
            return -1;
        }

        /* Propagate class qualifiers */
        {
            MI_Qualifier** qualifiers = NULL;
            MI_Uint32 numQualifiers = 0;

            /* This method overrides an inherited method */
            if (_FinalizeQualifiers(
                state,
                cd->name,
                NULL,
                cd->qualifiers,
                cd->numQualifiers,
                super->qualifiers,
                super->numQualifiers,
                &qualifiers,
                &numQualifiers) != 0)
            {
                return -1;
            }

            //MOF_Free(state, cd->qualifiers);
            cd->qualifiers = qualifiers;
            cd->numQualifiers = numQualifiers;
            cd->flags |= GetQualFlags(state, cd->qualifiers, cd->numQualifiers);
        }

        /* Clone the superclass method array */
        for (i = 0; i < super->numMethods; i++)
        {
            if (PtrArray_Append(state, (PtrArray*)(void*)&methodList, 
                super->methods[i]) != 0)
                return -1;
        }
    }

    /* Now append local methods (overriding as necessary) */
    for (i = 0; i < cd->numMethods; i++)
    {
        MI_MethodDecl* md = cd->methods[i];
        MI_Uint32 pos;

        /* Set hash code value to methoddecl if not has */
        if (md->code == 0)
        {
            md->code = Hash(md->name);
        }

        /* Set MI_MethodDecl.propagator */
        md->propagator = Batch_Tcsdup(state->batch, cd->name);

        /* See if the method is already in the list */

        pos = _FindMethodDecl(&methodList, md->name);

        if (pos == MOF_NOT_FOUND)
        {
            /* set default flavor to qualifers */
            for (k = 0; k < md->numQualifiers; k++)
            {
                md->qualifiers[k]->flavor = SetDefaultFlavors(md->qualifiers[k]->flavor);
            }

            /* First time this method has been seen in hierarchy */
            md->origin = Batch_Tcsdup(state->batch, cd->name);

            if (PtrArray_Append(state, (PtrArray*)(void*)&methodList, md) != 0)
                return -1;
        }
        else
        {
            MI_Qualifier** qualifiers;
            MI_Uint32 numQualifiers;

            _Analysis_assume_(methodList.data);

            /* This method overrides an inherited method */
            if (_FinalizeQualifiers(
                state,
                cd->name,
                md->name,
                md->qualifiers,
                md->numQualifiers,
                methodList.data[pos]->qualifiers,
                methodList.data[pos]->numQualifiers,
                &qualifiers,
                &numQualifiers) != 0)
            {
                return -1;
            }

            md->qualifiers = qualifiers;
            md->numQualifiers = numQualifiers;
            md->flags |= GetQualFlags(state, qualifiers, numQualifiers);

            md->origin = Batch_Tcsdup(state->batch, 
                methodList.data[pos]->origin);

            /* Use the superclass casing for the method name */
            md->name = methodList.data[pos]->name;
            methodList.data[pos] = md;
        }

        {
            size_t j;
            for(j = 0; j < md->numParameters; j++)
            {
                MI_Qualifier* embeddedQualifier = NULL;
                MI_ParameterDecl *pdecl = md->parameters[j];

                /* Set hash code value to parameterdecl if not has */
                if (pdecl->code == 0)
                {
                    pdecl->code = Hash(pdecl->name);
                }

                /* set default flavor to qualifers */
                for (k = 0; k < pdecl->numQualifiers; k++)
                {
                    pdecl->qualifiers[k]->flavor = SetDefaultFlavors(pdecl->qualifiers[k]->flavor);
                }

                pdecl->flags |= GetQualFlags(state, pdecl->qualifiers, pdecl->numQualifiers);

                _FindEmbeddedQualifier(pdecl->qualifiers, pdecl->numQualifiers, &embeddedQualifier);
                if (embeddedQualifier)
                {
                    if (pdecl->type == MI_STRING)
                    {
                        pdecl->type = MI_INSTANCE;
                    }
                    else if (pdecl->type == MI_STRINGA)
                    {
                        pdecl->type = MI_INSTANCEA;
                    }
                    else
                    {
                        yyerrorf(state->errhandler,
                            ID_PROPERTY_QUALIFIER_INCOMPATIBLE,
                            "",
                            embeddedQualifier->name,
                            pdecl->name,
                            _getTypeName_MI((MI_Type)pdecl->type));
                        return -1;
                    }

                    if (embeddedQualifier->type == MI_STRING)
                    {
                        pdecl->className = *(MI_Char**)embeddedQualifier->value;
                    }
                }
            }
        }

        /* Finalize method decl size and parameter offset */
        _FinalizeMethodSize(md);
    }

    /* Replace local method list with aggregate method list */
    //MOF_Free(state, cd->methods);
    cd->methods = methodList.data;
    cd->numMethods = methodList.size;

    return 0;
}