Exemplo n.º 1
0
FuncDeclaration *buildArrayOp(Identifier *ident, BinExp *exp, Scope *sc)
{
    Parameters *fparams = new Parameters();
    Expression *loopbody = buildArrayLoop(exp, fparams);

    /* Construct the function body:
     *  foreach (i; 0 .. p.length)    for (size_t i = 0; i < p.length; i++)
     *      loopbody;
     *  return p;
     */

    Parameter *p = (*fparams)[0];
    // foreach (i; 0 .. p.length)
    Statement *s1 = new ForeachRangeStatement(Loc(), TOKforeach,
        new Parameter(0, NULL, Id::p, NULL),
        new IntegerExp(Loc(), 0, Type::tsize_t),
        new ArrayLengthExp(Loc(), new IdentifierExp(Loc(), p->ident)),
        new ExpStatement(Loc(), loopbody),
        Loc());
    //printf("%s\n", s1->toChars());
    Statement *s2 = new ReturnStatement(Loc(), new IdentifierExp(Loc(), p->ident));
    //printf("s2: %s\n", s2->toChars());
    Statement *fbody = new CompoundStatement(Loc(), s1, s2);

    // Built-in array ops should be @trusted, pure, nothrow and nogc
    StorageClass stc = STCtrusted | STCpure | STCnothrow | STCnogc;

    /* Construct the function
     */
    TypeFunction *ftype = new TypeFunction(fparams, exp->e1->type, 0, LINKc, stc);
    //printf("fd: %s %s\n", ident->toChars(), ftype->toChars());
    FuncDeclaration *fd = new FuncDeclaration(Loc(), Loc(), ident, STCundefined, ftype);
    fd->fbody = fbody;
    fd->protection = Prot(PROTpublic);
    fd->linkage = LINKc;
    fd->isArrayOp = 1;

    sc->_module->importedFrom->members->push(fd);

    sc = sc->push();
    sc->parent = sc->_module->importedFrom;
    sc->stc = 0;
    sc->linkage = LINKc;
    fd->semantic(sc);
    fd->semantic2(sc);
    unsigned errors = global.startGagging();
    fd->semantic3(sc);
    if (global.endGagging(errors))
    {
        fd->type = Type::terror;
        fd->errors = true;
        fd->fbody = NULL;
    }
    sc->pop();

    return fd;
}
Exemplo n.º 2
0
std::vector<llvm::Type *>
IrTypeClass::buildVtblType(Type *first, FuncDeclarations *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);

  auto I = vtbl_array->begin();
  // first comes the classinfo for D interfaces
  if (first) {
    types.push_back(DtoType(first));
    ++I;
  }

  // then come the functions
  for (auto E = vtbl_array->end(); I != E; ++I) {
    FuncDeclaration *fd = *I;
    if (fd == nullptr) {
      // FIXME: This stems from the ancient D1 days – can it still happen?
      types.push_back(getVoidPtrType());
      continue;
    }

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

    // If inferring return type and semantic3 has not been run, do it now.
    // This pops up in some other places in the frontend as well, however
    // it is probably a bug that it still occurs that late.
    if (!fd->type->nextOf() && fd->inferRetType) {
      Logger::println("Running late semantic3 to infer return type.");
      TemplateInstance *spec = fd->isSpeculative();
      unsigned int olderrs = global.errors;
      fd->semantic3(fd->_scope);
      if (spec && global.errors != olderrs) {
        spec->errors = global.errors - olderrs;
      }
    }

    if (!fd->type->nextOf()) {
      // Return type of the function has not been inferred. This seems to
      // happen with virtual functions and is probably a frontend bug.
      IF_LOG Logger::println("Broken function type, semanticRun: %d",
                             fd->semanticRun);
      types.push_back(getVoidPtrType());
      continue;
    }

    types.push_back(getPtrToType(DtoFunctionType(fd)));
  }

  return types;
}
Exemplo n.º 3
0
void StructDeclaration::semanticTypeInfoMembers()
{
    if (xeq &&
        xeq->scope &&
        xeq->semanticRun < PASSsemantic3done)
    {
        unsigned errors = global.startGagging();
        xeq->semantic3(xeq->scope);
        if (global.endGagging(errors))
            xeq = xerreq;
    }

    if (xcmp &&
        xcmp->scope &&
        xcmp->semanticRun < PASSsemantic3done)
    {
        unsigned errors = global.startGagging();
        xcmp->semantic3(xcmp->scope);
        if (global.endGagging(errors))
            xcmp = xerrcmp;
    }

    FuncDeclaration *ftostr = search_toString(this);
    if (ftostr &&
        ftostr->scope &&
        ftostr->semanticRun < PASSsemantic3done)
    {
        ftostr->semantic3(ftostr->scope);
    }

    if (xhash &&
        xhash->scope &&
        xhash->semanticRun < PASSsemantic3done)
    {
        xhash->semantic3(xhash->scope);
    }

    if (postblit &&
        postblit->scope &&
        postblit->semanticRun < PASSsemantic3done)
    {
        postblit->semantic3(postblit->scope);
    }

    if (dtor &&
        dtor->scope &&
        dtor->semanticRun < PASSsemantic3done)
    {
        dtor->semantic3(dtor->scope);
    }
}
Exemplo n.º 4
0
Method* DelegateType::getMethod()
{
    if (!method_)
    {
        Identifier* invoke = Lexer::idPool("Invoke");
        Assembly& assembly = BackEnd::instance().getAssembly();
        FuncDeclaration* fd = new FuncDeclaration(0, 0, invoke, STCextern, getType());

        Expression* exp = new IntegerExp(0, 0, Type::tint32);
        Statement* ret = new ReturnStatement(0, exp);
        fd->parent = getClassDecl();
        fd->fbody = new ScopeStatement(0, ret);
        fd->hasReturnExp = true;
        fd->semantic3(&scope_);
        fd->linkage = LINKwindows; // to prevent mangling
        method_ = new Method(*fd, 1);
        assembly.add(*method_);
    }
    return method_;
}
Exemplo n.º 5
0
Arquivo: clone.c Projeto: Ingrater/dmd
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;
}
Exemplo n.º 6
0
Expression *BinExp::arrayOp(Scope *sc)
{
    //printf("BinExp::arrayOp() %s\n", toChars());

    Type *tb = type->toBasetype();
    assert(tb->ty == Tarray || tb->ty == Tsarray);
    if (tb->nextOf()->toBasetype()->ty == Tvoid)
    {
        error("Cannot perform array operations on void[] arrays");
        return new ErrorExp();
    }

    if (!isArrayOpValid(e2))
    {
        e2->error("invalid array operation %s (did you forget a [] ?)", toChars());
        return new ErrorExp();
    }

    Expressions *arguments = new Expressions();

    /* The expression to generate an array operation for is mangled
     * into a name to use as the array operation function name.
     * Mangle in the operands and operators in RPN order, and type.
     */
    OutBuffer buf;
    buf.writestring("_array");
    buildArrayIdent(&buf, arguments);
    buf.writeByte('_');

    /* Append deco of array element type
     */
#if DMDV2
    buf.writestring(type->toBasetype()->nextOf()->toBasetype()->mutableOf()->deco);
#else
    buf.writestring(type->toBasetype()->nextOf()->toBasetype()->deco);
#endif

    size_t namelen = buf.offset;
    buf.writeByte(0);
    char *name = buf.toChars();
    Identifier *ident = Lexer::idPool(name);

    /* Look up name in hash table
     */
    FuncDeclaration **pfd = (FuncDeclaration **)_aaGet(&arrayfuncs, ident);
    FuncDeclaration *fd = (FuncDeclaration *)*pfd;
    if (!fd)
    {
        /* Some of the array op functions are written as library functions,
         * presumably to optimize them with special CPU vector instructions.
         * List those library functions here, in alpha order.
         */
        static const char *libArrayopFuncs[] =
        {
            "_arrayExpSliceAddass_a",
            "_arrayExpSliceAddass_d",           // T[]+=T
            "_arrayExpSliceAddass_f",           // T[]+=T
            "_arrayExpSliceAddass_g",
            "_arrayExpSliceAddass_h",
            "_arrayExpSliceAddass_i",
            "_arrayExpSliceAddass_k",
            "_arrayExpSliceAddass_s",
            "_arrayExpSliceAddass_t",
            "_arrayExpSliceAddass_u",
            "_arrayExpSliceAddass_w",

            "_arrayExpSliceDivass_d",           // T[]/=T
            "_arrayExpSliceDivass_f",           // T[]/=T

            "_arrayExpSliceMinSliceAssign_a",
            "_arrayExpSliceMinSliceAssign_d",   // T[]=T-T[]
            "_arrayExpSliceMinSliceAssign_f",   // T[]=T-T[]
            "_arrayExpSliceMinSliceAssign_g",
            "_arrayExpSliceMinSliceAssign_h",
            "_arrayExpSliceMinSliceAssign_i",
            "_arrayExpSliceMinSliceAssign_k",
            "_arrayExpSliceMinSliceAssign_s",
            "_arrayExpSliceMinSliceAssign_t",
            "_arrayExpSliceMinSliceAssign_u",
            "_arrayExpSliceMinSliceAssign_w",

            "_arrayExpSliceMinass_a",
            "_arrayExpSliceMinass_d",           // T[]-=T
            "_arrayExpSliceMinass_f",           // T[]-=T
            "_arrayExpSliceMinass_g",
            "_arrayExpSliceMinass_h",
            "_arrayExpSliceMinass_i",
            "_arrayExpSliceMinass_k",
            "_arrayExpSliceMinass_s",
            "_arrayExpSliceMinass_t",
            "_arrayExpSliceMinass_u",
            "_arrayExpSliceMinass_w",

            "_arrayExpSliceMulass_d",           // T[]*=T
            "_arrayExpSliceMulass_f",           // T[]*=T
            "_arrayExpSliceMulass_i",
            "_arrayExpSliceMulass_k",
            "_arrayExpSliceMulass_s",
            "_arrayExpSliceMulass_t",
            "_arrayExpSliceMulass_u",
            "_arrayExpSliceMulass_w",

            "_arraySliceExpAddSliceAssign_a",
            "_arraySliceExpAddSliceAssign_d",   // T[]=T[]+T
            "_arraySliceExpAddSliceAssign_f",   // T[]=T[]+T
            "_arraySliceExpAddSliceAssign_g",
            "_arraySliceExpAddSliceAssign_h",
            "_arraySliceExpAddSliceAssign_i",
            "_arraySliceExpAddSliceAssign_k",
            "_arraySliceExpAddSliceAssign_s",
            "_arraySliceExpAddSliceAssign_t",
            "_arraySliceExpAddSliceAssign_u",
            "_arraySliceExpAddSliceAssign_w",

            "_arraySliceExpDivSliceAssign_d",   // T[]=T[]/T
            "_arraySliceExpDivSliceAssign_f",   // T[]=T[]/T

            "_arraySliceExpMinSliceAssign_a",
            "_arraySliceExpMinSliceAssign_d",   // T[]=T[]-T
            "_arraySliceExpMinSliceAssign_f",   // T[]=T[]-T
            "_arraySliceExpMinSliceAssign_g",
            "_arraySliceExpMinSliceAssign_h",
            "_arraySliceExpMinSliceAssign_i",
            "_arraySliceExpMinSliceAssign_k",
            "_arraySliceExpMinSliceAssign_s",
            "_arraySliceExpMinSliceAssign_t",
            "_arraySliceExpMinSliceAssign_u",
            "_arraySliceExpMinSliceAssign_w",

            "_arraySliceExpMulSliceAddass_d",   // T[] += T[]*T
            "_arraySliceExpMulSliceAddass_f",
            "_arraySliceExpMulSliceAddass_r",

            "_arraySliceExpMulSliceAssign_d",   // T[]=T[]*T
            "_arraySliceExpMulSliceAssign_f",   // T[]=T[]*T
            "_arraySliceExpMulSliceAssign_i",
            "_arraySliceExpMulSliceAssign_k",
            "_arraySliceExpMulSliceAssign_s",
            "_arraySliceExpMulSliceAssign_t",
            "_arraySliceExpMulSliceAssign_u",
            "_arraySliceExpMulSliceAssign_w",

            "_arraySliceExpMulSliceMinass_d",   // T[] -= T[]*T
            "_arraySliceExpMulSliceMinass_f",
            "_arraySliceExpMulSliceMinass_r",

            "_arraySliceSliceAddSliceAssign_a",
            "_arraySliceSliceAddSliceAssign_d", // T[]=T[]+T[]
            "_arraySliceSliceAddSliceAssign_f", // T[]=T[]+T[]
            "_arraySliceSliceAddSliceAssign_g",
            "_arraySliceSliceAddSliceAssign_h",
            "_arraySliceSliceAddSliceAssign_i",
            "_arraySliceSliceAddSliceAssign_k",
            "_arraySliceSliceAddSliceAssign_r", // T[]=T[]+T[]
            "_arraySliceSliceAddSliceAssign_s",
            "_arraySliceSliceAddSliceAssign_t",
            "_arraySliceSliceAddSliceAssign_u",
            "_arraySliceSliceAddSliceAssign_w",

            "_arraySliceSliceAddass_a",
            "_arraySliceSliceAddass_d",         // T[]+=T[]
            "_arraySliceSliceAddass_f",         // T[]+=T[]
            "_arraySliceSliceAddass_g",
            "_arraySliceSliceAddass_h",
            "_arraySliceSliceAddass_i",
            "_arraySliceSliceAddass_k",
            "_arraySliceSliceAddass_s",
            "_arraySliceSliceAddass_t",
            "_arraySliceSliceAddass_u",
            "_arraySliceSliceAddass_w",

            "_arraySliceSliceMinSliceAssign_a",
            "_arraySliceSliceMinSliceAssign_d", // T[]=T[]-T[]
            "_arraySliceSliceMinSliceAssign_f", // T[]=T[]-T[]
            "_arraySliceSliceMinSliceAssign_g",
            "_arraySliceSliceMinSliceAssign_h",
            "_arraySliceSliceMinSliceAssign_i",
            "_arraySliceSliceMinSliceAssign_k",
            "_arraySliceSliceMinSliceAssign_r", // T[]=T[]-T[]
            "_arraySliceSliceMinSliceAssign_s",
            "_arraySliceSliceMinSliceAssign_t",
            "_arraySliceSliceMinSliceAssign_u",
            "_arraySliceSliceMinSliceAssign_w",

            "_arraySliceSliceMinass_a",
            "_arraySliceSliceMinass_d",         // T[]-=T[]
            "_arraySliceSliceMinass_f",         // T[]-=T[]
            "_arraySliceSliceMinass_g",
            "_arraySliceSliceMinass_h",
            "_arraySliceSliceMinass_i",
            "_arraySliceSliceMinass_k",
            "_arraySliceSliceMinass_s",
            "_arraySliceSliceMinass_t",
            "_arraySliceSliceMinass_u",
            "_arraySliceSliceMinass_w",

            "_arraySliceSliceMulSliceAssign_d", // T[]=T[]*T[]
            "_arraySliceSliceMulSliceAssign_f", // T[]=T[]*T[]
            "_arraySliceSliceMulSliceAssign_i",
            "_arraySliceSliceMulSliceAssign_k",
            "_arraySliceSliceMulSliceAssign_s",
            "_arraySliceSliceMulSliceAssign_t",
            "_arraySliceSliceMulSliceAssign_u",
            "_arraySliceSliceMulSliceAssign_w",

            "_arraySliceSliceMulass_d",         // T[]*=T[]
            "_arraySliceSliceMulass_f",         // T[]*=T[]
            "_arraySliceSliceMulass_i",
            "_arraySliceSliceMulass_k",
            "_arraySliceSliceMulass_s",
            "_arraySliceSliceMulass_t",
            "_arraySliceSliceMulass_u",
            "_arraySliceSliceMulass_w",
        };

        int i = binary(name, libArrayopFuncs, sizeof(libArrayopFuncs) / sizeof(char *));
        if (i == -1)
        {
#ifdef DEBUG    // Make sure our array is alphabetized
            for (i = 0; i < sizeof(libArrayopFuncs) / sizeof(char *); i++)
            {
                if (strcmp(name, libArrayopFuncs[i]) == 0)
                    assert(0);
            }
#endif
            /* Not in library, so generate it.
             * Construct the function body:
             *  foreach (i; 0 .. p.length)    for (size_t i = 0; i < p.length; i++)
             *      loopbody;
             *  return p;
             */

            Parameters *fparams = new Parameters();
            Expression *loopbody = buildArrayLoop(fparams);
            Parameter *p = (*fparams)[0 /*fparams->dim - 1*/];
#if DMDV1
            // for (size_t i = 0; i < p.length; i++)
            Initializer *init = new ExpInitializer(0, new IntegerExp(0, 0, Type::tsize_t));
            Dsymbol *d = new VarDeclaration(0, Type::tsize_t, Id::p, init);
            Statement *s1 = new ForStatement(0,
                new DeclarationStatement(0, d),
                new CmpExp(TOKlt, 0, new IdentifierExp(0, Id::p), new ArrayLengthExp(0, new IdentifierExp(0, p->ident))),
                new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id::p)),
                new ExpStatement(0, loopbody));
#else
            // foreach (i; 0 .. p.length)
            Statement *s1 = new ForeachRangeStatement(0, TOKforeach,
                new Parameter(0, NULL, Id::p, NULL),
                new IntegerExp(0, 0, Type::tsize_t),
                new ArrayLengthExp(0, new IdentifierExp(0, p->ident)),
                new ExpStatement(0, loopbody));
#endif
            Statement *s2 = new ReturnStatement(0, new IdentifierExp(0, p->ident));
            //printf("s2: %s\n", s2->toChars());
            Statement *fbody = new CompoundStatement(0, s1, s2);

            /* Construct the function
             */
            TypeFunction *ftype = new TypeFunction(fparams, type, 0, LINKc);
            //printf("ftype: %s\n", ftype->toChars());
            fd = new FuncDeclaration(loc, 0, ident, STCundefined, ftype);
            fd->fbody = fbody;
            fd->protection = PROTpublic;
            fd->linkage = LINKc;
            fd->isArrayOp = 1;

            sc->module->importedFrom->members->push(fd);

            sc = sc->push();
            sc->parent = sc->module->importedFrom;
            sc->stc = 0;
            sc->linkage = LINKc;
            fd->semantic(sc);
            fd->semantic2(sc);
            fd->semantic3(sc);
            sc->pop();
        }
        else
        {   /* In library, refer to it.
             */
            fd = FuncDeclaration::genCfunc(type, ident);
        }
        *pfd = fd;      // cache symbol in hash table
    }

    /* Call the function fd(arguments)
     */
    Expression *ec = new VarExp(0, fd);
    Expression *e = new CallExp(loc, ec, arguments);
    e->type = type;
    return e;
}
Exemplo n.º 7
0
Arquivo: arrayop.c Projeto: BIGKAT/GDC
ArrayOp *buildArrayOp(Identifier *ident, BinExp *exp, Scope *sc, Loc loc)
{
    Parameters *fparams = new Parameters();
    Expression *loopbody = exp->buildArrayLoop(fparams);

    ArrayOp *op = new ArrayOp;
    if (isDruntimeArrayOp(ident))
        op->cFunc = FuncDeclaration::genCfunc(fparams, exp->type, ident);
    else
        op->cFunc = NULL;

    /* Construct the function body:
     *  foreach (i; 0 .. p.length)    for (size_t i = 0; i < p.length; i++)
     *      loopbody;
     *  return p;
     */

    Parameter *p = (*fparams)[0 /*fparams->dim - 1*/];
#if DMDV1
    // for (size_t i = 0; i < p.length; i++)
    Initializer *init = new ExpInitializer(0, new IntegerExp(0, 0, Type::tsize_t));
    Dsymbol *d = new VarDeclaration(0, Type::tsize_t, Id::p, init);
    Statement *s1 = new ForStatement(0,
        new ExpStatement(0, d),
        new CmpExp(TOKlt, 0, new IdentifierExp(0, Id::p), new ArrayLengthExp(0, new IdentifierExp(0, p->ident))),
        new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id::p)),
        new ExpStatement(0, loopbody));
