Пример #1
0
int ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
{
    //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toChars());
    Dsymbol *s = search(0, fd->ident, 4|2);
    if (!s)
    {   //printf("not found\n");
        /* Because, due to a hack, if there are multiple definitions
         * of fd->ident, NULL is returned.
         */
        return 0;
    }
    s = s->toAlias();
    OverloadSet *os = s->isOverloadSet();
    if (os)
    {
        for (int i = 0; i < os->a.dim; i++)
        {   Dsymbol *s = (Dsymbol *)os->a.data[i];
            FuncDeclaration *f2 = s->isFuncDeclaration();
            if (f2 && overloadApply(f2, &isf, fd))
                return 0;
        }
        return 1;
    }
    else
    {
        FuncDeclaration *fdstart = s->isFuncDeclaration();
        //printf("%s fdstart = %p\n", s->kind(), fdstart);
        return !overloadApply(fdstart, &isf, fd);
    }
}
Пример #2
0
int AliasDeclaration::overloadInsert(Dsymbol *s)
{
    /* Don't know yet what the aliased symbol is, so assume it can
     * be overloaded and check later for correctness.
     */

    //printf("AliasDeclaration::overloadInsert('%s')\n", s->toChars());
    if (aliassym) // see test/test56.d
    {
        Dsymbol *a = aliassym->toAlias();
        FuncDeclaration *f = a->isFuncDeclaration();
        if (f)  // BUG: what if it's a template?
        {
            FuncAliasDeclaration *fa = new FuncAliasDeclaration(f);
            aliassym = fa;
            return fa->overloadInsert(s);
        }
    }

    if (overnext == NULL)
    {
        if (s == this)
        {
            return TRUE;
        }
        overnext = s;
        return TRUE;
    }
    else
    {
        return overnext->overloadInsert(s);
    }
}
Пример #3
0
Файл: dsymbol.c Проект: olgk/ldc
FuncDeclaration *ScopeDsymbol::findGetMembers()
{
    Dsymbol *s = search_function(this, Id::getmembers);
    FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;

#if 0  // Finish
    static TypeFunction *tfgetmembers;

    if (!tfgetmembers)
    {
        Scope sc;
        Parameters *arguments = new Parameters;
        Parameters *arg = new Parameter(STCin, Type::tchar->constOf()->arrayOf(), NULL, NULL);
        arguments->push(arg);

        Type *tret = NULL;
        tfgetmembers = new TypeFunction(arguments, tret, 0, LINKd);
        tfgetmembers = (TypeFunction *)tfgetmembers->semantic(0, &sc);
    }
    if (fdx)
        fdx = fdx->overloadExactMatch(tfgetmembers);
#endif
    if (fdx && fdx->isVirtual())
        fdx = NULL;

    return fdx;
}
Пример #4
0
static FuncDeclaration* getParentFunc(Dsymbol* sym, bool stopOnStatic) {
    if (!sym)
        return NULL;
    Dsymbol* parent = sym->parent;
    assert(parent);
    while (parent && !parent->isFuncDeclaration()) {
        if (stopOnStatic) {
            Declaration* decl = sym->isDeclaration();
            if (decl && decl->isStatic())
                return NULL;
        }
        parent = parent->parent;
    }

    return (parent ? parent->isFuncDeclaration() : NULL);
}
Пример #5
0
int ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
{
    //printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toChars());
    Dsymbol *s = search(Loc(), fd->ident, IgnoreAmbiguous | IgnoreErrors);
    if (!s)
    {
        //printf("not found\n");
        /* Because, due to a hack, if there are multiple definitions
         * of fd->ident, NULL is returned.
         */
        return 0;
    }
    s = s->toAlias();
    OverloadSet *os = s->isOverloadSet();
    if (os)
    {
        for (size_t i = 0; i < os->a.dim; i++)
        {
            Dsymbol *s2 = os->a[i];
            FuncDeclaration *f2 = s2->isFuncDeclaration();
            if (f2 && overloadApply(f2, (void *)fd, &isf))
                return 0;
        }
        return 1;
    }
    else
    {
        FuncDeclaration *fdstart = s->isFuncDeclaration();
        //printf("%s fdstart = %p\n", s->kind(), fdstart);
        if (overloadApply(fdstart, (void *)fd, &isf))
            return 0;

        return !fd->parent->isTemplateMixin();
    }
}
Пример #6
0
    void visit(TemplateInstance *ti)
    {
        OutBuffer buf;

    #if 0
        printf("TemplateInstance::mangle() %p %s", ti, ti->toChars());
        if (ti->parent)
            printf("  parent = %s %s", ti->parent->kind(), ti->parent->toChars());
        printf("\n");
    #endif
        ti->getIdent();
        const char *id = ti->ident ? ti->ident->toChars() : ti->toChars();
        if (!ti->tempdecl)
            ti->error("is not defined");
        else
        {
            Dsymbol *par = ti->isTemplateMixin() ? ti->parent : ti->tempdecl->parent;
            if (par)
            {
                FuncDeclaration *f = par->isFuncDeclaration();
                if (f)
                    mangleExact(f);
                else
                    par->accept(this);
                if (result[0] == '_' && result[1] == 'D')
                    result += 2;
                buf.writestring(result);
            }
        }
        buf.printf("%llu%s", (ulonglong)strlen(id), id);
        id = buf.extractString();
        //printf("TemplateInstance::mangle() %s = %s\n", ti->toChars(), ti->id);
        result = id;
    }
