Exemple #1
0
EXPRESSION *anonymousVar(enum e_sc storage_class, TYPE *tp)
{
    static int anonct = 1;
    char buf[256];
    SYMBOL *rv = (SYMBOL *)Alloc(sizeof(SYMBOL));
//    if ((storage_class == sc_localstatic || storage_class == sc_auto) && !theCurrentFunc)
//    {
//        storage_class = sc_static;
//        insertInitSym(rv);
//    }
    if (tp->size == 0 && isstructured(tp))
        tp = basetype(tp)->sp->tp;
    rv->storage_class = storage_class;
    rv->tp = tp;
    rv->anonymous = TRUE;
    rv->allocate = !anonymousNotAlloc;
    rv->assigned = TRUE;
    rv->used = TRUE;
    if (theCurrentFunc)
        rv->value.i = theCurrentFunc->value.i;
    sprintf(buf,"$anontemp%d", anonct++);
    rv->name = litlate(buf);
    tp->size = basetype(tp)->size;
    if (theCurrentFunc && !inDefaultParam)
        InsertSymbol(rv, storage_class, FALSE, FALSE);
    SetLinkerNames(rv, lk_none);
    return varNode(storage_class == sc_auto || storage_class == sc_parameter ? en_auto : storage_class == sc_localstatic ? en_label : en_global, rv);
}
Exemple #2
0
void insertOverload(SYMBOL *in, HASHTABLE *table)
{
    if (cparams.prm_extwarning)
        if (in->storage_class == sc_parameter || in->storage_class == sc_auto ||
            in->storage_class == sc_register)
        {
            SYMBOL *sp;
            if ((sp = gsearch(in->name)) != NULL)
                preverror(ERR_VARIABLE_OBSCURES_VARIABLE_AT_HIGHER_SCOPE, in->name, 
                         sp->declfile, sp->declline);
        }
    if (AddOverloadName(in, table))
    {
#ifdef CPREPROCESSOR
        pperrorstr(ERR_DUPLICATE_IDENTIFIER, in->name);
#else
        SetLinkerNames(in, lk_cdecl);
    preverrorsym(ERR_DUPLICATE_IDENTIFIER, in, in->declfile, in->declline);
#endif
    }
}
Exemple #3
0
LEXEME *expression_lambda(LEXEME *lex, SYMBOL *funcsp, TYPE *atp, TYPE **tp, EXPRESSION **exp, int flags)
{
    LAMBDA *self;
    SYMBOL *vpl, *ths;
    HASHREC *hrl;
    TYPE *ltp;
    STRUCTSYM ssl;
    if (funcsp)
        funcsp->noinline = TRUE;
    IncGlobalFlag();
    self = Alloc(sizeof(LAMBDA));
    ltp = Alloc(sizeof(TYPE));
    ltp->type = bt_struct;
    ltp->syms = CreateHashTable(1);
    ltp->tags = CreateHashTable(1);
    ltp->size = 0;
    self->captured = CreateHashTable(1);
    self->oldSyms = localNameSpace->syms;
    self->oldTags = localNameSpace->tags;
    self->index = lambdaIndex;
    self->captureMode = cmNone;
    self->isMutable = FALSE;
    self->captureThis = FALSE;
    self->cls = makeID(sc_type, ltp, NULL, LambdaName());
    ltp->sp = self->cls;
    SetLinkerNames(self->cls, lk_cdecl);
    self->cls->islambda = TRUE;
    self->cls->structAlign = getAlign(sc_global, &stdpointer);
    self->func = makeID(sc_member, ltp, NULL, "$internalFunc");
    self->func->parentClass = self->cls;
    self->functp = &stdauto;
    self->enclosingFunc = theCurrentFunc;
    if (lambdas)
        lambdas->prev = self;
    self->next = lambdas;
    lambdas = self;
    
    localNameSpace->syms = CreateHashTable(1);
    localNameSpace->tags = CreateHashTable(1);
    if (lambdas->next)
    {
        self->lthis = lambdas->next->lthis;
    }
    else if (funcsp && funcsp->parentClass)
    {
        self->lthis = ((SYMBOL *)funcsp->tp->syms->table[0]->p);
    }
    lex = getsym(); // past [
    if (funcsp)
    {
        // can have a capture list;
        if (MATCHKW(lex, assign))
        {
            lex = getsym();
            if (MATCHKW(lex, comma) || MATCHKW(lex, closebr))
            {
                self->captureMode = cmValue;
                skip(&lex, comma);
            }
            else
            {
                lex = backupsym();
            }
        }
        else if (MATCHKW(lex, and))
        {
            lex = getsym();
            if (MATCHKW(lex, comma) || MATCHKW(lex, closebr))
            {
                self->captureMode = cmRef;
                skip(&lex, comma);
            }
            else
            {
                lex = backupsym();
            }
        }
        if (!MATCHKW(lex, comma) && !MATCHKW(lex, closebr))
        {
            do            
            {
                enum e_cm localMode = self->captureMode;
                if (MATCHKW(lex, comma))
                    skip(&lex, comma);
                if (MATCHKW(lex, kw_this))
                {
                    lex = getsym();
                    if (localMode == cmValue || !self->lthis)
                    {
                        error(ERR_CANNOT_CAPTURE_THIS);
                    }
                    else
                    {
                        if (self->captureThis)
                        {
                            error(ERR_CAPTURE_ITEM_LISTED_MULTIPLE_TIMES);
                        }
                        self->captureThis = TRUE;
                        lambda_capture(NULL, cmThis, TRUE);
                    }
                    continue;
                }
                else if (MATCHKW(lex, and))
                {
                    if (localMode == cmRef)
                    {
                        error(ERR_INVALID_LAMBDA_CAPTURE_MODE);
                    }
                    localMode = cmRef;
                    lex = getsym();
                }
                else 
                {
                    if (localMode == cmValue)
                    {
                        error(ERR_INVALID_LAMBDA_CAPTURE_MODE);
                    }
                    localMode = cmValue;
                }
                if (ISID(lex))
                {
                    SYMBOL *sp = search(lex->value.s.a, localNameSpace->syms);
                    LAMBDA *current = lambdas;
                    while (current && !sp)
                    {
                        sp = search(lex->value.s.a, current->oldSyms);
                        current = current->next;
                        
                    }
                    lex = getsym();
                    if (sp)
                    {
                        if (sp->packed)
                        {
                            if (!MATCHKW(lex, ellipse))
                                error(ERR_PACK_SPECIFIER_REQUIRED_HERE);
                            else
                                lex = getsym();
                        }
                        if (sp->packed)
                        {
                            int n;
                            TEMPLATEPARAMLIST * templateParam = sp->tp->templateParam->p->byPack.pack;
                            HASHREC *hr;
                            for (n=0; templateParam; templateParam = templateParam->next, n++);
                            hr = funcsp->tp->syms->table[0];
                            while (hr && ((SYMBOL *)hr->p) != sp)
                                hr = hr->next;
                            while (hr && n)
                            {
                                lambda_capture((SYMBOL *)hr->p, localMode, TRUE);
                                hr = hr->next;
                                n--;
                            }
                        }
                        else
                        {
                            lambda_capture(sp, localMode, TRUE);
                        }
                    }
                    else
                        errorstr(ERR_UNDEFINED_IDENTIFIER, lex->value.s.a);
                }
                else
                {
                    error(ERR_INVALID_LAMBDA_CAPTURE_MODE);
                }
            } while (MATCHKW(lex, comma));
        }
        needkw(&lex, closebr);
    }
    else
    {
        if (!MATCHKW(lex, closebr))
        {
            error(ERR_LAMBDA_CANNOT_CAPTURE);
        }
        else
        {
            lex = getsym();
        }
    }
    if (MATCHKW(lex, openpa))
    {
        TYPE *tpx = &stdvoid;
        HASHREC *hr;
        lex = getFunctionParams(lex, NULL, &self->func, &tpx, FALSE, sc_auto);
        self->funcargs = self->func->tp->syms->table[0];
        hr = self->func->tp->syms->table[0];
        while (hr)
        {
            SYMBOL *sym = (SYMBOL *)hr->p;
            if (sym->init)
            {
                error(ERR_CANNOT_DEFAULT_PARAMETERS_WITH_LAMBDA);
            }
            hr = hr->next;
        }
        if (MATCHKW(lex, kw_mutable))
        {
            HASHREC *hr = self->captured->table[0];
            while (hr)
            {
                LAMBDASP *lsp = (LAMBDASP *)hr->p;
                if (lsp->sym->lambdaMode == cmValue)
                {
                    lsp->sym->tp = basetype(lsp->sym->tp);
                }
                hr = hr->next;
            }
            self->isMutable = TRUE;
            
            lex = getsym();
        }
        ParseAttributeSpecifiers(&lex, funcsp, TRUE);
        if (MATCHKW(lex, pointsto))
        {
            lex = getsym();
            lex = get_type_id(lex, &self->functp, funcsp, sc_cast, FALSE, TRUE);
        }
    }
    else
    {
        TYPE *tp1 = Alloc(sizeof(TYPE));
        SYMBOL *spi;
        tp1->type = bt_func;
        tp1->size = getSize(bt_pointer);
        tp1->btp = &stdvoid;
        tp1->sp = self->func;
        self->func->tp = tp1;
        spi = makeID(sc_parameter, tp1, NULL, AnonymousName());
        spi->anonymous = TRUE;
        spi->tp = Alloc(sizeof(TYPE));
        spi->tp->type = bt_void;
        insert(spi, localNameSpace->syms);
        SetLinkerNames(spi, lk_cpp);
        self->func->tp->syms = localNameSpace->syms;
        self->funcargs = self->func->tp->syms->table[0];
        self->func->tp->syms->table[0] = NULL;
    }
    vpl = makeID(sc_parameter, &stdpointer, NULL, AnonymousName());
    vpl->assigned = vpl->used = TRUE;
    SetLinkerNames(vpl, lk_cdecl);
    hrl = Alloc(sizeof(HASHREC));
    hrl->p = (struct _hrintern_ *)vpl;
    hrl->next = lambdas->func->tp->syms->table[0];
    lambdas->func->tp->syms->table[0] = hrl;
    vpl = makeID(sc_parameter, &stdpointer, NULL, AnonymousName());
    vpl->assigned = vpl->used = TRUE;
    SetLinkerNames(vpl, lk_cdecl);
    hrl = Alloc(sizeof(HASHREC));
    hrl->p = (struct _hrintern_ *)vpl;
    hrl->next = lambdas->func->tp->syms->table[0];
    lambdas->func->tp->syms->table[0] = hrl;
    SetLinkerNames(lambdas->func, lk_cdecl);
    injectThisPtr(lambdas->func, basetype(lambdas->func->tp)->syms);
    lambdas->func->tp->btp = self->functp;
    lambdas->func->linkage = lk_virtual;
    lambdas->func->isInline = TRUE;
    ssl.str = self->cls;
    ssl.tmpl = NULL;
    addStructureDeclaration(&ssl);
    ths = makeID(sc_member, &stdpointer, NULL, "$this");
    lambda_insert(ths, lambdas);
    if (MATCHKW(lex, begin))
    {
        lex = body(lex, self->func);
    }
    else
    {
        error(ERR_LAMBDA_FUNCTION_BODY_EXPECTED);
    }
    dropStructureDeclaration();
    localNameSpace->syms = self->oldSyms;
    localNameSpace->tags = self->oldTags;
    inferType();
    finishClass();
    *exp = createLambda(0);
    *tp = lambdas->cls->tp;
    lambdas = lambdas->next;
    if (lambdas)
        lambdas->prev = NULL;
    DecGlobalFlag();
    return lex;
}
Exemple #4
0
static EXPRESSION *createLambda(BOOLEAN noinline)
{
    EXPRESSION *rv = NULL, **cur = &rv;
    HASHREC *hr;
    EXPRESSION *clsThs, *parentThs;
    SYMBOL *cls = makeID(lambdas->enclosingFunc ? sc_auto : sc_localstatic, lambdas->cls->tp, NULL, AnonymousName());
    SetLinkerNames(cls, lk_cdecl);
    cls->allocate = TRUE;
    if (lambdas->enclosingFunc)
    {
        insert(cls, localNameSpace->syms);
        clsThs = varNode(en_auto, cls); // this ptr
    }
    else
    {
        insert(cls, globalNameSpace->syms); // well if we could put this as an auto in the init func that would be good but there is no way to do that here...
        clsThs = varNode(en_label, cls); // this ptr
        cls->label = nextLabel++;
        insertInitSym(cls);
    }
    {
        INITIALIZER *init = NULL;
        EXPRESSION *exp = clsThs;
        callDestructor(cls, NULL, &exp, NULL, TRUE, FALSE, FALSE);
        initInsert(&init, cls->tp, exp, 0, TRUE);
        if (cls->storage_class != sc_auto)
        {
            insertDynamicDestructor(cls, init);
        }
        else
        {
            cls->dest = init;
        }
    }
    parentThs = varNode(en_auto, (SYMBOL *)basetype(lambdas->func->tp)->syms->table[0]->p); // this ptr
    hr = lambdas->cls->tp->syms->table[0];
    while (hr)
    {
        SYMBOL *sp = (SYMBOL *)hr->p;
        EXPRESSION *en = NULL, *en1 = NULL;
        if (!strcmp(sp->name, "$self"))
        {
            en1 = clsThs;
            en = varNode(en_label, sp);
            deref(&stdpointer, &en);
            en = exprNode(en_assign, en, en1);
        }
        else if (!strcmp(sp->name, "$parent"))
        {
            en1 = parentThs; // get parent from function call
            deref(&stdpointer, &en1);
            en = exprNode(en_add, clsThs, intNode(en_c_i, sp->offset)) ;
            deref(&stdpointer, &en);
            en = exprNode(en_assign, en, en1);
        }
        else if (!strcmp(sp->name, "$this"))
        {
            if (!lambdas->next || !lambdas->captureThis)
            {
                en1 = parentThs; // get parent from function call
            }
            else
            {
                SYMBOL *parent = search("$parent", lambdas->cls->tp->syms);
                en1 = varNode(en_auto, cls);
                deref(&stdpointer, &en1);
                en1 = exprNode(en_add, en1, intNode(en_c_i, parent->offset));
            }
            deref(&stdpointer, &en1);
            en = exprNode(en_add, clsThs, intNode(en_c_i, sp->offset)) ;
            deref(&stdpointer, &en);
            en = exprNode(en_assign, en, en1);
        }
        else if (sp->lambdaMode)
        {
            LAMBDASP *lsp = (LAMBDASP *)search(sp->name, lambdas->captured);
            if (lsp)
            {
                en1 = exprNode(en_add, clsThs, intNode(en_c_i, sp->offset));
                if (sp->lambdaMode == cmRef)
                {
                    SYMBOL *capture = lsp->parent;
                    deref(&stdpointer, &en1);
                    if (capture->lambdaMode)
                    {
                        en = parentThs;
                        deref(&stdpointer, &en);
                        en = exprNode(en_add, en, intNode(en_c_i, capture->offset));
                    }
                    else // must be an sc_auto
                    {
                        en = varNode(en_auto, capture);
                    }
                    if (isref(capture->tp))
                    {
                        deref(&stdpointer, &en);
                    }
                    en = exprNode(en_assign, en1, en);
                }
                else // cmValue
                {
                    SYMBOL *capture = lsp->parent;
                    TYPE *ctp = capture->tp;
                    if (capture->lambdaMode)
                    {
                        en = parentThs;
                        deref(&stdpointer, &en);
                        en = exprNode(en_add, en, intNode(en_c_i, capture->offset));
                    }
                    else // must be an sc_auto
                    {
                        en = varNode(en_auto, capture);
                    }
                    if (isref(ctp))
                    {
                        ctp = basetype(ctp)->btp;
                        deref(&stdpointer, &en);
                    }
                    if (isstructured(ctp))
                    {
                        FUNCTIONCALL *params = (FUNCTIONCALL *)Alloc(sizeof(FUNCTIONCALL));
                        params->arguments = (INITLIST *)Alloc(sizeof(INITLIST));
                        params->arguments->tp = ctp;
                        params->arguments->exp = en;
                        if (!callConstructor(&ctp, &en1, params, FALSE, NULL, TRUE, FALSE, TRUE, FALSE, FALSE))
                            errorsym(ERR_NO_APPROPRIATE_CONSTRUCTOR, lsp->sym);
                        en = en1;
                    }
                    else
                    {
                        deref(ctp, &en1);
                        deref(ctp, &en);
                        en = exprNode(en_assign, en1, en);
                    }
                }
            }
            else
            {
                diag("createLambda: no capture var");
            }
        }
        if (en)
        {
            *cur = exprNode(en_void, en, NULL);
            cur = &(*cur)->right;            
        }
        hr = hr->next;
    }
    *cur = clsThs; // this expression will be used in copy constructors, or discarded if unneeded
    return rv;
}