示例#1
0
Optional<ProjectionPath>
ProjectionPath::subtractPaths(const ProjectionPath &LHS, const ProjectionPath &RHS) {
    // If RHS is greater than or equal to LHS in size, RHS can not be a prefix of
    // LHS. Return None.
    unsigned RHSSize = RHS.size();
    unsigned LHSSize = LHS.size();
    if (RHSSize >= LHSSize)
        return llvm::NoneType::None;

    // First make sure that the prefix matches.
    Optional<ProjectionPath> P = ProjectionPath();
    for (unsigned i = 0; i < RHSSize; i++) {
        if (LHS.Path[i] != RHS.Path[i]) {
            P.reset();
            return P;
        }
    }

    // Add the rest of LHS to P and return P.
    for (unsigned i = RHSSize, e = LHSSize; i != e; ++i) {
        P->Path.push_back(LHS.Path[i]);
    }

    return P;
}
示例#2
0
/// TODO: Integrate has empty non-symmetric difference into here.
SubSeqRelation_t
ProjectionPath::
computeSubSeqRelation(const ProjectionPath &RHS) const {
    // If either path is empty, we can not prove anything, return Unrelated.
    if (empty() || RHS.empty())
        return SubSeqRelation_t::Unrelated;

    // We reverse the projection path to scan from the common object.
    auto LHSReverseIter = rbegin();
    auto RHSReverseIter = RHS.rbegin();

    unsigned MinPathSize = std::min(size(), RHS.size());

    // For each index i until min path size...
    for (unsigned i = 0; i != MinPathSize; ++i) {
        // Grab the current projections.
        const Projection &LHSProj = *LHSReverseIter;
        const Projection &RHSProj = *RHSReverseIter;

        // If the two projections do not equal exactly, return Unrelated.
        //
        // TODO: If Index equals zero, then we know that the two lists have nothing
        // in common and should return unrelated. If Index is greater than zero,
        // then we know that the two projection paths have a common base but a
        // non-empty symmetric difference. For now we just return Unrelated since I
        // can not remember why I had the special check in the
        // hasNonEmptySymmetricDifference code.
        if (LHSProj != RHSProj)
            return SubSeqRelation_t::Unrelated;

        // Otherwise increment reverse iterators.
        LHSReverseIter++;
        RHSReverseIter++;
    }

    // Ok, we now know that one of the paths is a subsequence of the other. If
    // both size() and RHS.size() equal then we know that the entire sequences
    // equal.
    if (size() == RHS.size())
        return SubSeqRelation_t::Equal;

    // If MinPathSize == size(), then we know that LHS is a strict subsequence of
    // RHS.
    if (MinPathSize == size())
        return SubSeqRelation_t::LHSStrictSubSeqOfRHS;

    // Otherwise, we know that MinPathSize must be RHS.size() and RHS must be a
    // strict subsequence of LHS. Assert to check this and return.
    assert(MinPathSize == RHS.size() &&
           "Since LHS and RHS don't equal and size() != MinPathSize, RHS.size() "
           "must equal MinPathSize");
    return SubSeqRelation_t::RHSStrictSubSeqOfLHS;
}
示例#3
0
/// Returns true if the two paths have a non-empty symmetric difference.
///
/// This means that the two objects have the same base but access different
/// fields of the base object.
bool
ProjectionPath::
hasNonEmptySymmetricDifference(const ProjectionPath &RHS) const {
    // If either the LHS or RHS is empty, there is no common base class. Return
    // false.
    if (empty() || RHS.empty())
        return false;

    // We reverse the projection path to scan from the common object.
    auto LHSReverseIter = Path.rbegin();
    auto RHSReverseIter = RHS.Path.rbegin();

    // For each index i until min path size...
    for (unsigned i = 0, e = std::min(size(), RHS.size()); i != e; ++i) {
        // Grab the current projections.
        const Projection &LHSProj = *LHSReverseIter;
        const Projection &RHSProj = *RHSReverseIter;

        // If we are accessing different fields of a common object, return
        // true. The two projection paths must have a non-empty symmetric
        // difference.
        if (areProjectionsToDifferentFields(LHSProj, RHSProj)) {
            DEBUG(llvm::dbgs() << "        Path different at index: " << i << '\n');
            return true;
        }

        // Otherwise, if the two projections equal exactly, they have no symmetric
        // difference.
        if (LHSProj == RHSProj)
            return false;

        // Continue if we are accessing the same field.
        LHSReverseIter++;
        RHSReverseIter++;
    }

    // We checked
    return false;
}