Пример #7
0
Файл: dsymbol.c Проект: eco/dmd
bool Dsymbol::oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident)
{
    //printf("Dsymbol::oneMembers() %d\n", members ? members->dim : 0);
    Dsymbol *s = NULL;

    if (members)
    {
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *sx = (*members)[i];
            bool x = sx->oneMember(ps, ident);
            //printf("\t[%d] kind %s = %d, s = %p\n", i, sx->kind(), x, *ps);
            if (!x)
            {
                //printf("\tfalse 1\n");
                assert(*ps == NULL);
                return false;
            }
            if (*ps)
            {
                assert(ident);
                if (!(*ps)->ident || !(*ps)->ident->equals(ident))
                    continue;
                if (!s)
                    s = *ps;
                else if (s->isOverloadable() && (*ps)->isOverloadable())
                {
                    // keep head of overload set
                    FuncDeclaration *f1 = s->isFuncDeclaration();
                    FuncDeclaration *f2 = (*ps)->isFuncDeclaration();
                    if (f1 && f2)
                    {
                        assert(!f1->isFuncAliasDeclaration());
                        assert(!f2->isFuncAliasDeclaration());
                        for (; f1 != f2; f1 = f1->overnext0)
                        {
                            if (f1->overnext0 == NULL)
                            {
                                f1->overnext0 = f2;
                                break;
                            }
                        }
                    }
                }
                else                    // more than one symbol
                {
                    *ps = NULL;
                    //printf("\tfalse 2\n");
                    return false;
                }
            }
        }
    }
    *ps = s;            // s is the one symbol, NULL if none
    //printf("\ttrue\n");
    return true;
}
Пример #8
0
char *mangle(Declaration *sthis)
{
    OutBuffer buf;
    char *id;
    Dsymbol *s;

    //printf("::mangle(%s)\n", sthis->toChars());
    s = sthis;
    do
    {
        //printf("mangle: s = %p, '%s', parent = %p\n", s, s->toChars(), s->parent);
        if (s->ident)
        {
            FuncDeclaration *fd = s->isFuncDeclaration();
            if (s != sthis && fd)
            {
                id = mangle(fd);
                buf.prependstring(id);
                goto L1;
            }
            else
            {
                id = s->ident->toChars();
                int len = strlen(id);
                char tmp[sizeof(len) * 3 + 1];
                buf.prependstring(id);
                sprintf(tmp, "%d", len);
                buf.prependstring(tmp);
            }
        }
        else
            buf.prependstring("0");
        s = s->parent;
    } while (s);

//    buf.prependstring("_D");
L1:
    //printf("deco = '%s'\n", sthis->type->deco ? sthis->type->deco : "null");
    //printf("sthis->type = %s\n", sthis->type->toChars());
    FuncDeclaration *fd = sthis->isFuncDeclaration();
    if (fd && (fd->needThis() || fd->isNested()))
        buf.writeByte(Type::needThisPrefix());
    if (sthis->type->deco)
        buf.writestring(sthis->type->deco);
    else
    {
#ifdef DEBUG
        if (!fd->inferRetType)
            printf("%s\n", fd->toChars());
#endif
        assert(fd && fd->inferRetType);
    }

    id = buf.toChars();
    buf.data = NULL;
    return id;
}
Пример #9
0
void AggregateDeclaration::makeNested()
{
    if (!enclosing && sizeok != SIZEOKdone && !isUnionDeclaration() && !isInterfaceDeclaration())
    {
        // If nested struct, add in hidden 'this' pointer to outer scope
        if (!(storage_class & STCstatic))
        {
            Dsymbol *s = toParent2();
            if (s)
            {
                AggregateDeclaration *ad = s->isAggregateDeclaration();
                FuncDeclaration *fd = s->isFuncDeclaration();

                if (fd)
                {
                    enclosing = fd;
                }
                else if (isClassDeclaration() && ad && ad->isClassDeclaration())
                {
                    enclosing = ad;
                }
                else if (isStructDeclaration() && ad)
                {
                    if (TemplateInstance *ti = ad->parent->isTemplateInstance())
                    {
                        enclosing = ti->enclosing;
                    }
                }
                if (enclosing)
                {
                    //printf("makeNested %s, enclosing = %s\n", toChars(), enclosing->toChars());
                    Type *t;
                    if (ad)
                        t = ad->handleType();
                    else if (fd)
                    {
                        AggregateDeclaration *ad2 = fd->isMember2();
                        if (ad2)
                            t = ad2->handleType();
                        else
                            t = Type::tvoidptr;
                    }
                    else
                        assert(0);
                    if (t->ty == Tstruct)
                        t = Type::tvoidptr;     // t should not be a ref type
                    assert(!vthis);
                    vthis = new ThisDeclaration(loc, t);
                    //vthis->storage_class |= STCref;
                    members->push(vthis);
                }
            }
        }
    }
}
Пример #10
0
void AggregateDeclaration::makeNested()
{
    if (enclosing)  // if already nested
        return;
    if (sizeok == SIZEOKdone)
        return;
    if (isUnionDeclaration() || isInterfaceDeclaration())
        return;
    if (storage_class & STCstatic)
        return;

    // If nested struct, add in hidden 'this' pointer to outer scope
    Dsymbol *s = toParent2();
    if (!s)
        return;
    AggregateDeclaration *ad = s->isAggregateDeclaration();
    FuncDeclaration *fd = s->isFuncDeclaration();
    Type *t = NULL;
    if (fd)
    {
        enclosing = fd;

        AggregateDeclaration *agg = fd->isMember2();
        t = agg ? agg->handleType() : Type::tvoidptr;
    }
    else if (ad)
    {
        if (isClassDeclaration() && ad->isClassDeclaration())
        {
            enclosing = ad;
        }
        else if (isStructDeclaration())
        {
            if (TemplateInstance *ti = ad->parent->isTemplateInstance())
            {
                enclosing = ti->enclosing;
            }
        }

        t = ad->handleType();
    }
    if (enclosing)
    {
        //printf("makeNested %s, enclosing = %s\n", toChars(), enclosing->toChars());
        assert(t);
        if (t->ty == Tstruct)
            t = Type::tvoidptr;     // t should not be a ref type
        assert(!vthis);
        vthis = new ThisDeclaration(loc, t);
        //vthis->storage_class |= STCref;
        members->push(vthis);
    }
}
Пример #11
0
/**********************************
 * Determine if smember has access to private members of this declaration.
 */
