return Error::success();
}
-static std::vector<std::pair<uint32_t, DbiModuleDescriptor>>
+typedef std::pair<uint32_t, DbiModuleDescriptor> IndexedModuleDescriptor;
+typedef std::vector<IndexedModuleDescriptor> IndexedModuleDescriptorList;
+
+static IndexedModuleDescriptorList
getModuleDescriptors(const DbiModuleList &ML) {
- std::vector<std::pair<uint32_t, DbiModuleDescriptor>> List;
+ IndexedModuleDescriptorList List;
List.reserve(ML.getModuleCount());
for (uint32_t I = 0; I < ML.getModuleCount(); ++I)
List.emplace_back(I, ML.getModuleDescriptor(I));
return List;
}
-static void
-diffOneModule(DiffPrinter &D,
- const std::pair<uint32_t, DbiModuleDescriptor> Item,
- std::vector<std::pair<uint32_t, DbiModuleDescriptor>> &Other,
- bool ItemIsRight) {
+static IndexedModuleDescriptorList::iterator
+findOverrideEquivalentModule(uint32_t Modi,
+ IndexedModuleDescriptorList &OtherList) {
+ auto &EqMap = opts::diff::Equivalences;
+
+ auto Iter = EqMap.find(Modi);
+ if (Iter == EqMap.end())
+ return OtherList.end();
+
+ uint32_t EqValue = Iter->second;
+
+ return llvm::find_if(OtherList,
+ [EqValue](const IndexedModuleDescriptor &Desc) {
+ return Desc.first == EqValue;
+ });
+}
+
+static IndexedModuleDescriptorList::iterator
+findEquivalentModule(const IndexedModuleDescriptor &Item,
+ IndexedModuleDescriptorList &OtherList, bool ItemIsRight) {
+
+ if (!ItemIsRight) {
+ uint32_t Modi = Item.first;
+ auto OverrideIter = findOverrideEquivalentModule(Modi, OtherList);
+ if (OverrideIter != OtherList.end())
+ return OverrideIter;
+ }
+
+ BinaryPathProvider PathProvider(28);
+
+ auto Iter = OtherList.begin();
+ auto End = OtherList.end();
+ for (; Iter != End; ++Iter) {
+ const IndexedModuleDescriptor *Left = &Item;
+ const IndexedModuleDescriptor *Right = &*Iter;
+ if (ItemIsRight)
+ std::swap(Left, Right);
+ DiffResult Result = PathProvider.compare(Left->second.getModuleName(),
+ Right->second.getModuleName());
+ if (Result == DiffResult::EQUIVALENT || Result == DiffResult::IDENTICAL)
+ return Iter;
+ }
+ return OtherList.end();
+}
+
+static void diffOneModule(DiffPrinter &D, const IndexedModuleDescriptor &Item,
+ IndexedModuleDescriptorList &Other,
+ bool ItemIsRight) {
StreamPurposeProvider HeaderProvider(70);
std::pair<StreamPurpose, std::string> Header;
Header.first = StreamPurpose::ModuleStream;
const auto *L = &Item;
- BinaryPathProvider PathProvider(28);
- auto Iter = llvm::find_if(
- Other, [&PathProvider, ItemIsRight,
- L](const std::pair<uint32_t, DbiModuleDescriptor> &Other) {
- const auto *Left = L;
- const auto *Right = &Other;
- if (ItemIsRight)
- std::swap(Left, Right);
- DiffResult Result = PathProvider.compare(Left->second.getModuleName(),
- Right->second.getModuleName());
- return Result == DiffResult::EQUIVALENT ||
- Result == DiffResult::IDENTICAL;
- });
+ auto Iter = findEquivalentModule(Item, Other, ItemIsRight);
if (Iter == Other.end()) {
// We didn't find this module at all on the other side. Just print one row
// and continue.
- D.print<ModiProvider>("- Modi", Item.first, None);
+ if (ItemIsRight)
+ D.print<ModiProvider>("- Modi", None, Item.first);
+ else
+ D.print<ModiProvider>("- Modi", Item.first, None);
return;
}
if (ItemIsRight)
std::swap(L, R);
+ BinaryPathProvider PathProvider(28);
D.print<ModiProvider>("- Modi", L->first, R->first);
D.print<BinaryPathProvider>("- Obj File Name", L->second.getObjFileName(),
R->second.getObjFileName(), PathProvider);
cl::desc("Print a column with the result status"),
cl::Optional, cl::sub(DiffSubcommand));
+cl::list<std::string>
+ RawModiEquivalences("modi-equivalence", cl::ZeroOrMore,
+ cl::value_desc("left,right"),
+ cl::desc("Modules with the specified indices will be "
+ "treated as referring to the same module"),
+ cl::sub(DiffSubcommand));
+
cl::opt<std::string> LeftRoot(
"left-bin-root", cl::Optional,
cl::desc("Treats the specified path as the root of the tree containing "
cl::sub(DiffSubcommand));
cl::opt<std::string> Right(cl::Positional, cl::desc("<right>"),
cl::sub(DiffSubcommand));
+
+llvm::DenseMap<uint32_t, uint32_t> Equivalences;
}
cl::OptionCategory FileOptions("Module & File Options");
std::for_each(opts::bytes::InputFilenames.begin(),
opts::bytes::InputFilenames.end(), dumpBytes);
} else if (opts::DiffSubcommand) {
+ for (StringRef S : opts::diff::RawModiEquivalences) {
+ StringRef Left;
+ StringRef Right;
+ std::tie(Left, Right) = S.split(',');
+ uint32_t X, Y;
+ if (!to_integer(Left, X) || !to_integer(Right, Y)) {
+ errs() << formatv("invalid value {0} specified for modi equivalence\n",
+ S);
+ exit(1);
+ }
+ opts::diff::Equivalences[X] = Y;
+ }
+
diff(opts::diff::Left, opts::diff::Right);
} else if (opts::MergeSubcommand) {
if (opts::merge::InputFilenames.size() < 2) {