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