bool hasPrivateAccess(AggregateDeclaration *ad, Dsymbol *smember)
{
    if (smember)
    {
        AggregateDeclaration *cd = NULL;
        Dsymbol *smemberparent = smember->toParent();
        if (smemberparent)
            cd = smemberparent->isAggregateDeclaration();

#if LOG
        printf("AggregateDeclaration::hasPrivateAccess(class %s, member %s)\n",
                ad->toChars(), smember->toChars());
#endif

        if (ad == cd)         // smember is a member of this class
        {
#if LOG
            printf("\tyes 1\n");
#endif
            return true;           // so we get private access
        }

        // If both are members of the same module, grant access
        while (1)
        {
            Dsymbol *sp = smember->toParent();
            if (sp->isFuncDeclaration() && smember->isFuncDeclaration())
                smember = sp;
            else
                break;
        }
        if (!cd && ad->toParent() == smember->toParent())
        {
#if LOG
            printf("\tyes 2\n");
#endif
            return true;
        }
        if (!cd && ad->getAccessModule() == smember->getAccessModule())
        {
#if LOG
            printf("\tyes 3\n");
#endif
            return true;
        }
    }
#if LOG
    printf("\tno\n");
#endif
    return false;
}
Пример #12
0
static FuncDeclaration* find_method_overload(AggregateDeclaration* ad, Identifier* id, TypeFunction* tf, Module* mod)
{
    Dsymbol *s = search_function(ad, id);
    FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;
    if (fdx)
    {
        FuncDeclaration *fd = fdx->overloadExactMatch(tf, mod);
        if (fd)
        {
            return fd;
        }
    }
    return NULL;
}
Пример #13
0
Файл: s2ir.c Проект: Faianca/dmd
 void visit(PragmaStatement *s)
 {
     //printf("PragmaStatement::toIR()\n");
     if (s->ident == Id::startaddress)
     {
         assert(s->args && s->args->dim == 1);
         Expression *e = (*s->args)[0];
         Dsymbol *sa = getDsymbol(e);
         FuncDeclaration *f = sa->isFuncDeclaration();
         assert(f);
         Symbol *sym = toSymbol(f);
         while (irs->prev)
             irs = irs->prev;
         irs->startaddress = sym;
     }
 }
Пример #14
0
Файл: s2ir.c Проект: Rayerd/dmd
void PragmaStatement::toIR(IRState *irs)
{
    //printf("PragmaStatement::toIR()\n");
    if (ident == Id::startaddress)
    {
        assert(args && args->dim == 1);
        Expression *e = args->tdata()[0];
        Dsymbol *sa = getDsymbol(e);
        FuncDeclaration *f = sa->isFuncDeclaration();
        assert(f);
        Symbol *s = f->toSymbol();
        while (irs->prev)
            irs = irs->prev;
        irs->startaddress = s;
    }
}
Пример #15
0
/***************************************
 * Search toString member function for TypeInfo_Struct.
 *      string toString();
 */