#else
    // foreach (i; 0 .. p.length)
    Statement *s1 = new ForeachRangeStatement(Loc(), TOKforeach,
        new Parameter(0, NULL, Id::p, NULL),
        new IntegerExp(Loc(), 0, Type::tsize_t),
        new ArrayLengthExp(Loc(), new IdentifierExp(Loc(), p->ident)),
        new ExpStatement(Loc(), loopbody));
#endif
    //printf("%s\n", s1->toChars());
    Statement *s2 = new ReturnStatement(Loc(), new IdentifierExp(Loc(), p->ident));
    //printf("s2: %s\n", s2->toChars());
    Statement *fbody = new CompoundStatement(Loc(), s1, s2);

    // Built-in array ops should be @trusted, pure and nothrow
    StorageClass stc = STCtrusted | STCpure | STCnothrow;

    /* Construct the function
     */
    TypeFunction *ftype = new TypeFunction(fparams, exp->type, 0, LINKc, stc);
    //printf("ftype: %s\n", ftype->toChars());
    FuncDeclaration *fd = new FuncDeclaration(Loc(), Loc(), ident, STCundefined, ftype);
    fd->fbody = fbody;
    fd->protection = PROTpublic;
    fd->linkage = LINKc;
    fd->isArrayOp = 1;

    if (!op->cFunc)
        sc->module->importedFrom->members->push(fd);

    sc = sc->push();
    sc->parent = sc->module->importedFrom;
    sc->stc = 0;
    sc->linkage = LINKc;
    fd->semantic(sc);
    fd->semantic2(sc);
    fd->semantic3(sc);
    sc->pop();

    if (op->cFunc)
    {
        op->cFunc->dArrayOp = fd;
        op->cFunc->type = fd->type;
    }
    op->dFunc = fd;
    return op;
}
Exemplo n.º 8
0
void AggregateDeclaration::semantic3(Scope *sc)
{
    //printf("AggregateDeclaration::semantic3(%s)\n", toChars());
    if (members)
    {
        StructDeclaration *sd = isStructDeclaration();
        if (!sc)    // from runDeferredSemantic3 for TypeInfo generation
            goto Lxop;

        sc = sc->push(this);
        sc->parent = this;
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            s->semantic3(sc);
        }
        sc = sc->pop();

        if (!getRTInfo && Type::rtinfo &&
            (!isDeprecated() || global.params.useDeprecated) && // don't do it for unused deprecated types
            (type && type->ty != Terror)) // or error types
        {
            // Evaluate: RTinfo!type
            Objects *tiargs = new Objects();
            tiargs->push(type);
            TemplateInstance *ti = new TemplateInstance(loc, Type::rtinfo, tiargs);
            ti->semantic(sc);
            ti->semantic2(sc);
            ti->semantic3(sc);
            Dsymbol *s = ti->toAlias();
            Expression *e = new DsymbolExp(Loc(), s, 0);

            Scope *sc2 = ti->tempdecl->scope->startCTFE();
            sc2->instantiatingModule = sc->instantiatingModule ? sc->instantiatingModule : sc->module;
            e = e->semantic(sc2);
            sc2->endCTFE();

            e = e->ctfeInterpret();
            getRTInfo = e;
        }

        if (sd)
        {
        Lxop:
            if (sd->xeq &&
                sd->xeq->scope &&
                sd->xeq->semanticRun < PASSsemantic3done)
            {
                unsigned errors = global.startGagging();
                sd->xeq->semantic3(sd->xeq->scope);
                if (global.endGagging(errors))
                    sd->xeq = sd->xerreq;
            }

            if (sd->xcmp &&
                sd->xcmp->scope &&
                sd->xcmp->semanticRun < PASSsemantic3done)
            {
                unsigned errors = global.startGagging();
                sd->xcmp->semantic3(sd->xcmp->scope);
                if (global.endGagging(errors))
                    sd->xcmp = sd->xerrcmp;
            }

            FuncDeclaration *ftostr = search_toString(sd);
            if (ftostr &&
                ftostr->scope &&
                ftostr->semanticRun < PASSsemantic3done)
            {
                ftostr->semantic3(ftostr->scope);
            }

            FuncDeclaration *ftohash = search_toHash(sd);
            if (ftohash &&
                ftohash->scope &&
                ftohash->semanticRun < PASSsemantic3done)
            {
                ftohash->semantic3(ftohash->scope);
            }
        }
    }
}
Exemplo n.º 9
0
Arquivo: clone.c Projeto: Axure/ldc
FuncDeclaration *buildOpAssign(StructDeclaration *sd, Scope *sc)
{
    if (FuncDeclaration *f = hasIdentityOpAssign(sd, sc))
    {
        sd->hasIdentityAssign = true;
        return f;
    }
    // Even if non-identity opAssign is defined, built-in identity opAssign
    // will be defined.

    if (!needOpAssign(sd))
        return NULL;

    //printf("StructDeclaration::buildOpAssign() %s\n", toChars());
    StorageClass stc = STCsafe | STCnothrow | STCpure | STCnogc;
    Loc declLoc = sd->loc;
    Loc loc = Loc();    // internal code should have no loc to prevent coverage

    if (sd->dtor || sd->postblit)
    {
        if (!sd->type->isAssignable())  // Bugzilla 13044
            return NULL;
        if (sd->dtor)
        {
            stc = mergeFuncAttrs(stc, sd->dtor);
            if (stc & STCsafe)
                stc = (stc & ~STCsafe) | STCtrusted;
        }
    }
    else
    {
        for (size_t i = 0; i < sd->fields.dim; i++)
        {
            VarDeclaration *v = sd->fields[i];
            if (v->storage_class & STCref)
                continue;
            Type *tv = v->type->baseElemOf();
            if (tv->ty == Tstruct)
            {
                TypeStruct *ts = (TypeStruct *)tv;
                if (FuncDeclaration *f = hasIdentityOpAssign(ts->sym, sc))
                    stc = mergeFuncAttrs(stc, f);
            }
        }
    }

    Parameters *fparams = new Parameters;
    fparams->push(new Parameter(STCnodtor, sd->type, Id::p, NULL));
    Type *tf = new TypeFunction(fparams, sd->handleType(), 0, LINKd, stc | STCref);

    FuncDeclaration *fop = new FuncDeclaration(declLoc, Loc(), Id::assign, stc, tf);

    Expression *e = NULL;
    if (stc & STCdisable)
    {
    }
    else if (sd->dtor || sd->postblit)
    {
        /* Do swap this and rhs
         *    tmp = this; this = s; tmp.dtor();
         */
        //printf("\tswap copy\n");
        Identifier *idtmp = Lexer::uniqueId("__tmp");
        VarDeclaration *tmp = NULL;
        AssignExp *ec = NULL;
        if (sd->dtor)
        {
            tmp = new VarDeclaration(loc, sd->type, idtmp, new VoidInitializer(loc));
            tmp->noscope = 1;
            tmp->storage_class |= STCtemp | STCctfe;
            e = new DeclarationExp(loc, tmp);
            ec = new BlitExp(loc, new VarExp(loc, tmp), new ThisExp(loc));
            e = Expression::combine(e, ec);
        }
        ec = new BlitExp(loc, new ThisExp(loc), new IdentifierExp(loc, Id::p));
        e = Expression::combine(e, ec);
        if (sd->dtor)
        {
            /* Instead of running the destructor on s, run it
             * on tmp. This avoids needing to copy tmp back in to s.
             */
            Expression *ec2 = new DotVarExp(loc, new VarExp(loc, tmp), sd->dtor, 0);
            ec2 = new CallExp(loc, ec2);
            e = Expression::combine(e, ec2);
        }
    }
    else
    {
        /* Do memberwise copy
         */
        //printf("\tmemberwise copy\n");
        for (size_t i = 0; i < sd->fields.dim; i++)
        {
            VarDeclaration *v = sd->fields[i];
            // this.v = s.v;
            AssignExp *ec = new AssignExp(loc,
                new DotVarExp(loc, new ThisExp(loc), v, 0),
                new DotVarExp(loc, new IdentifierExp(loc, Id::p), v, 0));
            e = Expression::combine(e, ec);
        }
    }
    if (e)
    {
        Statement *s1 = new ExpStatement(loc, e);

        /* Add:
         *   return this;
         */
        e = new ThisExp(loc);
        Statement *s2 = new ReturnStatement(loc, e);

        fop->fbody = new CompoundStatement(loc, s1, s2);
    }

    sd->members->push(fop);
    fop->addMember(sc, sd, 1);
    sd->hasIdentityAssign = true;        // temporary mark identity assignable

    unsigned errors = global.startGagging();    // Do not report errors, even if the
    Scope *sc2 = sc->push();
    sc2->stc = 0;
    sc2->linkage = LINKd;

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

    sc2->pop();
    if (global.endGagging(errors))    // if errors happened
    {
        // Disable generated opAssign, because some members forbid identity assignment.
        fop->storage_class |= STCdisable;
        fop->fbody = NULL;  // remove fbody which contains the error
    }

    //printf("-StructDeclaration::buildOpAssign() %s, errors = %d\n", sd->toChars(), (fop->storage_class & STCdisable) != 0);

    return fop;
}
Exemplo n.º 10
0
Arquivo: struct.c Projeto: rainers/dmd
void AggregateDeclaration::semantic3(Scope *sc)
{
    //printf("AggregateDeclaration::semantic3(%s)\n", toChars());
    if (members)
    {
        StructDeclaration *sd = isStructDeclaration();
        if (!sc)    // from runDeferredSemantic3 for TypeInfo generation
            goto Lxop;

        sc = sc->push(this);
        sc->parent = this;
        for (size_t i = 0; i < members->dim; i++)
        {
            Dsymbol *s = (*members)[i];
            s->semantic3(sc);
        }
        sc = sc->pop();

        type->buildTypeInfo(sc, false); // implicitely calls generateTypeInfoData
        if (type->vtinfo && type->builtinTypeInfo())
            type->vtinfo->semantic3(sc);

        if (sd)
        {
        Lxop:
            if (sd->xeq &&
                sd->xeq->scope &&
                sd->xeq->semanticRun < PASSsemantic3done)
            {
                unsigned errors = global.startGagging();
                sd->xeq->semantic3(sd->xeq->scope);
                if (global.endGagging(errors))
                    sd->xeq = sd->xerreq;
            }

            if (sd->xcmp &&
                sd->xcmp->scope &&
                sd->xcmp->semanticRun < PASSsemantic3done)
            {
                unsigned errors = global.startGagging();
                sd->xcmp->semantic3(sd->xcmp->scope);
                if (global.endGagging(errors))
                    sd->xcmp = sd->xerrcmp;
            }

            FuncDeclaration *ftostr = search_toString(sd);
            if (ftostr &&
                ftostr->scope &&
                ftostr->semanticRun < PASSsemantic3done)
            {
                ftostr->semantic3(ftostr->scope);
            }

            FuncDeclaration *ftohash = search_toHash(sd);
            if (ftohash &&
                ftohash->scope &&
                ftohash->semanticRun < PASSsemantic3done)
            {
                ftohash->semantic3(ftohash->scope);
            }
        }
    }
}