diff --git a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp --- a/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/RangeConstraintManager.cpp @@ -584,6 +584,11 @@ LLVM_NODISCARD static inline Optional areEqual(ProgramStateRef State, SymbolRef First, SymbolRef Second); + void dumpToStream(ProgramStateRef State, raw_ostream &os) const; + LLVM_DUMP_METHOD void dump(ProgramStateRef State) const { + dumpToStream(State, llvm::errs()); + } + /// Check equivalence data for consistency. LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED static bool isClassDataConsistent(ProgramStateRef State); @@ -644,6 +649,46 @@ // Constraint functions //===----------------------------------------------------------------------===// +/// Dump all equivalence classes. +LLVM_DUMP_METHOD static void dumpEqToStream(ProgramStateRef State, + raw_ostream &os) { + ClassMembersTy Members = State->get(); + for (std::pair ClassToSymbolSet : Members) { + EquivalenceClass Class = ClassToSymbolSet.first; + Class.dumpToStream(State, os); + os << "\n"; + } +} +LLVM_DUMP_METHOD static void dumpEq(ProgramStateRef State) { + dumpEqToStream(State, llvm::errs()); +} + +/// Dump all equivalence classes along with their disequivalent classes if they +/// have any. +LLVM_DUMP_METHOD static void dumpDisEqToStream(ProgramStateRef State, + raw_ostream &os) { + DisequalityMapTy Disequalities = State->get(); + for (std::pair ClassToDisEqSet : Disequalities) { + EquivalenceClass Class = ClassToDisEqSet.first; + Class.dumpToStream(State, os); + ClassSet DisequalClasses = ClassToDisEqSet.second; + if (!DisequalClasses.isEmpty()) { + for (EquivalenceClass DisEqClass : DisequalClasses) { + os << "DisequalTo:\n"; + DisEqClass.dumpToStream(State, os); + } + } + os << "\n"; + } +} +LLVM_DUMP_METHOD static void dumpDisEq(ProgramStateRef State) { + dumpDisEqToStream(State, llvm::errs()); +} + +//===----------------------------------------------------------------------===// +// Constraint functions +//===----------------------------------------------------------------------===// + LLVM_NODISCARD LLVM_ATTRIBUTE_UNUSED bool areFeasible(ConstraintRangeTy Constraints) { return llvm::none_of( @@ -1589,6 +1634,15 @@ // EqualityClass implementation details //===----------------------------------------------------------------------===// +LLVM_DUMP_METHOD void EquivalenceClass::dumpToStream(ProgramStateRef State, + raw_ostream &os) const { + SymbolSet ClassMembers = getClassMembers(State); + for (const SymbolRef &MemberSym : ClassMembers) { + MemberSym->dump(); + os << "\n"; + } +} + inline EquivalenceClass EquivalenceClass::find(ProgramStateRef State, SymbolRef Sym) { // We store far from all Symbol -> Class mappings