FuncDeclaration *search_toString(StructDeclaration *sd)
{
    Dsymbol *s = search_function(sd, Id::tostring);
    FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL;
    if (fd)
    {
        static TypeFunction *tftostring;
        if (!tftostring)
        {
            tftostring = new TypeFunction(NULL, Type::tstring, 0, LINKd);
            tftostring = (TypeFunction *)tftostring->merge();
        }

        fd = fd->overloadExactMatch(tftostring);
    }
    return fd;
}
Пример #16
0
/***************************************
 * Search toHash member function for TypeInfo_Struct.
 *      const hash_t toHash();
 */
FuncDeclaration *search_toHash(StructDeclaration *sd)
{
    Dsymbol *s = search_function(sd, Id::tohash);
    FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL;
    if (fd)
    {
        static TypeFunction *tftohash;
        if (!tftohash)
        {
            tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
            tftohash->mod = MODconst;
            tftohash = (TypeFunction *)tftohash->merge();
        }

        fd = fd->overloadExactMatch(tftohash);
    }
    return fd;
}
Пример #17
0
Expression *isFuncX(TraitsExp *e, bool (*fp)(FuncDeclaration *f))
{
    int result = 0;
    if (!e->args || !e->args->dim)
        goto Lfalse;
    for (size_t i = 0; i < e->args->dim; i++)
    {
        Dsymbol *s = getDsymbol((*e->args)[i]);
        if (!s)
            goto Lfalse;
        FuncDeclaration *f = s->isFuncDeclaration();
        if (!f || !fp(f))
            goto Lfalse;
    }
    result = 1;
Lfalse:
    return new IntegerExp(e->loc, result, Type::tbool);
}
Пример #18
0
void PragmaDeclaration::toObjFile(int multiobj)
{
    if (ident == Id::lib)
    {
        assert(args && args->dim == 1);

        Expression *e = (Expression *)args->data[0];

        assert(e->op == TOKstring);

        StringExp *se = (StringExp *)e;
        char *name = (char *)mem.malloc(se->len + 1);
        memcpy(name, se->string, se->len);
        name[se->len] = 0;
#if OMFOBJ
        /* The OMF format allows library names to be inserted
         * into the object file. The linker will then automatically
         * search that library, too.
         */
        obj_includelib(name);
#elif ELFOBJ || MACHOBJ
        /* The format does not allow embedded library names,
         * so instead append the library name to the list to be passed
         * to the linker.
         */
        global.params.libfiles->push((void *) name);
#else
        error("pragma lib not supported");
#endif
    }
#if DMDV2
    else if (ident == Id::startaddress)
    {
        assert(args && args->dim == 1);
        Expression *e = (Expression *)args->data[0];
        Dsymbol *sa = getDsymbol(e);
        FuncDeclaration *f = sa->isFuncDeclaration();
        assert(f);
        Symbol *s = f->toSymbol();
        obj_startaddress(s);
    }
#endif
    AttribDeclaration::toObjFile(multiobj);
}
Пример #19
0
            static int fp(void *param, Dsymbol *s)
            {
                if (!isCPP(s))
                    return 0;
                auto fd = s->isFuncDeclaration();
                auto td = static_cast<cpp::TemplateDeclaration*>(
                                            s->isTemplateDeclaration());
                DEquals *p = (DEquals *)param;

                decltype(D) s_D = fd ? getFD(fd) : td->TempOrSpec;

                if (p->D == getCanonicalDecl(s_D))
                {
                    p->s = s;
                    return 1;
                }

                return 0;
            }
Пример #20
0
void PragmaDeclaration::toObjFile(int multiobj)
{
    if (ident == Id::lib)
    {
        assert(args && args->dim == 1);

        Expression *e = (*args)[0];

        assert(e->op == TOKstring);

        StringExp *se = (StringExp *)e;
        char *name = (char *)mem.malloc(se->len + 1);
        memcpy(name, se->string, se->len);
        name[se->len] = 0;

        /* Embed the library names into the object file.
         * The linker will then automatically
         * search that library, too.
         */
        if (!obj_includelib(name))
        {
        /* The format does not allow embedded library names,
         * so instead append the library name to the list to be passed
         * to the linker.
         */
        global.params.libfiles->push(name);
        }
    }
#if DMDV2
    else if (ident == Id::startaddress)
    {
        assert(args && args->dim == 1);
        Expression *e = (*args)[0];
        Dsymbol *sa = getDsymbol(e);
        FuncDeclaration *f = sa->isFuncDeclaration();
        assert(f);
        Symbol *s = f->toSymbol();
        obj_startaddress(s);
    }
#endif
    AttribDeclaration::toObjFile(multiobj);
}
Пример #21
0
/***********************************************
 * This is mostly the same as UnaryExp::op_overload(), but has
 * a different rewrite.
 */
