xref: /llvm-project/llvm/lib/DebugInfo/LogicalView/Core/LVSupport.cpp (revision 0060c54e0da6d1429875da2d30895faa7562b706)
1e28b9357SCarlos Alberto Enciso //===-- LVSupport.cpp -----------------------------------------------------===//
2e28b9357SCarlos Alberto Enciso //
3e28b9357SCarlos Alberto Enciso // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e28b9357SCarlos Alberto Enciso // See https://llvm.org/LICENSE.txt for license information.
5e28b9357SCarlos Alberto Enciso // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e28b9357SCarlos Alberto Enciso //
7e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
8e28b9357SCarlos Alberto Enciso //
9e28b9357SCarlos Alberto Enciso // This implements the supporting functions.
10e28b9357SCarlos Alberto Enciso //
11e28b9357SCarlos Alberto Enciso //===----------------------------------------------------------------------===//
12e28b9357SCarlos Alberto Enciso 
13e28b9357SCarlos Alberto Enciso #include "llvm/DebugInfo/LogicalView/Core/LVSupport.h"
14e28b9357SCarlos Alberto Enciso #include "llvm/Support/FormatVariadic.h"
15e28b9357SCarlos Alberto Enciso 
16e28b9357SCarlos Alberto Enciso using namespace llvm;
17e28b9357SCarlos Alberto Enciso using namespace llvm::logicalview;
18e28b9357SCarlos Alberto Enciso 
19e28b9357SCarlos Alberto Enciso #define DEBUG_TYPE "Support"
20e28b9357SCarlos Alberto Enciso 
2192716a42SCarlos Alberto Enciso namespace {
2292716a42SCarlos Alberto Enciso // Unique string pool instance used by all logical readers.
2392716a42SCarlos Alberto Enciso LVStringPool StringPool;
2492716a42SCarlos Alberto Enciso } // namespace
2592716a42SCarlos Alberto Enciso LVStringPool &llvm::logicalview::getStringPool() { return StringPool; }
2692716a42SCarlos Alberto Enciso 
27e28b9357SCarlos Alberto Enciso // Perform the following transformations to the given 'Path':
28e28b9357SCarlos Alberto Enciso // - all characters to lowercase.
29e28b9357SCarlos Alberto Enciso // - '\\' into '/' (Platform independent).
30e28b9357SCarlos Alberto Enciso // - '//' into '/'
31e28b9357SCarlos Alberto Enciso std::string llvm::logicalview::transformPath(StringRef Path) {
32e28b9357SCarlos Alberto Enciso   std::string Name(Path);
33e28b9357SCarlos Alberto Enciso   std::transform(Name.begin(), Name.end(), Name.begin(), tolower);
34e28b9357SCarlos Alberto Enciso   std::replace(Name.begin(), Name.end(), '\\', '/');
35e28b9357SCarlos Alberto Enciso 
36e28b9357SCarlos Alberto Enciso   // Remove all duplicate slashes.
37e28b9357SCarlos Alberto Enciso   size_t Pos = 0;
38e28b9357SCarlos Alberto Enciso   while ((Pos = Name.find("//", Pos)) != std::string::npos)
39e28b9357SCarlos Alberto Enciso     Name.erase(Pos, 1);
40e28b9357SCarlos Alberto Enciso 
41e28b9357SCarlos Alberto Enciso   return Name;
42e28b9357SCarlos Alberto Enciso }
43e28b9357SCarlos Alberto Enciso 
44e28b9357SCarlos Alberto Enciso // Convert the given 'Path' to lowercase and change any matching character
45e28b9357SCarlos Alberto Enciso // from 'CharSet' into '_'.
46e28b9357SCarlos Alberto Enciso // The characters in 'CharSet' are:
47e28b9357SCarlos Alberto Enciso //   '/', '\', '<', '>', '.', ':', '%', '*', '?', '|', '"', ' '.
48e28b9357SCarlos Alberto Enciso std::string llvm::logicalview::flattenedFilePath(StringRef Path) {
49e28b9357SCarlos Alberto Enciso   std::string Name(Path);
50e28b9357SCarlos Alberto Enciso   std::transform(Name.begin(), Name.end(), Name.begin(), tolower);
51e28b9357SCarlos Alberto Enciso 
52e28b9357SCarlos Alberto Enciso   const char *CharSet = "/\\<>.:%*?|\" ";
53e28b9357SCarlos Alberto Enciso   char *Input = Name.data();
54e28b9357SCarlos Alberto Enciso   while (Input && *Input) {
55e28b9357SCarlos Alberto Enciso     Input = strpbrk(Input, CharSet);
56e28b9357SCarlos Alberto Enciso     if (Input)
57e28b9357SCarlos Alberto Enciso       *Input++ = '_';
58e28b9357SCarlos Alberto Enciso   };
59e28b9357SCarlos Alberto Enciso   return Name;
60e28b9357SCarlos Alberto Enciso }
61*e7950fceSCarlos Alberto Enciso 
62*e7950fceSCarlos Alberto Enciso using LexicalEntry = std::pair<size_t, size_t>;
63*e7950fceSCarlos Alberto Enciso using LexicalIndexes = SmallVector<LexicalEntry, 10>;
64*e7950fceSCarlos Alberto Enciso 
65*e7950fceSCarlos Alberto Enciso static LexicalIndexes getAllLexicalIndexes(StringRef Name) {
66*e7950fceSCarlos Alberto Enciso   if (Name.empty())
67*e7950fceSCarlos Alberto Enciso     return {};
68*e7950fceSCarlos Alberto Enciso 
69*e7950fceSCarlos Alberto Enciso   size_t AngleCount = 0;
70*e7950fceSCarlos Alberto Enciso   size_t ColonSeen = 0;
71*e7950fceSCarlos Alberto Enciso   size_t Current = 0;
72*e7950fceSCarlos Alberto Enciso 
73*e7950fceSCarlos Alberto Enciso   LexicalIndexes Indexes;
74*e7950fceSCarlos Alberto Enciso 
75*e7950fceSCarlos Alberto Enciso #ifndef NDEBUG
76*e7950fceSCarlos Alberto Enciso   auto PrintLexicalEntry = [&]() {
77*e7950fceSCarlos Alberto Enciso     LexicalEntry Entry = Indexes.back();
78*e7950fceSCarlos Alberto Enciso     llvm::dbgs() << formatv(
79*e7950fceSCarlos Alberto Enciso         "'{0}:{1}', '{2}'\n", Entry.first, Entry.second,
80*e7950fceSCarlos Alberto Enciso         Name.substr(Entry.first, Entry.second - Entry.first + 1));
81*e7950fceSCarlos Alberto Enciso   };
82*e7950fceSCarlos Alberto Enciso #endif
83*e7950fceSCarlos Alberto Enciso 
84*e7950fceSCarlos Alberto Enciso   size_t Length = Name.size();
85*e7950fceSCarlos Alberto Enciso   for (size_t Index = 0; Index < Length; ++Index) {
86*e7950fceSCarlos Alberto Enciso     LLVM_DEBUG({
87*e7950fceSCarlos Alberto Enciso       llvm::dbgs() << formatv("Index: '{0}', Char: '{1}'\n", Index,
88*e7950fceSCarlos Alberto Enciso                               Name[Index]);
89*e7950fceSCarlos Alberto Enciso     });
90*e7950fceSCarlos Alberto Enciso     switch (Name[Index]) {
91*e7950fceSCarlos Alberto Enciso     case '<':
92*e7950fceSCarlos Alberto Enciso       ++AngleCount;
93*e7950fceSCarlos Alberto Enciso       break;
94*e7950fceSCarlos Alberto Enciso     case '>':
95*e7950fceSCarlos Alberto Enciso       --AngleCount;
96*e7950fceSCarlos Alberto Enciso       break;
97*e7950fceSCarlos Alberto Enciso     case ':':
98*e7950fceSCarlos Alberto Enciso       ++ColonSeen;
99*e7950fceSCarlos Alberto Enciso       break;
100*e7950fceSCarlos Alberto Enciso     }
101*e7950fceSCarlos Alberto Enciso     if (ColonSeen == 2) {
102*e7950fceSCarlos Alberto Enciso       if (!AngleCount) {
103*e7950fceSCarlos Alberto Enciso         Indexes.push_back(LexicalEntry(Current, Index - 2));
104*e7950fceSCarlos Alberto Enciso         Current = Index + 1;
105*e7950fceSCarlos Alberto Enciso         LLVM_DEBUG({ PrintLexicalEntry(); });
106*e7950fceSCarlos Alberto Enciso       }
107*e7950fceSCarlos Alberto Enciso       ColonSeen = 0;
108*e7950fceSCarlos Alberto Enciso       continue;
109*e7950fceSCarlos Alberto Enciso     }
110*e7950fceSCarlos Alberto Enciso   }
111*e7950fceSCarlos Alberto Enciso 
112*e7950fceSCarlos Alberto Enciso   // Store last component.
113*e7950fceSCarlos Alberto Enciso   Indexes.push_back(LexicalEntry(Current, Length - 1));
114*e7950fceSCarlos Alberto Enciso   LLVM_DEBUG({ PrintLexicalEntry(); });
115*e7950fceSCarlos Alberto Enciso   return Indexes;
116*e7950fceSCarlos Alberto Enciso }
117*e7950fceSCarlos Alberto Enciso 
118*e7950fceSCarlos Alberto Enciso LVLexicalComponent llvm::logicalview::getInnerComponent(StringRef Name) {
119*e7950fceSCarlos Alberto Enciso   if (Name.empty())
120*e7950fceSCarlos Alberto Enciso     return {};
121*e7950fceSCarlos Alberto Enciso 
122*e7950fceSCarlos Alberto Enciso   LexicalIndexes Indexes = getAllLexicalIndexes(Name);
123*e7950fceSCarlos Alberto Enciso   if (Indexes.size() == 1)
124*e7950fceSCarlos Alberto Enciso     return std::make_tuple(StringRef(), Name);
125*e7950fceSCarlos Alberto Enciso 
126*e7950fceSCarlos Alberto Enciso   LexicalEntry BeginEntry = Indexes.front();
127*e7950fceSCarlos Alberto Enciso   LexicalEntry EndEntry = Indexes[Indexes.size() - 2];
128*e7950fceSCarlos Alberto Enciso   StringRef Outer =
129*e7950fceSCarlos Alberto Enciso       Name.substr(BeginEntry.first, EndEntry.second - BeginEntry.first + 1);
130*e7950fceSCarlos Alberto Enciso 
131*e7950fceSCarlos Alberto Enciso   LexicalEntry LastEntry = Indexes.back();
132*e7950fceSCarlos Alberto Enciso   StringRef Inner =
133*e7950fceSCarlos Alberto Enciso       Name.substr(LastEntry.first, LastEntry.second - LastEntry.first + 1);
134*e7950fceSCarlos Alberto Enciso 
135*e7950fceSCarlos Alberto Enciso   return std::make_tuple(Outer, Inner);
136*e7950fceSCarlos Alberto Enciso }
137*e7950fceSCarlos Alberto Enciso 
138*e7950fceSCarlos Alberto Enciso LVStringRefs llvm::logicalview::getAllLexicalComponents(StringRef Name) {
139*e7950fceSCarlos Alberto Enciso   if (Name.empty())
140*e7950fceSCarlos Alberto Enciso     return {};
141*e7950fceSCarlos Alberto Enciso 
142*e7950fceSCarlos Alberto Enciso   LexicalIndexes Indexes = getAllLexicalIndexes(Name);
143*e7950fceSCarlos Alberto Enciso   LVStringRefs Components;
144*e7950fceSCarlos Alberto Enciso   for (const LexicalEntry &Entry : Indexes)
145*e7950fceSCarlos Alberto Enciso     Components.push_back(
146*e7950fceSCarlos Alberto Enciso         Name.substr(Entry.first, Entry.second - Entry.first + 1));
147*e7950fceSCarlos Alberto Enciso 
148*e7950fceSCarlos Alberto Enciso   return Components;
149*e7950fceSCarlos Alberto Enciso }
150*e7950fceSCarlos Alberto Enciso 
151*e7950fceSCarlos Alberto Enciso std::string llvm::logicalview::getScopedName(const LVStringRefs &Components,
152*e7950fceSCarlos Alberto Enciso                                              StringRef BaseName) {
153*e7950fceSCarlos Alberto Enciso   if (Components.empty())
154*e7950fceSCarlos Alberto Enciso     return {};
155*e7950fceSCarlos Alberto Enciso   std::string Name(BaseName);
156*e7950fceSCarlos Alberto Enciso   raw_string_ostream Stream(Name);
157*e7950fceSCarlos Alberto Enciso   if (BaseName.size())
158*e7950fceSCarlos Alberto Enciso     Stream << "::";
159*e7950fceSCarlos Alberto Enciso   Stream << Components[0];
160*e7950fceSCarlos Alberto Enciso   for (LVStringRefs::size_type Index = 1; Index < Components.size(); ++Index)
161*e7950fceSCarlos Alberto Enciso     Stream << "::" << Components[Index];
162*e7950fceSCarlos Alberto Enciso   return Name;
163*e7950fceSCarlos Alberto Enciso }
164