void ExprDict::visit(ExpressionPtr e) { assert(m_canonIdMap.size() == m_canonTypeMap.size()); if (m_am.insertForDict(e)) { // we've never seen e's structure before, so record it record(e); if (e->getCanonID() >= m_canonTypeMap.size()) { m_canonTypeMap.resize(e->getCanonID() + 1); m_canonIdMap.resize(e->getCanonID() + 1); } m_canonTypeMap[e->getCanonID()] = TypePtrIdxPair(extractTypeAssertion(e), e->getCanonID()); m_canonIdMap[e->getCanonID()] = e->getCanonID(); } else if (e->isTypeAssertion()) { TypePtrIdxPairVec types; assert(isCanonicalStructure(e->getCanonID())); getTypes(e->getCanonID(), types); TypePtrIdxPair entry; if (containsAssertion(e->getAssertedType(), types, entry)) { e->setCanonID(entry.second); } else { // new type assertion seen, record it int oldId = e->getCanonID(); assert(isCanonicalStructure(oldId)); record(e); // insert it into the list if (e->getCanonID() >= m_canonTypeMap.size()) { m_canonTypeMap.resize(e->getCanonID() + 1); m_canonIdMap.resize(e->getCanonID() + 1); } m_canonIdMap[e->getCanonID()] = oldId; TypePtrIdxPair &head = m_canonTypeMap[oldId]; int oldSecond = head.second; head.second = e->getCanonID(); m_canonTypeMap[e->getCanonID()] = TypePtrIdxPair(e->getAssertedType(), oldSecond); } } }
TypePtr ExprDict::extractTypeAssertion(ExpressionPtr e) const { assert(e); return e->isTypeAssertion() ? e->getAssertedType() : TypePtr(); }