Expression *CastExp::op_overload(Scope *sc)
{
    //printf("CastExp::op_overload() (%s)\n", toChars());
    AggregateDeclaration *ad = isAggregate(e1->type);
    if (ad)
    {
        Dsymbol *fd = NULL;
        /* Rewrite as:
         *      e1.opCast!(T)();
         */
        fd = search_function(ad, Id::cast);
        if (fd)
        {
#if 1 // Backwards compatibility with D1 if opCast is a function, not a template
            if (fd->isFuncDeclaration())
            {   // Rewrite as:  e1.opCast()
                return build_overload(loc, sc, e1, NULL, fd);
            }
#endif
            Objects *targsi = new Objects();
            targsi->push(to);
            Expression *e = new DotTemplateInstanceExp(loc, e1, fd->ident, targsi);
            e = new CallExp(loc, e);
            e = e->semantic(sc);
            return e;
        }

        // Didn't find it. Forward to aliasthis
        if (ad->aliasthis)
        {
            /* Rewrite op(e1) as:
             *  op(e1.aliasthis)
             */
            Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident);
            Expression *e = copy();
            ((UnaExp *)e)->e1 = e1;
            e = e->trySemantic(sc);
            return e;
        }
    }
    return NULL;
}
Пример #22
0
        void visit(PragmaDeclaration *pd)
        {
            if (pd->ident == Id::lib)
            {
                assert(pd->args && pd->args->dim == 1);

                Expression *e = (*pd->args)[0];

                assert(e->op == TOKstring);

                StringExp *se = (StringExp *)e;
                char *name = (char *)mem.xmalloc(se->numberOfCodeUnits() + 1);
                se->writeTo(name, true);

                /* Embed the library names into the object file.
                 * The linker will then automatically
                 * search that library, too.
                 */
                if (!obj_includelib(name))
                {
                    /* The format does not allow embedded library names,
                     * so instead append the library name to the list to be passed
                     * to the linker.
                     */
                    global.params.libfiles->push(name);
                }
            }
            else if (pd->ident == Id::startaddress)
            {
                assert(pd->args && pd->args->dim == 1);
                Expression *e = (*pd->args)[0];
                Dsymbol *sa = getDsymbol(e);
                FuncDeclaration *f = sa->isFuncDeclaration();
                assert(f);
                Symbol *s = toSymbol(f);
                obj_startaddress(s);
            }
            visit((AttribDeclaration *)pd);
        }
Пример #23
0
/*************************
 * Initialize the hidden aggregate member, vthis, with
 * the context pointer.
 * Returns:
 *      *(ey + ad.vthis.offset) = this;
 */
elem *setEthis(Loc loc, IRState *irs, elem *ey, AggregateDeclaration *ad)
{
    elem *ethis;
    FuncDeclaration *thisfd = irs->getFunc();
    int offset = 0;
    Dsymbol *adp = ad->toParent2();     // class/func we're nested in

    //printf("[%s] setEthis(ad = %s, adp = %s, thisfd = %s)\n", loc.toChars(), ad->toChars(), adp->toChars(), thisfd->toChars());

    if (adp == thisfd)
    {
        ethis = getEthis(loc, irs, ad);
    }
    else if (thisfd->vthis &&
          (adp == thisfd->toParent2() ||
           (adp->isClassDeclaration() &&
            adp->isClassDeclaration()->isBaseOf(thisfd->toParent2()->isClassDeclaration(), &offset)
           )
          )
        )
    {
        /* Class we're new'ing is at the same level as thisfd
         */
        assert(offset == 0);    // BUG: should handle this case
        ethis = el_var(irs->sthis);
    }
    else
    {
        ethis = getEthis(loc, irs, adp);
        FuncDeclaration *fdp = adp->isFuncDeclaration();
        if (fdp && fdp->hasNestedFrameRefs())
            ethis = el_una(OPaddr, TYnptr, ethis);
    }

    ey = el_bin(OPadd, TYnptr, ey, el_long(TYsize_t, ad->vthis->offset));
    ey = el_una(OPind, TYnptr, ey);
    ey = el_bin(OPeq, TYnptr, ey, ethis);
    return ey;
}
Пример #24
0
void StructDeclaration::makeNested()
{
    if (!isnested && sizeok != SIZEOKdone && !isUnionDeclaration())
    {
        // If nested struct, add in hidden 'this' pointer to outer scope
        if (!(storage_class & STCstatic))
        {   Dsymbol *s = toParent2();
            if (s)
            {
                AggregateDeclaration *ad = s->isAggregateDeclaration();
                FuncDeclaration *fd = s->isFuncDeclaration();

                TemplateInstance *ti;
                if (ad && (ti = ad->parent->isTemplateInstance()) != NULL && ti->isnested || fd)
                {   isnested = true;
                    Type *t;
                    if (ad)
                        t = ad->handle;
                    else if (fd)
                    {   AggregateDeclaration *ad = fd->isMember2();
                        if (ad)
                            t = ad->handle;
                        else
                            t = Type::tvoidptr;
                    }
                    else
                        assert(0);
                    if (t->ty == Tstruct)
                        t = Type::tvoidptr;     // t should not be a ref type
                    assert(!vthis);
                    vthis = new ThisDeclaration(loc, t);
                    //vthis->storage_class |= STCref;
                    members->push(vthis);
                }
            }
        }
    }
}
Пример #25
0
/*************************
 * Find all variables accessed by this delegate that are
 * in functions enclosing it.
 * Params:
 *      fd = function
 *      vars = array to append found variables to
 */
