void VarRefDeclNode::makeGlobal() { // could be tagged as local if allow-bare-refs is enabled assert(type == VT_UNRESOLVED || (type == VT_LOCAL && parse_check_parse_option(PO_ALLOW_BARE_REFS))); type = VT_GLOBAL; if (parseTypeInfo) ref.var = qore_root_ns_private::parseAddGlobalVarDef(name, takeParseTypeInfo()); else ref.var = qore_root_ns_private::parseAddResolvedGlobalVarDef(name, typeInfo); new_decl = true; }
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; }
AbstractQoreNode* UnresolvedCallReferenceNode::parseInit(LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo) { typeInfo = callReferenceTypeInfo; // try to resolve a method call if bare references are allowed // and we are parsing in an object context if (parse_check_parse_option(PO_ALLOW_BARE_REFS) && oflag) { const QoreClass* qc = oflag->getTypeInfo()->getUniqueReturnClass(); const QoreMethod* m = qore_class_private::parseFindSelfMethod(const_cast<QoreClass*>(qc), str); if (m) { ParseSelfMethodReferenceNode* rv = new ParseSelfMethodReferenceNode(m); delete this; return rv; } } return qore_root_ns_private::parseResolveCallReference(this); }
AbstractQoreNode* UnresolvedStaticMethodCallReferenceNode::parseInit(LocalVar* oflag, int pflag, int& lvids, const QoreTypeInfo*& typeInfo) { typeInfo = callReferenceTypeInfo; QoreClass* qc = qore_root_ns_private::parseFindScopedClassWithMethod(*scope, false); if (!qc) { // see if this is a function call to a function defined in a namespace const QoreFunction* f = qore_root_ns_private::parseResolveFunction(*scope); if (f) { LocalFunctionCallReferenceNode* fr = new LocalFunctionCallReferenceNode(f); deref(); return fr->parseInit(oflag, pflag, lvids, typeInfo); } parse_error("reference to undefined class '%s' in '%s()'", scope->get(scope->size() - 2), scope->ostr); return this; } const QoreMethod* qm = 0; // try to find a pointer to a non-static method if parsing in the class' context // and bare references are enabled if (oflag && parse_check_parse_option(PO_ALLOW_BARE_REFS) && oflag->getTypeInfo()->getUniqueReturnClass()->parseCheckHierarchy(qc)) { bool m_priv = false; qm = qore_class_private::parseFindMethodTree(*qc, scope->getIdentifier(), m_priv); assert(!qm || !qm->isStatic()); } if (!qm) { bool m_priv = false; qm = qore_class_private::parseFindStaticMethodTree(*qc, scope->getIdentifier(), m_priv); if (!qm) { parseException("INVALID-METHOD", "class '%s' has no static method '%s'", qc->getName(), scope->getIdentifier()); return this; } assert(qm->isStatic()); } // check class capabilities against parse options if (qore_program_private::parseAddDomain(getProgram(), qc->getDomain())) { parseException("class '%s' implements capabilities that are not allowed by current parse options", qc->getName()); return this; } AbstractQoreNode* rv = qm->isStatic() ? new LocalStaticMethodCallReferenceNode(qm) : new LocalMethodCallReferenceNode(qm); deref(); return rv; }