void ParserBase::popLabelInfo() { assert(!m_labelInfos.empty()); LabelInfo &info = m_labelInfos.back(); LabelMap labels = info.labels; // shallow copy for (unsigned int i = 0; i < info.gotos.size(); i++) { const GotoInfo &gotoInfo = info.gotos[i]; LabelMap::const_iterator iter = info.labels.find(gotoInfo.label); if (iter == info.labels.end()) { invalidateGoto(gotoInfo.stmt, UndefLabel); error("'goto' to undefined label '%s': %s", gotoInfo.label.c_str(), getMessage(gotoInfo.loc.get()).c_str()); continue; } const LabelStmtInfo &labelInfo = iter->second; if (gotoInfo.label.find(YIELD_LABEL_PREFIX) == 0) { labels.erase(gotoInfo.label); continue; } int labelScopeId = labelInfo.scopeId; bool found = false; for (int j = gotoInfo.scopes.size() - 1; j >= 0; j--) { if (labelScopeId == gotoInfo.scopes[j]) { found = true; break; } } if (!found) { invalidateGoto(gotoInfo.stmt, InvalidBlock); error("'goto' into loop or switch statement " "is disallowed: %s", getMessage(gotoInfo.loc.get()).c_str()); continue; } else { labels.erase(gotoInfo.label); } } // now invalidate all un-used labels for (LabelMap::const_iterator it(labels.begin()); it != labels.end(); ++it) { invalidateLabel(it->second.stmt); } m_labelInfos.pop_back(); }
void ParserBase::addLabel(const std::string &label, LocationPtr loc, ScannerToken *stmt) { assert(!m_labelInfos.empty()); LabelInfo &info = m_labelInfos.back(); if (info.labels.find(label) != info.labels.end()) { error("Label '%s' already defined: %s", label.c_str(), getMessage().c_str()); invalidateLabel(extractStatement(stmt)); return; } assert(!info.scopes.empty()); LabelStmtInfo labelInfo; labelInfo.scopeId = info.scopes.back(); labelInfo.stmt = extractStatement(stmt); labelInfo.loc = loc; info.labels[label] = labelInfo; }