void findAllOuterAccessedVariables(FuncDeclaration *fd, VarDeclarations *vars)
{
    for (Dsymbol *p = fd->parent; p; p = p->parent)
    {
        FuncDeclaration *fdp = p->isFuncDeclaration();
        if (fdp)
        {
            for (size_t i = 0; i < fdp->closureVars.dim; i++)
            {
                VarDeclaration *v = fdp->closureVars[i];
                for (size_t j = 0; j < v->nestedrefs.dim; j++)
                {
                    FuncDeclaration *fdv = v->nestedrefs[j];
                    if (fdv == fd)
                    {
                        //printf("accessed: %s, type %s\n", v->toChars(), v->type->toChars());
                        vars->push(v);
                    }
                }
            }
        }
    }
}
Пример #26
0
std::vector<llvm::Type*> IrTypeClass::buildVtblType(Type* first, Array* vtbl_array)
{
    IF_LOG Logger::println("Building vtbl type for class %s", cd->toPrettyChars());
    LOG_SCOPE;

    std::vector<llvm::Type*> types;
    types.reserve(vtbl_array->dim);

    // first comes the classinfo
    types.push_back(DtoType(first));

    // then come the functions
    ArrayIter<Dsymbol> it(*vtbl_array);
    it.index = 1;

    for (; !it.done(); it.next())
    {
        Dsymbol* dsym = it.get();
        if (dsym == NULL)
        {
            // FIXME
            // why is this null?
            // happens for mini/s.d
            types.push_back(getVoidPtrType());
            continue;
        }

        FuncDeclaration* fd = dsym->isFuncDeclaration();
        assert(fd && "invalid vtbl entry");

        IF_LOG Logger::println("Adding type of %s", fd->toPrettyChars());

        types.push_back(DtoType(fd->type->pointerTo()));
    }

    return types;
}
Пример #27
0
    void mangleParent(Dsymbol *s)
    {
        Dsymbol *p;
        if (TemplateInstance *ti = s->isTemplateInstance())
            p = ti->isTemplateMixin() ? ti->parent : ti->tempdecl->parent;
        else
            p = s->parent;

        if (p)
        {
            mangleParent(p);

            if (p->getIdent())
            {
                const char *id = p->ident->toChars();
                toBuffer(id, s);

                if (FuncDeclaration *f = p->isFuncDeclaration())
                    mangleFunc(f, true);
            }
            else
                buf->writeByte('0');
        }
    }
