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