1*bdd1243dSDimitry Andric //===-- LVSort.cpp --------------------------------------------------------===//
2*bdd1243dSDimitry Andric //
3*bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*bdd1243dSDimitry Andric //
7*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
8*bdd1243dSDimitry Andric //
9*bdd1243dSDimitry Andric // Support for LVObject sorting.
10*bdd1243dSDimitry Andric //
11*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
12*bdd1243dSDimitry Andric 
13*bdd1243dSDimitry Andric #include "llvm/DebugInfo/LogicalView/Core/LVSort.h"
14*bdd1243dSDimitry Andric #include "llvm/DebugInfo/LogicalView/Core/LVElement.h"
15*bdd1243dSDimitry Andric #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
16*bdd1243dSDimitry Andric #include <string>
17*bdd1243dSDimitry Andric 
18*bdd1243dSDimitry Andric using namespace llvm;
19*bdd1243dSDimitry Andric using namespace llvm::logicalview;
20*bdd1243dSDimitry Andric 
21*bdd1243dSDimitry Andric #define DEBUG_TYPE "Sort"
22*bdd1243dSDimitry Andric 
23*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
24*bdd1243dSDimitry Andric // Callback functions to sort objects.
25*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
26*bdd1243dSDimitry Andric // Callback comparator based on kind.
compareKind(const LVObject * LHS,const LVObject * RHS)27*bdd1243dSDimitry Andric LVSortValue llvm::logicalview::compareKind(const LVObject *LHS,
28*bdd1243dSDimitry Andric                                            const LVObject *RHS) {
29*bdd1243dSDimitry Andric   return std::string(LHS->kind()) < std::string(RHS->kind());
30*bdd1243dSDimitry Andric }
31*bdd1243dSDimitry Andric 
32*bdd1243dSDimitry Andric // Callback comparator based on line.
compareLine(const LVObject * LHS,const LVObject * RHS)33*bdd1243dSDimitry Andric LVSortValue llvm::logicalview::compareLine(const LVObject *LHS,
34*bdd1243dSDimitry Andric                                            const LVObject *RHS) {
35*bdd1243dSDimitry Andric   return LHS->getLineNumber() < RHS->getLineNumber();
36*bdd1243dSDimitry Andric }
37*bdd1243dSDimitry Andric 
38*bdd1243dSDimitry Andric // Callback comparator based on name.
compareName(const LVObject * LHS,const LVObject * RHS)39*bdd1243dSDimitry Andric LVSortValue llvm::logicalview::compareName(const LVObject *LHS,
40*bdd1243dSDimitry Andric                                            const LVObject *RHS) {
41*bdd1243dSDimitry Andric   return LHS->getName() < RHS->getName();
42*bdd1243dSDimitry Andric }
43*bdd1243dSDimitry Andric 
44*bdd1243dSDimitry Andric // Callback comparator based on DIE offset.
compareOffset(const LVObject * LHS,const LVObject * RHS)45*bdd1243dSDimitry Andric LVSortValue llvm::logicalview::compareOffset(const LVObject *LHS,
46*bdd1243dSDimitry Andric                                              const LVObject *RHS) {
47*bdd1243dSDimitry Andric   return LHS->getOffset() < RHS->getOffset();
48*bdd1243dSDimitry Andric }
49*bdd1243dSDimitry Andric 
50*bdd1243dSDimitry Andric // Callback comparator for Range compare.
compareRange(const LVObject * LHS,const LVObject * RHS)51*bdd1243dSDimitry Andric LVSortValue llvm::logicalview::compareRange(const LVObject *LHS,
52*bdd1243dSDimitry Andric                                             const LVObject *RHS) {
53*bdd1243dSDimitry Andric   if (LHS->getLowerAddress() < RHS->getLowerAddress())
54*bdd1243dSDimitry Andric     return true;
55*bdd1243dSDimitry Andric 
56*bdd1243dSDimitry Andric   // If the lower address is the same, use the upper address value in
57*bdd1243dSDimitry Andric   // order to put first the smallest interval.
58*bdd1243dSDimitry Andric   if (LHS->getLowerAddress() == RHS->getLowerAddress())
59*bdd1243dSDimitry Andric     return LHS->getUpperAddress() < RHS->getUpperAddress();
60*bdd1243dSDimitry Andric 
61*bdd1243dSDimitry Andric   return false;
62*bdd1243dSDimitry Andric }
63*bdd1243dSDimitry Andric 
64*bdd1243dSDimitry Andric // Callback comparator based on multiple keys (First: Kind).
sortByKind(const LVObject * LHS,const LVObject * RHS)65*bdd1243dSDimitry Andric LVSortValue llvm::logicalview::sortByKind(const LVObject *LHS,
66*bdd1243dSDimitry Andric                                           const LVObject *RHS) {
67*bdd1243dSDimitry Andric   // Order in which the object attributes are used for comparison:
68*bdd1243dSDimitry Andric   // kind, name, line number, offset.
69*bdd1243dSDimitry Andric   std::tuple<std::string, StringRef, uint32_t, LVOffset> Left(
70*bdd1243dSDimitry Andric       LHS->kind(), LHS->getName(), LHS->getLineNumber(), LHS->getOffset());
71*bdd1243dSDimitry Andric   std::tuple<std::string, StringRef, uint32_t, LVOffset> Right(
72*bdd1243dSDimitry Andric       RHS->kind(), RHS->getName(), RHS->getLineNumber(), RHS->getOffset());
73*bdd1243dSDimitry Andric   return Left < Right;
74*bdd1243dSDimitry Andric }
75*bdd1243dSDimitry Andric 
76*bdd1243dSDimitry Andric // Callback comparator based on multiple keys (First: Line).
sortByLine(const LVObject * LHS,const LVObject * RHS)77*bdd1243dSDimitry Andric LVSortValue llvm::logicalview::sortByLine(const LVObject *LHS,
78*bdd1243dSDimitry Andric                                           const LVObject *RHS) {
79*bdd1243dSDimitry Andric   // Order in which the object attributes are used for comparison:
80*bdd1243dSDimitry Andric   // line number, name, kind, offset.
81*bdd1243dSDimitry Andric   std::tuple<uint32_t, StringRef, std::string, LVOffset> Left(
82*bdd1243dSDimitry Andric       LHS->getLineNumber(), LHS->getName(), LHS->kind(), LHS->getOffset());
83*bdd1243dSDimitry Andric   std::tuple<uint32_t, StringRef, std::string, LVOffset> Right(
84*bdd1243dSDimitry Andric       RHS->getLineNumber(), RHS->getName(), RHS->kind(), RHS->getOffset());
85*bdd1243dSDimitry Andric   return Left < Right;
86*bdd1243dSDimitry Andric }
87*bdd1243dSDimitry Andric 
88*bdd1243dSDimitry Andric // Callback comparator based on multiple keys (First: Name).
sortByName(const LVObject * LHS,const LVObject * RHS)89*bdd1243dSDimitry Andric LVSortValue llvm::logicalview::sortByName(const LVObject *LHS,
90*bdd1243dSDimitry Andric                                           const LVObject *RHS) {
91*bdd1243dSDimitry Andric   // Order in which the object attributes are used for comparison:
92*bdd1243dSDimitry Andric   // name, line number, kind, offset.
93*bdd1243dSDimitry Andric   std::tuple<StringRef, uint32_t, std::string, LVOffset> Left(
94*bdd1243dSDimitry Andric       LHS->getName(), LHS->getLineNumber(), LHS->kind(), LHS->getOffset());
95*bdd1243dSDimitry Andric   std::tuple<StringRef, uint32_t, std::string, LVOffset> Right(
96*bdd1243dSDimitry Andric       RHS->getName(), RHS->getLineNumber(), RHS->kind(), RHS->getOffset());
97*bdd1243dSDimitry Andric   return Left < Right;
98*bdd1243dSDimitry Andric }
99*bdd1243dSDimitry Andric 
getSortFunction()100*bdd1243dSDimitry Andric LVSortFunction llvm::logicalview::getSortFunction() {
101*bdd1243dSDimitry Andric   using LVSortInfo = std::map<LVSortMode, LVSortFunction>;
102*bdd1243dSDimitry Andric   static LVSortInfo SortInfo = {
103*bdd1243dSDimitry Andric       {LVSortMode::None, nullptr},         {LVSortMode::Kind, sortByKind},
104*bdd1243dSDimitry Andric       {LVSortMode::Line, sortByLine},      {LVSortMode::Name, sortByName},
105*bdd1243dSDimitry Andric       {LVSortMode::Offset, compareOffset},
106*bdd1243dSDimitry Andric   };
107*bdd1243dSDimitry Andric 
108*bdd1243dSDimitry Andric   LVSortFunction SortFunction = nullptr;
109*bdd1243dSDimitry Andric   LVSortInfo::iterator Iter = SortInfo.find(options().getSortMode());
110*bdd1243dSDimitry Andric   if (Iter != SortInfo.end())
111*bdd1243dSDimitry Andric     SortFunction = Iter->second;
112*bdd1243dSDimitry Andric   return SortFunction;
113*bdd1243dSDimitry Andric }
114