Пример #1
0
/********************************************************
 * Helper function for checkAccess()
 * Returns:
 *      false   is not accessible
 *      true    is accessible
 */
static bool isAccessible(
        Dsymbol *smember,
        Dsymbol *sfunc,
        AggregateDeclaration *dthis,
        AggregateDeclaration *cdscope)
{
    assert(dthis);

#if 0
    printf("isAccessible for %s.%s in function %s() in scope %s\n",
        dthis->toChars(), smember->toChars(),
        sfunc ? sfunc->toChars() : "NULL",
        cdscope ? cdscope->toChars() : "NULL");
#endif
    if (hasPrivateAccess(dthis, sfunc) ||
        isFriendOf(dthis, cdscope))
    {
        if (smember->toParent() == dthis)
            return true;

        if (ClassDeclaration *cdthis = dthis->isClassDeclaration())
        {
            for (size_t i = 0; i < cdthis->baseclasses->dim; i++)
            {
                BaseClass *b = (*cdthis->baseclasses)[i];
                Prot access = getAccess(b->base, smember);
                if (access.kind >= PROTprotected ||
                    isAccessible(smember, sfunc, b->base, cdscope))
                {
                    return true;
                }
            }
        }
    }
    else
    {
        if (smember->toParent() != dthis)
        {
            if (ClassDeclaration *cdthis = dthis->isClassDeclaration())
            {
                for (size_t i = 0; i < cdthis->baseclasses->dim; i++)
                {
                    BaseClass *b = (*cdthis->baseclasses)[i];
                    if (isAccessible(smember, sfunc, b->base, cdscope))
                        return true;
                }
            }
        }
    }
    return false;
}
Пример #2
0
void AggregateDeclaration::accessCheck(Loc loc, Scope *sc, Dsymbol *smember)
{
    int result;

    FuncDeclaration *f = sc->func;
    AggregateDeclaration *cdscope = sc->getStructClassScope();
    enum PROT access;

#if LOG
    printf("AggregateDeclaration::accessCheck() for %s.%s in function %s() in scope %s\n",
        toChars(), smember->toChars(),
        f ? f->toChars() : NULL,
        cdscope ? cdscope->toChars() : NULL);
#endif

    Dsymbol *smemberparent = smember->toParent();
    if (!smemberparent || !smemberparent->isAggregateDeclaration())
    {
#if LOG
        printf("not an aggregate member\n");
#endif
        return;                         // then it is accessible
    }

    // BUG: should enable this check
    //assert(smember->parent->isBaseOf(this, NULL));

    if (smemberparent == this)
    {   enum PROT access2 = smember->prot();

        result = access2 >= PROTpublic ||
                hasPrivateAccess(f) ||
                isFriendOf(cdscope) ||
                (access2 == PROTpackage && hasPackageAccess(sc, this));
#if LOG
        printf("result1 = %d\n", result);
#endif
    }
    else if ((access = this->getAccess(smember)) >= PROTpublic)
    {
        result = 1;
#if LOG
        printf("result2 = %d\n", result);
#endif
    }
    else if (access == PROTpackage && hasPackageAccess(sc, this))
    {
        result = 1;
#if LOG
        printf("result3 = %d\n", result);
#endif
    }
    else
    {
        result = accessCheckX(smember, f, this, cdscope);
#if LOG
        printf("result4 = %d\n", result);
#endif
    }
    if (!result)
    {
        error(loc, "member %s is not accessible", smember->toChars());
    }
}
Пример #3
0
/*******************************
 * Do access check for member of this class, this class being the
 * type of the 'this' pointer used to access smember.
 * Returns true if the member is not accessible.
 */
bool checkAccess(AggregateDeclaration *ad, Loc loc, Scope *sc, Dsymbol *smember)
{
    FuncDeclaration *f = sc->func;
    AggregateDeclaration *cdscope = sc->getStructClassScope();

#if LOG
    printf("AggregateDeclaration::checkAccess() for %s.%s in function %s() in scope %s\n",
        ad->toChars(), smember->toChars(),
        f ? f->toChars() : NULL,
        cdscope ? cdscope->toChars() : NULL);
#endif

    Dsymbol *smemberparent = smember->toParent();
    if (!smemberparent || !smemberparent->isAggregateDeclaration())
    {
#if LOG
        printf("not an aggregate member\n");
#endif
        return false;                   // then it is accessible
    }

    // BUG: should enable this check
    //assert(smember->parent->isBaseOf(this, NULL));

    bool result;
    Prot access;
    if (smemberparent == ad)
    {
        Prot access2 = smember->prot();
        result = access2.kind >= PROTpublic ||
                hasPrivateAccess(ad, f) ||
                isFriendOf(ad, cdscope) ||
                (access2.kind == PROTpackage && hasPackageAccess(sc, ad)) ||
                ad->getAccessModule() == sc->module;
#if LOG
        printf("result1 = %d\n", result);
#endif
    }
    else if ((access = getAccess(ad, smember)).kind >= PROTpublic)
    {
        result = true;
#if LOG
        printf("result2 = %d\n", result);
#endif
    }
    else if (access.kind == PROTpackage && hasPackageAccess(sc, ad))
    {
        result = true;
#if LOG
        printf("result3 = %d\n", result);
#endif
    }
    else
    {
        result = isAccessible(smember, f, ad, cdscope);
#if LOG
        printf("result4 = %d\n", result);
#endif
    }
    if (!result)
    {
        ad->error(loc, "member %s is not accessible", smember->toChars());
        //printf("smember = %s %s, prot = %d, semanticRun = %d\n",
        //        smember->kind(), smember->toPrettyChars(), smember->prot(), smember->semanticRun);
        return true;
    }
    return false;
}