VirtualBox

Changeset 108342 in vbox


Ignore:
Timestamp:
Feb 24, 2025 10:21:58 AM (3 weeks ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
167701
Message:

libs/xpcom18a4/xpidl: Restore validation checks, bugref:10321

Location:
trunk/src/libs/xpcom18a4/xpcom/typelib/xpidl
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl.h

    r108340 r108342  
    395395
    396396/*
    397  * Verifies the interface declaration
    398  */
    399 DECLHIDDEN(bool) verify_interface_declaration(PCXPIDLNODE pNd);
    400 
    401 /*
    402397 * Find the underlying type of an identifier typedef.  Returns NULL
    403398 * (and doesn't complain) on failure.
     
    405400DECLHIDDEN(PCXPIDLNODE) find_underlying_type(PCXPIDLNODE pNd);
    406401
    407 #if 0
     402/*
     403 * Verifies the interface declaration
     404 */
     405DECLHIDDEN(int) verify_interface_declaration(PCXPIDLNODE pNd, PRTERRINFO pErrInfo);
     406
    408407/*
    409408 * Check that const declarations match their stated sign and are of the
    410409 * appropriate types.
    411410 */
    412 gboolean
    413 verify_const_declaration(IDL_tree const_tree);
     411DECLHIDDEN(int) verify_const_declaration(PCXPIDLNODE pNd, PRTERRINFO pErrInfo);
    414412
    415413/*
    416414 * Check that scriptable attributes in scriptable interfaces actually are.
    417415 */
    418 gboolean
    419 verify_attribute_declaration(IDL_tree method_tree);
     416DECLHIDDEN(int) verify_attribute_declaration(PCXPIDLNODE pNd, PRTERRINFO pErrInfo);
    420417
    421418/*
    422419 * Perform various validation checks on methods.
    423420 */
    424 gboolean
    425 verify_method_declaration(IDL_tree method_tree);
    426 #endif
     421DECLHIDDEN(int) verify_method_declaration(PCXPIDLNODE pNd, PRTERRINFO pErrInfo);
    427422
    428423/*
     
    430425 * it's of the form native <idl-name>(<c++-name>)
    431426 */
    432 DECLHIDDEN(bool) check_native(PCXPIDLNODE pNd);
     427DECLHIDDEN(int) check_native(PCXPIDLNODE pNd, PRTERRINFO pErrInfo);
    433428
    434429#endif /* __xpidl_h */
  • trunk/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_header.c

    r108340 r108342  
    393393
    394394
    395 static int xpidlHdrWriteMethod(PCXPIDLNODE pNd, FILE *pFile)
    396 {
    397 #if 0 /** @todo */
     395static int xpidlHdrWriteMethod(PCXPIDLNODE pNd, FILE *pFile, PRTERRINFO pErrInfo)
     396{
    398397    /*
    399398     * Verify that e.g. non-scriptable methods in [scriptable] interfaces
    400399     * are declared so.  Do this in a separate verification pass?
    401400     */
    402     if (!verify_method_declaration(state->tree))
    403         return FALSE;
    404 #endif
     401    int rc = verify_method_declaration(pNd, pErrInfo);
     402    if (RT_FAILURE(rc))
     403        return rc;
    405404
    406405    /* Dump the signature as a comment. */
     
    430429
    431430    write_indent(pFile);
    432     int rc = write_method_signature(pNd, pFile, true /*fDecl*/);
     431    rc = write_method_signature(pNd, pFile, true /*fDecl*/);
    433432    if (RT_FAILURE(rc))
    434433        return rc;
     
    475474}
    476475
    477 static int xpidlHdrWriteAttribute(PCXPIDLNODE pNd, FILE *pFile)
    478 {
    479 #if 0 /** @todo */
    480     if (!verify_attribute_declaration(state->tree))
    481         return FALSE;
    482 #endif
     476static int xpidlHdrWriteAttribute(PCXPIDLNODE pNd, FILE *pFile, PRTERRINFO pErrInfo)
     477{
     478    int rc = verify_attribute_declaration(pNd, pErrInfo);
     479    if (RT_FAILURE(rc))
     480        return rc;
    483481
    484482    /* Write the attribute as a comment. */
     
    492490
    493491    write_indent(pFile);
    494     int rc = xpidlHdrWriteAttrAccessor(pNd, pFile, true, true /*fDecl*/);
     492    rc = xpidlHdrWriteAttrAccessor(pNd, pFile, true, true /*fDecl*/);
    495493    if (RT_FAILURE(rc))
    496494        return rc;
     
    510508
    511509
    512 static int xpidlHdrWriteConst(PCXPIDLNODE pNd, FILE *pFile)
    513 {
    514 #if 0 /** @todo We only allow unsigned numbers for now. */
    515     if (!verify_const_declaration(pNd))
    516         return FALSE;
    517 #endif
     510static int xpidlHdrWriteConst(PCXPIDLNODE pNd, FILE *pFile, PRTERRINFO pErrInfo)
     511{
     512    int rc = verify_const_declaration(pNd, pErrInfo);
     513    if (RT_FAILURE(rc))
     514        return rc;
    518515
    519516    write_indent(pFile);
     
    536533    struct nsID id;
    537534    char iid_parsed[UUID_LENGTH];
    538     int rc = VINF_SUCCESS;
    539 
    540     if (!verify_interface_declaration(pNd))
    541         return VERR_INVALID_PARAMETER;
    542 
    543 #define FAIL    do {AssertFailed(); rc = VERR_INVALID_PARAMETER; goto out;} while(0)
     535
     536    int rc = verify_interface_declaration(pNd, pErrInfo);
     537    if (RT_FAILURE(rc))
     538        return rc;
     539
     540#define FAIL    do {/*AssertFailed();*/ rc = VERR_INVALID_PARAMETER; goto out;} while(0)
    544541
    545542    fprintf(pFile, "\n/* starting interface:    %s */\n", pNd->u.If.pszIfName);
     
    643640        {
    644641            case kXpidlNdType_Const:
    645                 rc = xpidlHdrWriteConst(pIt, pFile);
     642                rc = xpidlHdrWriteConst(pIt, pFile, pErrInfo);
    646643                if (RT_FAILURE(rc))
    647644                    FAIL;
    648645                break;
    649646            case kXpidlNdType_Attribute:
    650                 rc = xpidlHdrWriteAttribute(pIt, pFile);
     647                rc = xpidlHdrWriteAttribute(pIt, pFile, pErrInfo);
    651648                if (RT_FAILURE(rc))
    652649                    FAIL;
    653650                break;
    654651            case kXpidlNdType_Method:
    655                 rc = xpidlHdrWriteMethod(pIt, pFile);
     652                rc = xpidlHdrWriteMethod(pIt, pFile, pErrInfo);
    656653                if (RT_FAILURE(rc))
    657654                    FAIL;
  • trunk/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_idl.c

    r108340 r108342  
    607607static PCXPIDLNODE xpidlParseFindType(PXPIDLPARSE pThis, const char *pszName)
    608608{
     609    PCXPIDLNODE pIfFwd = NULL;
    609610    PCXPIDLNODE pIt;
    610611    RTListForEach(&pThis->LstNodes, pIt, XPIDLNODE, NdLst)
     
    622623            case kXpidlNdType_Interface_Forward_Decl:
    623624                if (!strcmp(pszName, pIt->u.pszIfFwdName))
    624                     return pIt;
     625                    pIfFwd = pIt; /* We will try finding the real definition before returning the forward declaration. */
    625626                break;
    626627            case kXpidlNdType_Interface_Def:
     
    633634    }
    634635
    635     return NULL;
     636    return pIfFwd;
    636637}
    637638
     
    13791380        free(outname);
    13801381    }
    1381     else
     1382
     1383    if (RT_FAILURE(rc))
    13821384        RTMsgError(ParseState.ErrInfo.Core.pszMsg);
    13831385
  • trunk/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_typelib.c

    r108340 r108342  
    979979    bool hidden = (xpidlNodeAttrFind(pNd, "noscript") != NULL);
    980980
    981     //if (!verify_attribute_declaration(state->tree))
    982     //    return VERR_NO_MEMORY;
     981    int rc = verify_attribute_declaration(pNd, pThis->pErrInfo);
     982    if (RT_FAILURE(rc))
     983        return rc;
    983984
    984985    if (!XPT_InterfaceDescriptorAddMethods(ARENA(pThis), id,
     
    988989    meth = &id->method_descriptors[NEXT_METH(pThis)];
    989990
    990     int rc = typelib_attr_accessor(pThis, pNd, meth, true, hidden);
     991    rc = typelib_attr_accessor(pThis, pNd, meth, true, hidden);
    991992    if (RT_FAILURE(rc))
    992993        return rc;
     
    10121013    bool op_noscript = (xpidlNodeAttrFind(pNd, "noscript") != NULL);
    10131014
    1014     //if (!verify_method_declaration(pNd))
    1015     //    return FALSE;
     1015    int rc = verify_method_declaration(pNd, pThis->pErrInfo);
     1016    if (RT_FAILURE(rc))
     1017        return rc;
    10161018
    10171019    if (!XPT_InterfaceDescriptorAddMethods(ARENA(pThis), id, 1))
     
    10941096    XPTConstDescriptor *cd;
    10951097
    1096     //if (!verify_const_declaration(state->tree))
    1097     //    return FALSE;
     1098    int rc = verify_const_declaration(pNd, pThis->pErrInfo);
     1099    if (RT_FAILURE(rc))
     1100        return rc;
    10981101
    10991102    /* Could be a typedef; try to map it to the real type. */
     
    11171120    fprintf(stderr, "DBG: adding const %s\n", cd->name);
    11181121#endif
    1119     int rc = fill_td_from_type(pThis, &cd->type, pNd->u.Const.pNdTypeSpec);
     1122    rc = fill_td_from_type(pThis, &cd->type, pNd->u.Const.pNdTypeSpec);
    11201123    if (RT_FAILURE(rc))
    11211124        return rc;
     
    12181221    This.pErrInfo = pErrInfo;
    12191222    int rc = typelib_prolog(&This, pInput, pParse);
    1220     AssertRC(rc);
    1221 
    12221223    if (RT_SUCCESS(rc))
    12231224    {
     
    12311232            {
    12321233                case kXpidlNdType_Native:
    1233                     if (!check_native(pIt))
    1234                         rc = VERR_INVALID_PARAMETER;
     1234                    rc = check_native(pIt, pErrInfo);
    12351235                    break;
    12361236                case kXpidlNdType_Interface_Def:
     
    12451245                    break;
    12461246            }
    1247             AssertRC(rc);
    12481247            if (RT_FAILURE(rc))
    12491248                break;
     
    12541253    }
    12551254
    1256     AssertRC(rc);
    12571255    return rc;
    12581256}
  • trunk/src/libs/xpcom18a4/xpcom/typelib/xpidl/xpidl_util.c

    r108340 r108342  
    146146}
    147147
    148 #if 0
    149 gboolean
    150 verify_const_declaration(IDL_tree const_tree) {
    151     struct _IDL_CONST_DCL *dcl = &IDL_CONST_DCL(const_tree);
    152     const char *name = IDL_IDENT(dcl->ident).str;
    153     IDL_tree real_type;
    154 
    155     /* const -> list -> interface */
    156     if (!IDL_NODE_UP(IDL_NODE_UP(const_tree)) ||
    157         IDL_NODE_TYPE(IDL_NODE_UP(IDL_NODE_UP(const_tree)))
    158         != IDLN_INTERFACE) {
    159         IDL_tree_error(const_tree,
    160                        "const declaration \'%s\' outside interface",
    161                        name);
    162         return FALSE;
    163     }
     148DECLHIDDEN(int) verify_const_declaration(PCXPIDLNODE pNd, PRTERRINFO pErrInfo)
     149{
     150    /* const must be inside an interface definition. */
     151    if (   !pNd->pParent
     152        || pNd->pParent->enmType != kXpidlNdType_Interface_Def)
     153        return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     154                             "const declaration \'%s\' outside interface",
     155                             pNd->u.Const.pszName);
    164156
    165157    /* Could be a typedef; try to map it to the real type. */
    166     real_type = find_underlying_type(dcl->const_type);
    167     real_type = real_type ? real_type : dcl->const_type;
    168     if (IDL_NODE_TYPE(real_type) == IDLN_TYPE_INTEGER &&
    169         (IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_SHORT ||
    170          IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG))
    171     {
    172         if (!IDL_TYPE_INTEGER(real_type).f_signed &&
    173             IDL_INTEGER(dcl->const_exp).value < 0)
    174         {
    175 #ifndef G_HAVE_GINT64
    176             /*
    177              * For platforms without longlong support turned on we can get
    178              * confused by the high bit of the long value and think that it
    179              * represents a negative value in an unsigned declaration.
    180              * In that case we don't know if it is the programmer who is
    181              * confused or the compiler. So we issue a warning instead of
    182              * an error.
    183              */
    184             if (IDL_TYPE_INTEGER(real_type).f_type == IDL_INTEGER_TYPE_LONG)
    185             {
    186                 XPIDL_WARNING((const_tree, IDL_WARNING1,
    187                               "unsigned const declaration \'%s\' "
    188                               "initialized with (possibly) negative constant",
    189                               name));
    190                 return TRUE;
    191             }
    192 #endif
    193             IDL_tree_error(const_tree,
    194                            "unsigned const declaration \'%s\' initialized with "
    195                            "negative constant",
    196                            name);
    197             return FALSE;
    198         }
    199     } else {
    200         IDL_tree_error(const_tree,
    201                        "const declaration \'%s\' must be of type short or long",
    202                        name);
    203         return FALSE;
    204     }
    205 
    206     return TRUE;
    207 }
    208 
    209 
    210 
    211 /*
    212  * This method consolidates error checking needed when coercing the XPIDL compiler
    213  * via the -t flag to generate output for a specific version of XPConnect.
    214  */
    215 static gboolean
    216 verify_type_fits_version(IDL_tree in_tree, IDL_tree error_tree)
    217 {
    218     if (major_version == 1 && minor_version == 1)
    219     {
    220         /* XPIDL Version 1.1 checks */
    221 
    222         /* utf8string, cstring, and astring types are not supported */
    223         if (IDL_tree_property_get(in_tree, "utf8string") != NULL ||
    224             IDL_tree_property_get(in_tree, "cstring")    != NULL ||
    225             IDL_tree_property_get(in_tree, "astring")    != NULL)
    226         {
    227             IDL_tree_error(error_tree,
    228                            "Cannot use [utf8string], [cstring] and [astring] "
    229                            "types when generating version 1.1 typelibs\n");
    230             return FALSE;
    231         }
    232     }
    233     return TRUE;
    234 }
    235 
    236 gboolean
    237 verify_attribute_declaration(IDL_tree attr_tree)
    238 {
    239     IDL_tree iface;
    240     IDL_tree ident;
    241     IDL_tree attr_type;
    242     gboolean scriptable_interface;
    243 
    244     /* We don't support attributes named IID, conflicts with static GetIID
     158    PCXPIDLNODE pNdType = find_underlying_type(pNd->u.Const.pNdTypeSpec);
     159    pNdType = pNdType ? pNdType : pNd->u.Const.pNdTypeSpec;
     160    if (   pNdType->enmType != kXpidlNdType_BaseType
     161        || (   pNdType->u.enmBaseType != kXpidlType_Short
     162            && pNdType->u.enmBaseType != kXpidlType_Long
     163            && pNdType->u.enmBaseType != kXpidlType_Unsigned_Short
     164            && pNdType->u.enmBaseType != kXpidlType_Unsigned_Long))
     165        return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     166                             "const declaration \'%s\' must be of type short or long",
     167                             pNd->u.Const.pszName);
     168
     169    return VINF_SUCCESS;
     170}
     171
     172
     173DECLHIDDEN(int) verify_attribute_declaration(PCXPIDLNODE pNd, PRTERRINFO pErrInfo)
     174{
     175    Assert(pNd->enmType == kXpidlNdType_Attribute);
     176
     177    /*
     178     * We don't support attributes named IID, conflicts with static GetIID
    245179     * member. The conflict is due to certain compilers (VC++) choosing a
    246180     * different vtable order, placing GetIID at the beginning regardless
    247181     * of it's placement
    248182     */
    249     if (strcmp(
    250         IDL_IDENT(
    251             IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).data).str,
    252         "IID") == 0) {
    253         IDL_tree_error(attr_tree,
    254                        "Attributes named IID not supported, causes vtable "
    255                        "ordering problems");
    256         return FALSE;
    257     }
     183    if (!strcmp(pNd->u.Attribute.pszName, "IID"))
     184        return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     185                             "Attributes named IID not supported, causes vtable ordering problems");
     186
    258187    /*
    259188     * Verify that we've been called on an interface, and decide if the
    260189     * interface was marked [scriptable].
    261190     */
    262     if (IDL_NODE_UP(attr_tree) && IDL_NODE_UP(IDL_NODE_UP(attr_tree)) &&
    263         IDL_NODE_TYPE(iface = IDL_NODE_UP(IDL_NODE_UP(attr_tree)))
    264         == IDLN_INTERFACE)
    265     {
    266         scriptable_interface =
    267             (IDL_tree_property_get(IDL_INTERFACE(iface).ident, "scriptable")
    268              != NULL);
    269     } else {
    270         IDL_tree_error(attr_tree,
    271                     "verify_attribute_declaration called on a non-interface?");
    272         return FALSE;
    273     }
    274 
    275     /*
    276      * Grab the first of the list of idents and hope that it'll
    277      * say scriptable or no.
    278      */
    279     ident = IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).data;
     191    bool fScriptable;
     192    if (   pNd->pParent
     193        && pNd->pParent->enmType == kXpidlNdType_Interface_Def)
     194        fScriptable = (xpidlNodeAttrFind(pNd->pParent, "scriptable") != NULL);
     195    else
     196        return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     197                             "verify_attribute_declaration called on a non-interface?");
    280198
    281199    /*
     
    283201     * there's no need to check.
    284202     */
    285     if (!scriptable_interface ||
    286         IDL_tree_property_get(ident, "noscript") != NULL)
    287         return TRUE;
     203    if (!fScriptable || !xpidlNodeAttrFind(pNd, "scriptable"))
     204        return VINF_SUCCESS;
    288205
    289206    /*
     
    291208     * domstring, utf8string, cstring, astring are exempted.
    292209     */
    293     attr_type = IDL_ATTR_DCL(attr_tree).param_type_spec;
    294 
    295     if (attr_type != NULL)
     210    PCXPIDLNODE pNdType = find_underlying_type(pNd->u.Attribute.pNdTypeSpec);
     211    pNdType = pNdType ? pNdType : pNd->u.Attribute.pNdTypeSpec;
     212    if (pNdType)
    296213    {
    297         if (UP_IS_NATIVE(attr_type) &&
    298             IDL_tree_property_get(attr_type, "nsid") == NULL &&
    299             IDL_tree_property_get(attr_type, "domstring") == NULL &&
    300             IDL_tree_property_get(attr_type, "utf8string") == NULL &&
    301             IDL_tree_property_get(attr_type, "cstring") == NULL &&
    302             IDL_tree_property_get(attr_type, "astring") == NULL)
    303         {
    304             IDL_tree_error(attr_tree,
    305                            "attributes in [scriptable] interfaces that are "
    306                            "non-scriptable because they refer to native "
    307                            "types must be marked [noscript]\n");
    308             return FALSE;
    309         }
     214        if (pNdType->enmType == kXpidlNdType_Native &&
     215            xpidlNodeAttrFind(pNdType, "nsid") == NULL &&
     216            xpidlNodeAttrFind(pNdType, "domstring") == NULL &&
     217            xpidlNodeAttrFind(pNdType, "utf8string") == NULL &&
     218            xpidlNodeAttrFind(pNdType, "cstring") == NULL &&
     219            xpidlNodeAttrFind(pNdType, "astring") == NULL)
     220            return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     221                                 "attributes in [scriptable] interfaces that are "
     222                                 "non-scriptable because they refer to native "
     223                                 "types must be marked [noscript]");
     224
    310225        /*
    311226         * We currently don't support properties of type nsid that aren't
     
    313228         * must be read-only
    314229         */
    315          
    316         if ((IDL_tree_property_get(ident, "notxpcom") == NULL || !(IDL_ATTR_DCL(attr_tree).f_readonly)) &&
    317             IDL_tree_property_get(attr_type,"nsid") != NULL &&
    318             IDL_tree_property_get(attr_type,"ptr") == NULL &&
    319             IDL_tree_property_get(attr_type,"ref") == NULL)
    320         {
    321             IDL_tree_error(attr_tree,
    322                            "Feature not currently supported: "
    323                            "attributes with a type of nsid must be marked "
    324                            "either [ptr] or [ref], or "
    325                            "else must be marked [notxpcom] "
    326                            "and must be read-only\n");
    327             return FALSE;
    328         }
    329 
    330         /*
    331          * Run additional error checks on the attribute type if targetting an
    332          * older version of XPConnect.
    333          */
    334 
    335         if (!verify_type_fits_version(attr_type, attr_tree))
    336             return FALSE;
    337     }
    338 
    339     if (IDL_LIST(IDL_ATTR_DCL(attr_tree).simple_declarations).next != NULL)
    340     {
    341         IDL_tree_error(attr_tree,
    342             "multiple attributes in a single declaration is not supported\n");
    343         return FALSE;
    344     }
    345     return TRUE;
    346 }
    347 #endif
     230        if (   (   xpidlNodeAttrFind(pNd, "notxpcom") == NULL
     231                || pNd->u.Attribute.fReadonly)
     232            && xpidlNodeAttrFind(pNdType,"nsid") != NULL
     233            && xpidlNodeAttrFind(pNdType,"ptr") == NULL
     234            && xpidlNodeAttrFind(pNdType,"ref") == NULL)
     235            return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     236                                 "Feature not currently supported: "
     237                                 "attributes with a type of nsid must be marked either [ptr] or [ref], or "
     238                                 "else must be marked [notxpcom] and must be read-only\n");
     239    }
     240
     241    return VINF_SUCCESS;
     242}
     243
    348244
    349245/*
     
    365261
    366262
    367 #if 0
    368 static IDL_tree /* IDL_PARAM_DCL */
    369 find_named_parameter(IDL_tree method_tree, const char *param_name)
    370 {
    371     IDL_tree iter;
    372     for (iter = IDL_OP_DCL(method_tree).parameter_dcls; iter;
    373          iter = IDL_LIST(iter).next)
     263static PCXPIDLNODE find_named_parameter(PCXPIDLNODE pNdMethod, const char *param_name)
     264{
     265    PCXPIDLNODE pIt;
     266    RTListForEach(&pNdMethod->u.Method.LstParams, pIt, XPIDLNODE, NdLst)
    374267    {
    375         IDL_tree param = IDL_LIST(iter).data;
    376         IDL_tree simple_decl = IDL_PARAM_DCL(param).simple_declarator;
    377         const char *current_name = IDL_IDENT(simple_decl).str;
    378         if (strcmp(current_name, param_name) == 0)
    379             return param;
     268        Assert(pIt->enmType == kXpidlNdType_Parameter);
     269        if (!strcmp(pIt->u.Param.pszName, param_name))
     270            return pIt;
    380271    }
    381272    return NULL;
     
    392283 * refer to parameters of the appropriate type.
    393284 */
    394 static gboolean
    395 check_param_attribute(IDL_tree method_tree, IDL_tree param,
    396                       ParamAttrType whattocheck)
    397 {
    398     const char *referred_name = NULL;
    399     IDL_tree simple_decl = IDL_PARAM_DCL(param).simple_declarator;
     285static int check_param_attribute(PCXPIDLNODE pNdMethod, PCXPIDLNODE pNdParam,
     286                                 ParamAttrType whattocheck, PRTERRINFO pErrInfo)
     287{
    400288    const char *attr_name;
    401289    const char *needed_type;
     
    411299        needed_type = "unsigned long (or PRUint32)";
    412300    } else {
    413         XPT_ASSERT("asked to check an unknown attribute type!");
    414         return TRUE;
     301        AssertMsgFailed(("asked to check an unknown attribute type!"));
     302        return VINF_SUCCESS;
    415303    }
    416304   
    417     referred_name = IDL_tree_property_get(simple_decl, attr_name);
    418     if (referred_name != NULL) {
    419         IDL_tree referred_param = find_named_parameter(method_tree,
     305    PCXPIDLATTR pAttr = xpidlNodeAttrFind(pNdParam, attr_name);
     306    if (pAttr != NULL)
     307    {
     308        const char *referred_name = pAttr->pszVal;
     309
     310        PCXPIDLNODE pNdParamRef = find_named_parameter(pNdMethod,
    420311                                                       referred_name);
    421         IDL_tree referred_param_type;
    422         if (referred_param == NULL) {
    423             IDL_tree_error(method_tree,
    424                            "attribute [%s(%s)] refers to missing "
    425                            "parameter \"%s\"",
    426                            attr_name, referred_name, referred_name);
    427             return FALSE;
    428         }
    429         if (referred_param == param) {
    430             IDL_tree_error(method_tree,
    431                            "attribute [%s(%s)] refers to it's own parameter",
    432                            attr_name, referred_name);
    433             return FALSE;
    434         }
     312        if (!pNdParamRef)
     313            return xpidlIdlError(pErrInfo, pNdParam, VERR_INVALID_STATE,
     314                                 "attribute [%s(%s)] refers to missing parameter \"%s\"",
     315                                 attr_name, referred_name, referred_name);
     316
     317        if (pNdParamRef == pNdParam)
     318            return xpidlIdlError(pErrInfo, pNdParam, VERR_INVALID_STATE,
     319                                 "attribute [%s(%s)] refers to it's own parameter",
     320                                 attr_name, referred_name);
    435321       
    436         referred_param_type = IDL_PARAM_DCL(referred_param).param_type_spec;
    437         if (whattocheck == IID_IS) {
     322        PCXPIDLNODE pNdTypeSpec = find_underlying_type(pNdParamRef->u.Param.pNdTypeSpec);
     323        pNdTypeSpec = pNdTypeSpec ? pNdTypeSpec : pNdParamRef->u.Param.pNdTypeSpec;
     324        if (whattocheck == IID_IS)
     325        {
    438326            /* require IID type */
    439             if (IDL_tree_property_get(referred_param_type, "nsid") == NULL) {
    440                 IDL_tree_error(method_tree,
     327            if (!xpidlNodeAttrFind(pNdTypeSpec, "nsid"))
     328                return xpidlIdlError(pErrInfo, pNdParamRef, VERR_INVALID_STATE,
    441329                               "target \"%s\" of [%s(%s)] attribute "
    442330                               "must be of %s type",
    443331                               referred_name, attr_name, referred_name,
    444332                               needed_type);
    445                 return FALSE;
    446             }
    447         } else if (whattocheck == LENGTH_IS || whattocheck == SIZE_IS) {
    448             /* require PRUint32 type */
    449             IDL_tree real_type;
    450 
    451             /* Could be a typedef; try to map it to the real type. */
    452             real_type = find_underlying_type(referred_param_type);
    453             real_type = real_type ? real_type : referred_param_type;
    454 
    455             if (IDL_NODE_TYPE(real_type) != IDLN_TYPE_INTEGER ||
    456                 IDL_TYPE_INTEGER(real_type).f_signed != FALSE ||
    457                 IDL_TYPE_INTEGER(real_type).f_type != IDL_INTEGER_TYPE_LONG)
    458             {
    459                 IDL_tree_error(method_tree,
    460                                "target \"%s\" of [%s(%s)] attribute "
    461                                "must be of %s type",
    462                                referred_name, attr_name, referred_name,
    463                                needed_type);
    464 
    465                 return FALSE;
    466             }
    467333        }
    468     }
    469 
    470     return TRUE;
     334        else if (whattocheck == LENGTH_IS || whattocheck == SIZE_IS)
     335        {
     336            PCXPIDLNODE pNdType = find_underlying_type(pNdTypeSpec);
     337            pNdType = pNdType ? pNdType : pNdTypeSpec;
     338
     339            if (   pNdType->enmType != kXpidlNdType_BaseType
     340                || pNdType->u.enmBaseType != kXpidlType_Unsigned_Long)
     341                return xpidlIdlError(pErrInfo, pNdParamRef, VERR_INVALID_STATE,
     342                                     "target \"%s\" of [%s(%s)] attribute "
     343                                     "must be of %s type",
     344                                     referred_name, attr_name, referred_name,
     345                                     needed_type);
     346        }
     347    }
     348
     349    return VINF_SUCCESS;
    471350}
    472351
     
    475354 * Common method verification code, called by *op_dcl in the various backends.
    476355 */
    477 gboolean
    478 verify_method_declaration(IDL_tree method_tree)
    479 {
    480     struct _IDL_OP_DCL *op = &IDL_OP_DCL(method_tree);
    481     IDL_tree iface;
    482     IDL_tree iter;
    483     gboolean notxpcom;
    484     gboolean scriptable_interface;
    485     gboolean scriptable_method;
    486     gboolean seen_retval = FALSE;
    487     const char *method_name = IDL_IDENT(IDL_OP_DCL(method_tree).ident).str;
    488 
    489     /* We don't support attributes named IID, conflicts with static GetIID
     356DECLHIDDEN(int) verify_method_declaration(PCXPIDLNODE pNd, PRTERRINFO pErrInfo)
     357{
     358    Assert(pNd->enmType == kXpidlNdType_Method);
     359    bool notxpcom;
     360    bool scriptable_interface;
     361    bool scriptable_method;
     362    bool seen_retval = false;
     363
     364    /*
     365     * We don't support attributes named IID, conflicts with static GetIID
    490366     * member. The conflict is due to certain compilers (VC++) choosing a
    491367     * different vtable order, placing GetIID at the beginning regardless
    492368     * of it's placement
    493369     */
    494     if (strcmp(method_name, "GetIID") == 0) {
    495         IDL_tree_error(method_tree,
    496                        "Methods named GetIID not supported, causes vtable "
    497                        "ordering problems");
    498         return FALSE;
    499     }
    500     if (op->f_varargs) {
    501         /* We don't currently support varargs. */
    502         IDL_tree_error(method_tree, "varargs are not currently supported");
    503         return FALSE;
    504     }
     370    if (!strcmp(pNd->u.Method.pszName, "GetIID"))
     371        return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     372                             "Methods named GetIID not supported, causes vtable "
     373                             "ordering problems");
    505374
    506375    /*
     
    508377     * interface was marked [scriptable].
    509378     */
    510     if (IDL_NODE_UP(method_tree) && IDL_NODE_UP(IDL_NODE_UP(method_tree)) &&
    511         IDL_NODE_TYPE(iface = IDL_NODE_UP(IDL_NODE_UP(method_tree)))
    512         == IDLN_INTERFACE)
    513     {
    514         scriptable_interface =
    515             (IDL_tree_property_get(IDL_INTERFACE(iface).ident, "scriptable")
    516              != NULL);
    517     } else {
    518         IDL_tree_error(method_tree,
    519                        "verify_method_declaration called on a non-interface?");
    520         return FALSE;
    521     }
     379    if (   pNd->pParent
     380        && pNd->pParent->enmType == kXpidlNdType_Interface_Def)
     381        scriptable_interface = (xpidlNodeAttrFind(pNd->pParent, "scriptable") != NULL);
     382    else
     383        return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     384                             "verify_method_declaration called on a non-interface?");
    522385
    523386    /*
     
    529392     * to unsigned long.
    530393     */
    531     notxpcom = IDL_tree_property_get(op->ident, "notxpcom") != NULL;
    532 
    533     scriptable_method = scriptable_interface &&
    534         !notxpcom &&
    535         IDL_tree_property_get(op->ident, "noscript") == NULL;
     394    notxpcom = xpidlNodeAttrFind(pNd, "notxpcom") != NULL;
     395
     396    scriptable_method =    scriptable_interface
     397                        && !notxpcom
     398                        && xpidlNodeAttrFind(pNd, "noscript") == NULL;
    536399
    537400    /* Loop through the parameters and check. */
    538     for (iter = op->parameter_dcls; iter; iter = IDL_LIST(iter).next) {
    539         IDL_tree param = IDL_LIST(iter).data;
    540         IDL_tree param_type =
    541             IDL_PARAM_DCL(param).param_type_spec;
    542         IDL_tree simple_decl =
    543             IDL_PARAM_DCL(param).simple_declarator;
    544         const char *param_name = IDL_IDENT(simple_decl).str;
     401    PCXPIDLNODE pIt;
     402    RTListForEach(&pNd->u.Method.LstParams, pIt, XPIDLNODE, NdLst)
     403    {
     404        int rc;
     405
     406        PCXPIDLNODE pNdTypeSpec = find_underlying_type(pIt->u.Param.pNdTypeSpec);
     407        pNdTypeSpec = pNdTypeSpec ? pNdTypeSpec : pIt->u.Param.pNdTypeSpec;
    545408       
    546409        /*
     
    549412         * cstring, astring or iid_is.
    550413         */
    551         if (scriptable_method &&
    552             UP_IS_NATIVE(param_type) &&
    553             IDL_tree_property_get(param_type, "nsid") == NULL &&
    554             IDL_tree_property_get(simple_decl, "iid_is") == NULL &&
    555             IDL_tree_property_get(param_type, "domstring") == NULL &&
    556             IDL_tree_property_get(param_type, "utf8string") == NULL &&
    557             IDL_tree_property_get(param_type, "cstring") == NULL &&
    558             IDL_tree_property_get(param_type, "astring") == NULL)
    559         {
    560             IDL_tree_error(method_tree,
     414        if (   scriptable_method
     415            && pNdTypeSpec->enmType == kXpidlNdType_Native
     416            && xpidlNodeAttrFind(pNdTypeSpec, "nsid") == NULL
     417            && xpidlNodeAttrFind(pIt, "iid_is") == NULL
     418            && xpidlNodeAttrFind(pNdTypeSpec, "domstring") == NULL
     419            && xpidlNodeAttrFind(pNdTypeSpec, "utf8string") == NULL
     420            && xpidlNodeAttrFind(pNdTypeSpec, "cstring") == NULL
     421            && xpidlNodeAttrFind(pNdTypeSpec, "astring") == NULL)
     422            return xpidlIdlError(pErrInfo, pIt, VERR_INVALID_STATE,
    561423                           "methods in [scriptable] interfaces that are "
    562424                           "non-scriptable because they refer to native "
    563425                           "types (parameter \"%s\") must be marked "
    564                            "[noscript]", param_name);
    565             return FALSE;
    566         }
     426                           "[noscript]", pIt->u.Param.pszName);
    567427
    568428        /*
     
    571431         * as input parameters
    572432         */
    573         if (!(notxpcom && IDL_PARAM_DCL(param).attr != IDL_PARAM_IN) &&
    574             IDL_tree_property_get(param_type, "nsid") != NULL &&
    575             IDL_tree_property_get(param_type, "ptr") == NULL &&
    576             IDL_tree_property_get(param_type, "ref") == NULL)
    577         {
    578             IDL_tree_error(method_tree,
    579                            "Feature currently not supported: "
    580                            "parameter \"%s\" is of type nsid and "
    581                            "must be marked either [ptr] or [ref] "
    582                            "or method \"%s\" must be marked [notxpcom] "
    583                            "and must not be an input parameter",
    584                            param_name,
    585                            method_name);
    586             return FALSE;
    587         }
     433        if (   !(   notxpcom
     434                 && pIt->u.Param.enmDir != kXpidlDirection_In)
     435            && xpidlNodeAttrFind(pNdTypeSpec, "nsid") != NULL
     436            && xpidlNodeAttrFind(pNdTypeSpec, "ptr") == NULL
     437            && xpidlNodeAttrFind(pNdTypeSpec, "ref") == NULL)
     438            return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     439                                 "Feature currently not supported: "
     440                                 "parameter \"%s\" is of type nsid and "
     441                                 "must be marked either [ptr] or [ref] "
     442                                 "or method \"%s\" must be marked [notxpcom] "
     443                                 "and must not be an input parameter",
     444                                 pIt->u.Param.pszName, pNd->u.Method.pszName);
     445
    588446        /*
    589447         * Sanity checks on return values.
    590448         */
    591         if (IDL_tree_property_get(simple_decl, "retval") != NULL) {
    592             if (IDL_LIST(iter).next != NULL) {
    593                 IDL_tree_error(method_tree,
    594                                "only the last parameter can be marked [retval]");
    595                 return FALSE;
    596             }
    597             if (op->op_type_spec) {
    598                 IDL_tree_error(method_tree,
    599                                "can't have [retval] with non-void return type");
    600                 return FALSE;
    601             }
     449        if (xpidlNodeAttrFind(pIt, "retval") != NULL)
     450        {
     451            if (!RTListNodeIsLast(&pNd->u.Method.LstParams, &pIt->NdLst))
     452                return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     453                                     "only the last parameter can be marked [retval]");
     454
     455            if (   pNd->u.Method.pNdTypeSpecRet->enmType != kXpidlNdType_BaseType
     456                || pNd->u.Method.pNdTypeSpecRet->u.enmBaseType != kXpidlType_Void)
     457                return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     458                                     "can't have [retval] with non-void return type");
     459
    602460            /* In case XPConnect relaxes the retval-is-last restriction. */
    603             if (seen_retval) {
    604                 IDL_tree_error(method_tree,
    605                                "can't have more than one [retval] parameter");
    606                 return FALSE;
    607             }
    608             seen_retval = TRUE;
     461            if (seen_retval)
     462                return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     463                                     "can't have more than one [retval] parameter");
     464
     465            seen_retval = true;
    609466        }
    610467
     
    614471         * and can't be used with [array].
    615472         */
    616         if (IDL_tree_property_get(simple_decl, "shared") != NULL) {
    617             IDL_tree real_type;
    618             real_type = find_underlying_type(param_type);
    619             real_type = real_type ? real_type : param_type;
    620 
    621             if (IDL_tree_property_get(simple_decl, "array") != NULL) {
    622                 IDL_tree_error(method_tree,
    623                                "[shared] parameter \"%s\" cannot "
    624                                "be of array type", param_name);
    625                 return FALSE;
    626             }               
    627 
    628             if (!(IDL_NODE_TYPE(real_type) == IDLN_TYPE_STRING ||
    629                   IDL_NODE_TYPE(real_type) == IDLN_TYPE_WIDE_STRING ||
    630                   (UP_IS_NATIVE(real_type) &&
    631                    !IDL_tree_property_get(real_type, "nsid") &&
    632                    !IDL_tree_property_get(real_type, "domstring")  &&
    633                    !IDL_tree_property_get(real_type, "utf8string") &&
    634                    !IDL_tree_property_get(real_type, "cstring")    &&
    635                    !IDL_tree_property_get(real_type, "astring"))))
    636             {
    637                 IDL_tree_error(method_tree,
    638                                "[shared] parameter \"%s\" must be of type "
    639                                "string, wstring or native", param_name);
    640                 return FALSE;
    641             }
     473        if (xpidlNodeAttrFind(pIt, "shared") != NULL)
     474        {
     475            if (xpidlNodeAttrFind(pIt, "array") != NULL)
     476                return xpidlIdlError(pErrInfo, pIt, VERR_INVALID_STATE,
     477                                     "[shared] parameter \"%s\" cannot be of array type",
     478                                     pIt->u.Param.pszName);
     479
     480            if (   !(   pNdTypeSpec->enmType == kXpidlNdType_BaseType
     481                     && (   pNdTypeSpec->u.enmBaseType == kXpidlType_String
     482                         || pNdTypeSpec->u.enmBaseType == kXpidlType_Wide_String))
     483                && !(   pNdTypeSpec->enmType == kXpidlNdType_Native
     484                     && (   !xpidlNodeAttrFind(pNdTypeSpec, "nsid")
     485                         && !xpidlNodeAttrFind(pNdTypeSpec, "domstring")
     486                         && !xpidlNodeAttrFind(pNdTypeSpec, "utf8string")
     487                         && !xpidlNodeAttrFind(pNdTypeSpec, "cstring")
     488                         && !xpidlNodeAttrFind(pNdTypeSpec, "astring"))))
     489                return xpidlIdlError(pErrInfo, pIt, VERR_INVALID_STATE,
     490                                     "[shared] parameter \"%s\" must be of type "
     491                                     "string, wstring or native", pIt->u.Param.pszName);
    642492        }
    643493
     
    646496         * and "AString" types
    647497         */
    648         if (IDL_PARAM_DCL(param).attr == IDL_PARAM_INOUT &&
    649             UP_IS_NATIVE(param_type) &&
    650             (IDL_tree_property_get(param_type, "domstring")  != NULL ||
    651              IDL_tree_property_get(param_type, "utf8string") != NULL ||
    652              IDL_tree_property_get(param_type, "cstring")    != NULL ||
    653              IDL_tree_property_get(param_type, "astring")    != NULL )) {
    654             IDL_tree_error(method_tree,
    655                            "[domstring], [utf8string], [cstring], [astring] "
    656                            "types cannot be used as inout parameters");
    657             return FALSE;
    658         }
    659 
     498        if (   pIt->u.Param.enmDir == kXpidlDirection_InOut
     499            && pNdTypeSpec->enmType == kXpidlNdType_Native
     500            && (   xpidlNodeAttrFind(pNdTypeSpec, "domstring")  != NULL
     501                || xpidlNodeAttrFind(pNdTypeSpec, "utf8string") != NULL
     502                || xpidlNodeAttrFind(pNdTypeSpec, "cstring")    != NULL
     503                || xpidlNodeAttrFind(pNdTypeSpec, "astring")    != NULL))
     504            return xpidlIdlError(pErrInfo, pIt, VERR_INVALID_STATE,
     505                                 "[domstring], [utf8string], [cstring], [astring] "
     506                                 "types cannot be used as inout parameters");
    660507
    661508        /*
    662509         * arrays of domstring, utf8string, cstring, astring types not allowed
    663510         */
    664         if (IDL_tree_property_get(simple_decl, "array") != NULL &&
    665             UP_IS_NATIVE(param_type) &&
    666             (IDL_tree_property_get(param_type, "domstring")  != NULL ||
    667              IDL_tree_property_get(param_type, "utf8string") != NULL ||
    668              IDL_tree_property_get(param_type, "cstring")    != NULL ||
    669              IDL_tree_property_get(param_type, "astring")    != NULL)) {
    670             IDL_tree_error(method_tree,
     511        if (   xpidlNodeAttrFind(pIt, "array")
     512            && pNdTypeSpec->enmType == kXpidlNdType_Native
     513            && (   xpidlNodeAttrFind(pNdTypeSpec, "domstring")  != NULL
     514                || xpidlNodeAttrFind(pNdTypeSpec, "utf8string") != NULL
     515                || xpidlNodeAttrFind(pNdTypeSpec, "cstring")    != NULL
     516                || xpidlNodeAttrFind(pNdTypeSpec, "astring")    != NULL))
     517            return xpidlIdlError(pErrInfo, pIt, VERR_INVALID_STATE,
    671518                           "[domstring], [utf8string], [cstring], [astring] "
    672519                           "types cannot be used in array parameters");
    673             return FALSE;
    674         }               
    675 
    676         if (!check_param_attribute(method_tree, param, IID_IS) ||
    677             !check_param_attribute(method_tree, param, LENGTH_IS) ||
    678             !check_param_attribute(method_tree, param, SIZE_IS))
    679             return FALSE;
    680 
    681         /*
    682          * Run additional error checks on the parameter type if targetting an
    683          * older version of XPConnect.
    684          */
    685 
    686         if (!verify_type_fits_version(param_type, method_tree))
    687             return FALSE;
    688        
    689     }
    690    
     520
     521        rc = check_param_attribute(pNd, pIt, IID_IS, pErrInfo);
     522        if (RT_FAILURE(rc))
     523            return rc;
     524        rc = check_param_attribute(pNd, pIt, LENGTH_IS, pErrInfo);
     525        if (RT_FAILURE(rc))
     526            return rc;
     527        rc = check_param_attribute(pNd, pIt, SIZE_IS, pErrInfo);
     528        if (RT_FAILURE(rc))
     529            return rc;
     530    }
     531
     532    PCXPIDLNODE pNdTypeSpec = find_underlying_type(pNd->u.Method.pNdTypeSpecRet);
     533    pNdTypeSpec = pNdTypeSpec ? pNdTypeSpec : pIt->u.Method.pNdTypeSpecRet;
     534
    691535    /* XXX q: can return type be nsid? */
    692536    /* Native return type? */
    693     if (scriptable_method &&
    694         op->op_type_spec != NULL && UP_IS_NATIVE(op->op_type_spec) &&
    695         IDL_tree_property_get(op->op_type_spec, "nsid") == NULL &&
    696         IDL_tree_property_get(op->op_type_spec, "domstring") == NULL &&
    697         IDL_tree_property_get(op->op_type_spec, "utf8string") == NULL &&
    698         IDL_tree_property_get(op->op_type_spec, "cstring") == NULL &&
    699         IDL_tree_property_get(op->op_type_spec, "astring") == NULL)
    700     {
    701         IDL_tree_error(method_tree,
    702                        "methods in [scriptable] interfaces that are "
    703                        "non-scriptable because they return native "
    704                        "types must be marked [noscript]");
    705         return FALSE;
    706     }
    707 
     537    if (   scriptable_method
     538        && pNdTypeSpec->enmType == kXpidlNdType_Native
     539        && xpidlNodeAttrFind(pNdTypeSpec, "nsid") == NULL
     540        && xpidlNodeAttrFind(pNdTypeSpec, "domstring") == NULL
     541        && xpidlNodeAttrFind(pNdTypeSpec, "utf8string") == NULL
     542        && xpidlNodeAttrFind(pNdTypeSpec, "cstring") == NULL
     543        && xpidlNodeAttrFind(pNdTypeSpec, "astring") == NULL)
     544        return xpidlIdlError(pErrInfo, pIt, VERR_INVALID_STATE,
     545                             "methods in [scriptable] interfaces that are "
     546                             "non-scriptable because they return native "
     547                             "types must be marked [noscript]");
    708548
    709549    /*
     
    711551     * supported in xpcom
    712552     */
    713     if (!notxpcom &&
    714         op->op_type_spec != NULL &&
    715         IDL_tree_property_get(op->op_type_spec, "nsid") != NULL &&
    716         IDL_tree_property_get(op->op_type_spec, "ptr") == NULL &&
    717         IDL_tree_property_get(op->op_type_spec, "ref") == NULL)
    718     {
    719         IDL_tree_error(method_tree,
    720                        "Feature currently not supported: "
    721                        "return value is of type nsid and "
    722                        "must be marked either [ptr] or [ref], "
    723                        "or else method \"%s\" must be marked [notxpcom] ",
    724                        method_name);
    725         return FALSE;
    726     }
    727 
    728     /*
    729      * Run additional error checks on the return type if targetting an
    730      * older version of XPConnect.
    731      */
    732 
    733     if (op->op_type_spec != NULL &&
    734         !verify_type_fits_version(op->op_type_spec, method_tree))
    735     {
    736         return FALSE;
    737     }
    738 
    739     return TRUE;
    740 }
    741 #endif
     553    if (   !notxpcom
     554        && pNdTypeSpec->enmType == kXpidlNdType_Native
     555        && xpidlNodeAttrFind(pNdTypeSpec, "nsid") != NULL
     556        && xpidlNodeAttrFind(pNdTypeSpec, "ptr") == NULL
     557        && xpidlNodeAttrFind(pNdTypeSpec, "ref") == NULL)
     558        return xpidlIdlError(pErrInfo, pIt, VERR_INVALID_STATE,
     559                             "Feature currently not supported: "
     560                             "return value is of type nsid and "
     561                             "must be marked either [ptr] or [ref], "
     562                             "or else method \"%s\" must be marked [notxpcom] ",
     563                             pNd->u.Method.pszName);
     564
     565    return VINF_SUCCESS;
     566}
     567
    742568
    743569/*
     
    745571 * it's of the form native <idl-name>(<c++-name>)
    746572 */
    747 DECLHIDDEN(bool) check_native(PCXPIDLNODE pNd)
     573DECLHIDDEN(int) check_native(PCXPIDLNODE pNd, PRTERRINFO pErrInfo)
    748574{
    749575    Assert(pNd->enmType == kXpidlNdType_Native);
     
    751577    /* require that native declarations give a native type */
    752578    if (pNd->u.Native.pszNative)
    753         return true;
    754 
    755     //IDL_tree_error(state->tree,
    756     //               "``native %s;'' needs C++ type: ``native %s(<C++ type>);''",
    757     //               pNd->u.Native.pszName, pNd->u.Native.pszName);
    758     return false;
     579        return VINF_SUCCESS;
     580
     581    return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     582                         "``native %s;'' needs C++ type: ``native %s(<C++ type>);''",
     583                         pNd->u.Native.pszName, pNd->u.Native.pszName);
    759584}
    760585
     
    763588 * Verify that the interface declaration is correct
    764589 */
    765 DECLHIDDEN(bool) verify_interface_declaration(PCXPIDLNODE pNd)
     590DECLHIDDEN(int) verify_interface_declaration(PCXPIDLNODE pNd, PRTERRINFO pErrInfo)
    766591{
    767592    /*
     
    770595     * NOTE: We don't recurse since all interfaces will fall through here
    771596     */
    772     if (xpidlNodeAttrFind(pNd,  "scriptable"))
     597    if (xpidlNodeAttrFind(pNd, "scriptable"))
    773598    {
    774 #if 0
    775         for (iter = IDL_INTERFACE(interface_tree).inheritance_spec; iter;
    776             iter = IDL_LIST(iter).next) {
    777             if (IDL_tree_property_get(
    778                 IDL_INTERFACE(iter).ident, "scriptable") == 0) {
    779                 XPIDL_WARNING((interface_tree,IDL_WARNING1,
    780                     "%s is scriptable but inherits from the non-scriptable interface %s\n",
    781                     IDL_IDENT(IDL_INTERFACE(interface_tree).ident).str,
    782                     IDL_IDENT(IDL_INTERFACE(iter).ident).str));
    783             }
     599        Assert(pNd->enmType == kXpidlNdType_Interface_Def);
     600        while (pNd->pNdTypeRef)
     601        {
     602            if (!xpidlNodeAttrFind(pNd->pNdTypeRef, "scriptable"))
     603                return xpidlIdlError(pErrInfo, pNd, VERR_INVALID_STATE,
     604                                     "%s is scriptable but inherits from the non-scriptable interface %s",
     605                                     pNd->u.If.pszIfName, pNd->u.If.pszIfInherit);
     606
     607            pNd = pNd->pNdTypeRef;
    784608        }
    785 #endif
    786     }
    787     return true;
     609    }
     610    return VINF_SUCCESS;
    788611}
    789612
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette