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); }
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; }
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); }
// 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; }
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; }