1 //===-- LVSupport.cpp -----------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This implements the supporting functions.
11 //===----------------------------------------------------------------------===//
13 #include "llvm/DebugInfo/LogicalView/Core/LVSupport.h"
14 #include "llvm/Support/FormatAdapters.h"
15 #include "llvm/Support/FormatVariadic.h"
19 using namespace llvm::logicalview
;
21 #define DEBUG_TYPE "Support"
24 // Unique string pool instance used by all logical readers.
25 LVStringPool StringPool
;
27 LVStringPool
&llvm::logicalview::getStringPool() { return StringPool
; }
29 // Perform the following transformations to the given 'Path':
30 // - all characters to lowercase.
31 // - '\\' into '/' (Platform independent).
33 std::string
llvm::logicalview::transformPath(StringRef Path
) {
34 std::string
Name(Path
);
35 std::transform(Name
.begin(), Name
.end(), Name
.begin(), tolower
);
36 std::replace(Name
.begin(), Name
.end(), '\\', '/');
38 // Remove all duplicate slashes.
40 while ((Pos
= Name
.find("//", Pos
)) != std::string::npos
)
46 // Convert the given 'Path' to lowercase and change any matching character
47 // from 'CharSet' into '_'.
48 // The characters in 'CharSet' are:
49 // '/', '\', '<', '>', '.', ':', '%', '*', '?', '|', '"', ' '.
50 std::string
llvm::logicalview::flattenedFilePath(StringRef Path
) {
51 std::string
Name(Path
);
52 std::transform(Name
.begin(), Name
.end(), Name
.begin(), tolower
);
54 const char *CharSet
= "/\\<>.:%*?|\" ";
55 char *Input
= Name
.data();
56 while (Input
&& *Input
) {
57 Input
= strpbrk(Input
, CharSet
);
64 using LexicalEntry
= std::pair
<size_t, size_t>;
65 using LexicalIndexes
= SmallVector
<LexicalEntry
, 10>;
67 static LexicalIndexes
getAllLexicalIndexes(StringRef Name
) {
71 size_t AngleCount
= 0;
75 LexicalIndexes Indexes
;
78 auto PrintLexicalEntry
= [&]() {
79 LexicalEntry Entry
= Indexes
.back();
80 llvm::dbgs() << formatv(
81 "'{0}:{1}', '{2}'\n", Entry
.first
, Entry
.second
,
82 Name
.substr(Entry
.first
, Entry
.second
- Entry
.first
+ 1));
86 size_t Length
= Name
.size();
87 for (size_t Index
= 0; Index
< Length
; ++Index
) {
89 llvm::dbgs() << formatv("Index: '{0}', Char: '{1}'\n", Index
,
92 switch (Name
[Index
]) {
103 if (ColonSeen
== 2) {
105 Indexes
.push_back(LexicalEntry(Current
, Index
- 2));
107 LLVM_DEBUG({ PrintLexicalEntry(); });
114 // Store last component.
115 Indexes
.push_back(LexicalEntry(Current
, Length
- 1));
116 LLVM_DEBUG({ PrintLexicalEntry(); });
120 LVLexicalComponent
llvm::logicalview::getInnerComponent(StringRef Name
) {
124 LexicalIndexes Indexes
= getAllLexicalIndexes(Name
);
125 if (Indexes
.size() == 1)
126 return std::make_tuple(StringRef(), Name
);
128 LexicalEntry BeginEntry
= Indexes
.front();
129 LexicalEntry EndEntry
= Indexes
[Indexes
.size() - 2];
131 Name
.substr(BeginEntry
.first
, EndEntry
.second
- BeginEntry
.first
+ 1);
133 LexicalEntry LastEntry
= Indexes
.back();
135 Name
.substr(LastEntry
.first
, LastEntry
.second
- LastEntry
.first
+ 1);
137 return std::make_tuple(Outer
, Inner
);
140 LVStringRefs
llvm::logicalview::getAllLexicalComponents(StringRef Name
) {
144 LexicalIndexes Indexes
= getAllLexicalIndexes(Name
);
145 LVStringRefs Components
;
146 for (const LexicalEntry
&Entry
: Indexes
)
147 Components
.push_back(
148 Name
.substr(Entry
.first
, Entry
.second
- Entry
.first
+ 1));
153 std::string
llvm::logicalview::getScopedName(const LVStringRefs
&Components
,
154 StringRef BaseName
) {
155 if (Components
.empty())
157 std::string
Name(BaseName
);
158 raw_string_ostream
Stream(Name
);
161 Stream
<< Components
[0];
162 for (LVStringRefs::size_type Index
= 1; Index
< Components
.size(); ++Index
)
163 Stream
<< "::" << Components
[Index
];