LocalVar* find_local_var(const char* name, bool& in_closure) { VNode* vnode = getVStack(); ClosureParseEnvironment* cenv = thread_get_closure_parse_env(); in_closure = false; if (vnode && !vnode->lvar) vnode = vnode->nextSearch(); //printd(5, "find_local_var('%s' %p) vnode: %p\n", name, name, vnode); while (vnode) { assert(vnode->lvar); if (cenv && !in_closure && cenv->getHighWaterMark() == vnode) in_closure = true; //printd(5, "find_local_var('%s' %p) v: '%s' %p in_closure: %d match: %d\n", name, name, vnode->getName(), vnode->getName(), in_closure, !strcmp(vnode->getName(), name)); if (!strcmp(vnode->getName(), name)) { //printd(5, "find_local_var() %s in_closure: %d\n", name, in_closure); if (in_closure) cenv->add(vnode->lvar); vnode->setRef(); return vnode->lvar; } vnode = vnode->nextSearch(); } //printd(5, "find_local_var('%s' %p) returning 0 NOT FOUND\n", name, name); return 0; }
LocalVar* push_local_var(const char* name, const QoreProgramLocation& loc, const QoreTypeInfo* typeInfo, bool is_arg, int n_refs, bool top_level) { QoreProgram* pgm = getProgram(); LocalVar* lv = pgm->createLocalVar(name, typeInfo); QoreString ls; loc.toString(ls); //printd(5, "push_local_var() lv: %p name: %s type: %s %s\n", lv, name, typeInfo->getName(), ls.getBuffer()); bool found_block = false; // check stack for duplicate entries bool avs = parse_check_parse_option(PO_ASSUME_LOCAL); if (is_arg) { lv->parseAssigned(); if (pgm->checkWarning(QP_WARN_DUPLICATE_LOCAL_VARS | QP_WARN_DUPLICATE_BLOCK_VARS) || avs) { VNode* vnode = getVStack(); while (vnode) { if (!found_block && vnode->isBlockStart()) found_block = true; if (!strcmp(vnode->getName(), name)) { if (!found_block) { QoreStringNode* desc = new QoreStringNodeMaker("local variable '%s' was already declared in the same block", name); if (avs) { vnode->appendLocation(*desc); parseException(loc, "PARSE-ERRPR", desc); } else { vnode->appendLocation(*desc); qore_program_private::makeParseWarning(getProgram(), loc, QP_WARN_DUPLICATE_BLOCK_VARS, "DUPLICATE-BLOCK-VARIABLE", desc); } } else if (top_level || !vnode->isTopLevel()) { QoreStringNode* desc = new QoreStringNodeMaker("local variable '%s' was already declared in this lexical scope", name); vnode->appendLocation(*desc); qore_program_private::makeParseWarning(getProgram(), loc, QP_WARN_DUPLICATE_LOCAL_VARS, "DUPLICATE-LOCAL-VARIABLE", desc); } break; } vnode = vnode->nextSearch(); } } } //printd(5, "push_local_var(): pushing var %s\n", name); new VNode(lv, &loc, n_refs, top_level); return lv; }