Пример #28
0
void mangleParent(OutBuffer *buf, Dsymbol *s)
{
    Dsymbol *p;
    if (TemplateInstance *ti = s->isTemplateInstance())
        p = ti->isTemplateMixin() ? ti->parent : ti->tempdecl->parent;
    else
        p = s->parent;

    if (p)
    {
        mangleParent(buf, p);

        if (p->getIdent())
        {
            const char *id = p->ident->toChars();
            buf->printf("%llu%s", (ulonglong)strlen(id), id);

            if (FuncDeclaration *f = p->isFuncDeclaration())
                mangleFunc(buf, f, true);
        }
        else
            buf->writeByte('0');
    }
}
Пример #29
0
void StructDeclaration::semantic(Scope *sc)
{
    Scope *sc2;

    //printf("+StructDeclaration::semantic(this=%p, %s '%s', sizeok = %d)\n", this, parent->toChars(), toChars(), sizeok);

    //static int count; if (++count == 20) halt();

    assert(type);
    if (!members)               // if opaque declaration
    {
        return;
    }

    if (symtab)
    {   if (sizeok == SIZEOKdone || !scope)
        {   //printf("already completed\n");
            scope = NULL;
            return;             // semantic() already completed
        }
    }
    else
        symtab = new DsymbolTable();

    Scope *scx = NULL;
    if (scope)
    {   sc = scope;
        scx = scope;            // save so we don't make redundant copies
        scope = NULL;
    }

    int errors = global.errors;

    unsigned dprogress_save = Module::dprogress;

    parent = sc->parent;
    type = type->semantic(loc, sc);
    handle = type;
    protection = sc->protection;
    alignment = sc->structalign;
    storage_class |= sc->stc;
    if (sc->stc & STCdeprecated)
        isdeprecated = true;
    assert(!isAnonymous());
    if (sc->stc & STCabstract)
        error("structs, unions cannot be abstract");
    userAttributes = sc->userAttributes;

    if (sizeok == SIZEOKnone)            // if not already done the addMember step
    {
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            //printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars());
            s->addMember(sc, this, 1);
        }
    }

    sizeok = SIZEOKnone;
    sc2 = sc->push(this);
    sc2->stc &= STCsafe | STCtrusted | STCsystem;
    sc2->parent = this;
    if (isUnionDeclaration())
        sc2->inunion = 1;
    sc2->protection = PROTpublic;
    sc2->explicitProtection = 0;
    sc2->structalign = STRUCTALIGN_DEFAULT;
    sc2->userAttributes = NULL;

    /* Set scope so if there are forward references, we still might be able to
     * resolve individual members like enums.
     */
    for (size_t i = 0; i < members->dim; i++)
    {   Dsymbol *s = (*members)[i];
        /* There are problems doing this in the general case because
         * Scope keeps track of things like 'offset'
         */
        //if (s->isEnumDeclaration() || (s->isAggregateDeclaration() && s->ident))
        {
            //printf("struct: setScope %s %s\n", s->kind(), s->toChars());
            s->setScope(sc2);
        }
    }

    for (size_t i = 0; i < members->dim; i++)
    {
        Dsymbol *s = (*members)[i];

        /* If this is the last member, see if we can finish setting the size.
         * This could be much better - finish setting the size after the last
         * field was processed. The problem is the chicken-and-egg determination
         * of when that is. See Bugzilla 7426 for more info.
         */
        if (i + 1 == members->dim)
        {
            if (sizeok == SIZEOKnone && s->isAliasDeclaration())
                finalizeSize(sc2);
        }
        // Ungag errors when not speculative
        unsigned oldgag = global.gag;
        if (global.isSpeculativeGagging() && !isSpeculative())
        {
            global.gag = 0;
        }
        s->semantic(sc2);
        global.gag = oldgag;
    }
    finalizeSize(sc2);

    if (sizeok == SIZEOKfwd)
    {   // semantic() failed because of forward references.
        // Unwind what we did, and defer it for later
        for (size_t i = 0; i < fields.dim; i++)
        {   Dsymbol *s = fields[i];
            VarDeclaration *vd = s->isVarDeclaration();
            if (vd)
                vd->offset = 0;
        }
        fields.setDim(0);
        structsize = 0;
        alignsize = 0;
//        structalign = 0;

        scope = scx ? scx : new Scope(*sc);
        scope->setNoFree();
        scope->module->addDeferredSemantic(this);

        Module::dprogress = dprogress_save;
        //printf("\tdeferring %s\n", toChars());
        return;
    }

    Module::dprogress++;

    //printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());

    // Determine if struct is all zeros or not
    zeroInit = 1;
    for (size_t i = 0; i < fields.dim; i++)
    {
        Dsymbol *s = fields[i];
        VarDeclaration *vd = s->isVarDeclaration();
        if (vd && !vd->isDataseg())
        {
            if (vd->init)
            {
                // Should examine init to see if it is really all 0's
                zeroInit = 0;
                break;
            }
            else
            {
                if (!vd->type->isZeroInit(loc))
                {
                    zeroInit = 0;
                    break;
                }
            }
        }
    }

#if DMDV1
    /* This doesn't work for DMDV2 because (ref S) and (S) parameter
     * lists will overload the same.
     */
    /* The TypeInfo_Struct is expecting an opEquals and opCmp with
     * a parameter that is a pointer to the struct. But if there
     * isn't one, but is an opEquals or opCmp with a value, write
     * another that is a shell around the value:
     *  int opCmp(struct *p) { return opCmp(*p); }
     */

    TypeFunction *tfeqptr;
    {
        Parameters *arguments = new Parameters;
        Parameter *arg = new Parameter(STCin, handle, Id::p, NULL);

        arguments->push(arg);
        tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
        tfeqptr = (TypeFunction *)tfeqptr->semantic(Loc(), sc);
    }

    TypeFunction *tfeq;
    {
        Parameters *arguments = new Parameters;
        Parameter *arg = new Parameter(STCin, type, NULL, NULL);

        arguments->push(arg);
        tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
        tfeq = (TypeFunction *)tfeq->semantic(Loc(), sc);
    }

    Identifier *id = Id::eq;
    for (int i = 0; i < 2; i++)
    {
        Dsymbol *s = search_function(this, id);
        FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;
        if (fdx)
        {   FuncDeclaration *fd = fdx->overloadExactMatch(tfeqptr);
            if (!fd)
            {   fd = fdx->overloadExactMatch(tfeq);
                if (fd)
                {   // Create the thunk, fdptr
                    FuncDeclaration *fdptr = new FuncDeclaration(loc, loc, fdx->ident, STCundefined, tfeqptr);
                    Expression *e = new IdentifierExp(loc, Id::p);
                    e = new PtrExp(loc, e);
                    Expressions *args = new Expressions();
                    args->push(e);
                    e = new IdentifierExp(loc, id);
                    e = new CallExp(loc, e, args);
                    fdptr->fbody = new ReturnStatement(loc, e);
                    ScopeDsymbol *s = fdx->parent->isScopeDsymbol();
                    assert(s);
                    s->members->push(fdptr);
                    fdptr->addMember(sc, s, 1);
                    fdptr->semantic(sc2);
                }
            }
        }

        id = Id::cmp;
    }
