Esempio n. 1
0
static void createCaller(void)
{
    FUNCTIONCALL *params = Alloc(sizeof(FUNCTIONCALL));
    TYPE *args = realArgs(lambdas->func);
    SYMBOL *func = makeID(sc_member, args, NULL, overloadNameTab[CI_FUNC]);
    SYMBOL *lambdaCall = search(isstructured(basetype(lambdas->func->tp)->btp) ? "__lambdaCallS" : "__lambdaCall", globalNameSpace->syms);
    BLOCKDATA block1, block2;
    STATEMENT *st;
    lambdaCall = (SYMBOL *)lambdaCall->tp->syms->table[0]->p;
    func->parentClass = lambdas->cls;
    func->linkage = lk_virtual;
    func->isInline = FALSE;
    func->omitFrame = TRUE;
    memset(&block1, 0, sizeof(BLOCKDATA));
    memset(&block2, 0, sizeof(BLOCKDATA));
    insertFunc(lambdas->cls, func);
    InsertInline(func);
    st = stmtNode(NULL, &block2, isstructured(basetype(lambdas->func->tp)->btp) ? st_expr : st_return);
    st->select = varNode(en_func, NULL);
    st->select->v.func = params;
    params->arguments = Alloc(sizeof(INITLIST));
    params->arguments->exp = varNode(en_pc, lambdas->func);
    params->arguments->tp = &stdpointer;
    params->ascall = TRUE;
    params->sp = func;
    params->fcall = varNode(en_pc, lambdaCall);
    params->functp = func->tp;
    st = stmtNode(NULL, &block1, st_block);
    st->lower = block2.head;
    st->blockTail = block2.blockTail;
    func->inlineFunc.stmt = stmtNode(NULL, NULL, st_block);
    func->inlineFunc.stmt->lower = block1.head;
    func->inlineFunc.stmt->blockTail = block1.blockTail;
}
void RecursiveCFGBuilder::visitStmt(ShPtr<Statement> stmt, bool visitSuccessors,
		bool visitNestedStmts) {
	if (!stmt) {
		return;
	}

	if (hasItem(accessedStmts, stmt)) {
		// The statement has been accessed.
		ShPtr<CFG::Node> stmtNode(firstStmtNodeMapping[stmt]);
		cfg->addEdge(currNode, stmtNode);
		return;
	}

	// When the statement is a goto target and there are some statements in the
	// current node, we have to emit the statement into a new node.
	if (stmt->isGotoTarget() && !currNode->stmts.empty()) {
		ShPtr<CFG::Node> prevNode(currNode);
		ShPtr<CFG::Node> stmtNode(addNode(stmt));
		cfg->addEdge(prevNode, stmtNode);
		return;
	}

	accessedStmts.insert(stmt);

	// The statement is not a goto target, so process it normally.
	stmt->accept(this);
}
Esempio n. 3
0
void AllocateLocalContext(BLOCKDATA *block, SYMBOL *sp)
{
    HASHTABLE *tn = CreateHashTable(1);
    STATEMENT *st;
    LIST *l;
    int label = nextLabel++;
    st = stmtNode(NULL, block, st_dbgblock);
    st->label = 1;
    if (block && cparams.prm_debug)
    {
        st = stmtNode(NULL, block, st_label);
        st->label = label;
        tn->blocknum = st->blocknum;
    }
    tn->next = tn->chain = localNameSpace->syms;
    localNameSpace->syms = tn;
    tn = CreateHashTable(1);
    if (block && cparams.prm_debug)
    {
        tn->blocknum = st->blocknum;
    }
    tn->next = tn->chain = localNameSpace->tags;
    localNameSpace->tags = tn;
    if (sp)
        localNameSpace->tags->blockLevel = sp->value.i++;
    
    l = Alloc(sizeof(LIST));
    l->data = localNameSpace->usingDirectives;
    l->next = usingDirectives;
    usingDirectives = l;
    
}
Esempio n. 4
0
void FreeLocalContext(BLOCKDATA *block, SYMBOL *sp)
{
    HASHTABLE *locals = localNameSpace->syms;
    HASHTABLE *tags = localNameSpace->tags;
    STATEMENT *st;
    int label = nextLabel++;
    if (block && cparams.prm_debug)
    {
        st = stmtNode(NULL, block, st_label);
        st->label = label;
    }
    checkUnused(localNameSpace->syms);
    if (sp && listFile)
    {
        if (localNameSpace->syms->table[0])
        {
            fprintf(listFile, "******** Local Symbols ********\n");
            list_table(sp->inlineFunc.syms,0);
            fprintf(listFile, "\n");
        }
        if (localNameSpace->tags->table[0])
        {
            fprintf(listFile,"******** Local Tags ********\n");
            list_table(sp->inlineFunc.tags, 0);
            fprintf(listFile, "\n");
        }
    }
    if (sp)
        sp->value.i--;

    st = stmtNode(NULL, block, st_expr);
    destructBlock(&st->select, localNameSpace->syms->table[0]);    
    localNameSpace->syms = localNameSpace->syms->next;
    localNameSpace->tags = localNameSpace->tags->next;

    localNameSpace->usingDirectives = usingDirectives->data;
    usingDirectives = usingDirectives->next;

#ifdef PARSER_ONLY
    TagSyms(locals);
    TagSyms(tags);
#endif
    if (sp)
    {
        locals->next = sp->inlineFunc.syms;
        tags->next = sp->inlineFunc.tags;
        sp->inlineFunc.syms = locals;
        sp->inlineFunc.tags = tags;
    }
    st = stmtNode(NULL, block, st_dbgblock);
    st->label = 0;
}
/**
* @brief Adds a forward or backward edge from the current node to the
*        successor/parent of @a stmt.
*
* @param[in] stmt Statement for which the edge is added.
* @param[in] edgeCond Optional condition of the added edge.
*
* If @c stmt->getParent() does not exist, it implies that there is an implicit
* return from the function. If it exists and it is a while or for loop, it
* creates a backward edge. If it is an if or switch statement, it creates a
* forward edge.
*
* Precondition:
*  - @a stmt doesn't have a (direct) successor
*
* This function may add new nodes.
*/
void RecursiveCFGBuilder::addForwardOrBackwardEdge(ShPtr<Statement> stmt,
		ShPtr<Expression> edgeCond) {
	PRECONDITION(!stmt->getSuccessor(), stmt << "should not have a successor;"
		"the successor is `" << stmt->getSuccessor() << "`");

	ShPtr<CFG::Node> stmtNode(currNode);
	cfg->addEdge(stmtNode, getIndirectSuccessor(stmt), edgeCond);
}
Esempio n. 6
0
// these next two rely on the CONST specifier on the func not being set up yet.
static SYMBOL *createPtrCaller(SYMBOL *self)
{
    // if the closure is copied then used on another thread yes the resulting
    // code can get into a race condition...
    INITLIST *args;
    FUNCTIONCALL *params = Alloc(sizeof(FUNCTIONCALL));
    TYPE *pargs = realArgs(lambdas->func);
    SYMBOL *func = makeID(sc_static, pargs, NULL, "$ptrcaller");
    SYMBOL *lambdaCall = search(isstructured(basetype(lambdas->func->tp)->btp) ? "__lambdaPtrCallS" : "__lambdaPtrCall", globalNameSpace->syms);
    BLOCKDATA block1, block2;
    STATEMENT *st;
    EXPRESSION *exp = varNode(en_label, self);
    lambdaCall = (SYMBOL *)lambdaCall->tp->syms->table[0]->p;
    func->parentClass = lambdas->cls;
    func->linkage = lk_virtual;
    func->isInline = FALSE;
    func->omitFrame = TRUE;
    deref(&stdpointer, &exp);
    memset(&block1, 0, sizeof(BLOCKDATA));
    memset(&block2, 0, sizeof(BLOCKDATA));
    insertFunc(lambdas->cls, func);
    st = stmtNode(NULL, &block2, isstructured(basetype(lambdas->func->tp)->btp) ? st_expr : st_return);
    st->select = varNode(en_func, NULL);
    st->select->v.func = params;
    params->arguments = Alloc(sizeof(INITLIST));
    params->arguments->exp = varNode(en_pc, lambdas->func);
    params->arguments->tp = &stdpointer;
    args = Alloc(sizeof(INITLIST));
    args->next = params->arguments;
    params->arguments = args;
    params->arguments->exp = exp;
    params->arguments->tp = &stdpointer;
    params->ascall = TRUE;
    params->sp = func;
    params->fcall = varNode(en_pc, lambdaCall);
    params->functp = func->tp;
    st = stmtNode(NULL, &block1, st_block);
    st->lower = block2.head;
    st->blockTail = block2. blockTail;
    func->inlineFunc.stmt = stmtNode(NULL, NULL, st_block);
    func->inlineFunc.stmt->lower = block1.head;
    func->inlineFunc.stmt->blockTail = block1.blockTail;
    return func;
}
Esempio n. 7
0
static void createConverter(SYMBOL *self)
{
    SYMBOL *caller = createPtrCaller(self);
    TYPE *args = realArgs(lambdas->func);
    SYMBOL *func = makeID(sc_member, Alloc(sizeof(TYPE)), NULL, overloadNameTab[CI_CAST]);
    BLOCKDATA block1, block2;
    STATEMENT *st;
    EXPRESSION *exp;
    SYMBOL *sym = makeID(sc_parameter, &stdvoid, NULL, AnonymousName());
    HASHREC *hr = Alloc(sizeof(HASHREC));
    func->tp->type = bt_func;
    func->tp->btp = Alloc(sizeof(TYPE));
    func->tp->btp->type = bt_pointer;
    func->tp->btp->size = getSize(bt_pointer);
    func->tp->btp->btp = args;
    func->tp->syms = CreateHashTable(1);
    func->linkage = lk_virtual;
    func->isInline = FALSE;
    hr->p = (struct _hrintern_ *)sym;
    func->tp->syms->table[0] = hr;
    func->parentClass = lambdas->cls;
    memset(&block1, 0, sizeof(BLOCKDATA));
    memset(&block2, 0, sizeof(BLOCKDATA));
    func->castoperator = TRUE;
    insertFunc(lambdas->cls, func);
    InsertInline(func);
    InsertInline(caller);
    st = stmtNode(NULL, &block2, st_return);
    st->select = varNode(en_pc, caller);
    st = stmtNode(NULL, &block1, st_block);
    st->lower = block2.head;
    st->blockTail = block2. blockTail;
    func->inlineFunc.stmt = stmtNode(NULL, NULL, st_block);
    func->inlineFunc.stmt->lower = block1.head;
    func->inlineFunc.stmt->blockTail = block1.blockTail;
}