#endif
#if DMDV2
    dtor = buildDtor(sc2);
    postblit = buildPostBlit(sc2);
    cpctor = buildCpCtor(sc2);

    buildOpAssign(sc2);
    buildOpEquals(sc2);
#endif
    inv = buildInv(sc2);

    sc2->pop();

    /* Look for special member functions.
     */
#if DMDV2
    ctor = search(Loc(), Id::ctor, 0);
#endif
    aggNew =       (NewDeclaration *)search(Loc(), Id::classNew,       0);
    aggDelete = (DeleteDeclaration *)search(Loc(), Id::classDelete,    0);

    TypeTuple *tup = type->toArgTypes();
    size_t dim = tup->arguments->dim;
    if (dim >= 1)
    {   assert(dim <= 2);
        arg1type = (*tup->arguments)[0]->type;
        if (dim == 2)
            arg2type = (*tup->arguments)[1]->type;
    }

    if (sc->func)
    {
        semantic2(sc);
        semantic3(sc);
    }

    if (global.errors != errors)
    {   // The type is no good.
        type = Type::terror;
    }

    if (deferred && !global.gag)
    {
        deferred->semantic2(sc);
        deferred->semantic3(sc);
    }

#if 0
    if (type->ty == Tstruct && ((TypeStruct *)type)->sym != this)
    {
        printf("this = %p %s\n", this, this->toChars());
        printf("type = %d sym = %p\n", type->ty, ((TypeStruct *)type)->sym);
    }
#endif
    assert(type->ty != Tstruct || ((TypeStruct *)type)->sym == this);
}
Пример #30
0
FuncDeclaration *StructDeclaration::buildXopEquals(Scope *sc)
{
    if (!search_function(this, Id::eq))
        return NULL;

    /* static bool__xopEquals(in void* p, in void* q) {
     *     return ( *cast(const S*)(p) ).opEquals( *cast(const S*)(q) );
     * }
     */

    Parameters *parameters = new Parameters;
    parameters->push(new Parameter(STCin, Type::tvoidptr, Id::p, NULL));
    parameters->push(new Parameter(STCin, Type::tvoidptr, Id::q, NULL));
    TypeFunction *tf = new TypeFunction(parameters, Type::tbool, 0, LINKd);
    tf = (TypeFunction *)tf->semantic(0, sc);

    Identifier *id = Lexer::idPool("__xopEquals");
    FuncDeclaration *fop = new FuncDeclaration(0, 0, id, STCstatic, tf);

    Expression *e = new CallExp(0,
        new DotIdExp(0,
            new PtrExp(0, new CastExp(0,
                new IdentifierExp(0, Id::p), type->pointerTo()->constOf())),
            Id::eq),
        new PtrExp(0, new CastExp(0,
            new IdentifierExp(0, Id::q), type->pointerTo()->constOf())));

    fop->fbody = new ReturnStatement(0, e);

    size_t index = members->dim;
    members->push(fop);

    unsigned errors = global.startGagging();    // Do not report errors, even if the
    unsigned oldspec = global.speculativeGag;   // template opAssign fbody makes it.
    global.speculativeGag = global.gag;
    Scope *sc2 = sc->push();
    sc2->stc = 0;
    sc2->linkage = LINKd;
    sc2->speculative = true;

    fop->semantic(sc2);
    fop->semantic2(sc2);
    fop->semantic3(sc2);

    sc2->pop();
    global.speculativeGag = oldspec;
    if (global.endGagging(errors))    // if errors happened
    {
        members->remove(index);

        if (!xerreq)
        {
            Expression *e = new IdentifierExp(0, Id::empty);
            e = new DotIdExp(0, e, Id::object);
            e = new DotIdExp(0, e, Lexer::idPool("_xopEquals"));
            e = e->semantic(sc);
            Dsymbol *s = getDsymbol(e);
            FuncDeclaration *fd = s->isFuncDeclaration();

            xerreq = fd;
        }
        fop = xerreq;
    }
    else
        fop->addMember(sc, this, 1);

    return fop;
}