reland: [Demangle] make llvm::demangle take std::string_view rather than const std::string&

As suggested by @erichkeane in
https://reviews.llvm.org/D141451#inline-1429549

There's potential for a lot more cleanups around these APIs. This is
just a start.

Callers need to be more careful about sub-expressions producing strings
that don't outlast the expression using `llvm::demangle`. Add a
release note.

Differential Revision: https://reviews.llvm.org/D149104
This commit is contained in:
Nick Desaulniers 2023-06-05 14:59:46 -07:00
parent 78de45fd4a
commit 8abbc17ff3
16 changed files with 45 additions and 52 deletions

View File

@ -635,9 +635,8 @@ BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) {
return false;
Diags.Report(*Loc, diag::warn_fe_frame_larger_than)
<< D.getStackSize()
<< D.getStackLimit()
<< llvm::demangle(D.getFunction().getName().str());
<< D.getStackSize() << D.getStackLimit()
<< llvm::demangle(D.getFunction().getName());
return true;
}
@ -651,7 +650,7 @@ bool BackendConsumer::ResourceLimitDiagHandler(
Diags.Report(*Loc, DiagID)
<< D.getResourceName() << D.getResourceSize() << D.getResourceLimit()
<< llvm::demangle(D.getFunction().getName().str());
<< llvm::demangle(D.getFunction().getName());
return true;
}
@ -856,7 +855,7 @@ void BackendConsumer::DontCallDiagHandler(const DiagnosticInfoDontCall &D) {
Diags.Report(LocCookie, D.getSeverity() == DiagnosticSeverity::DS_Error
? diag::err_fe_backend_error_attr
: diag::warn_fe_backend_warning_attr)
<< llvm::demangle(D.getFunctionName().str()) << D.getNote();
<< llvm::demangle(D.getFunctionName()) << D.getNote();
}
void BackendConsumer::MisExpectDiagHandler(

View File

@ -38,9 +38,9 @@ static std::string maybeDemangleSymbol(const COFFLinkerContext &ctx,
StringRef demangleInput = prefixless;
if (ctx.config.machine == I386)
demangleInput.consume_front("_");
std::string demangled = demangle(demangleInput.str());
std::string demangled = demangle(demangleInput);
if (demangled != demangleInput)
return prefix + demangle(demangleInput.str());
return prefix + demangled;
return (prefix + prefixless).str();
}
return std::string(symName);

View File

@ -145,13 +145,16 @@ StringMap<SmallVector<Symbol *, 0>> &SymbolTable::getDemangledSyms() {
if (canBeVersioned(*sym)) {
StringRef name = sym->getName();
size_t pos = name.find('@');
std::string substr;
if (pos == std::string::npos)
demangled = demangle(name.str());
else if (pos + 1 == name.size() || name[pos + 1] == '@')
demangled = demangle(name.substr(0, pos).str());
else
demangled =
(demangle(name.substr(0, pos).str()) + name.substr(pos)).str();
demangled = demangle(name);
else if (pos + 1 == name.size() || name[pos + 1] == '@') {
substr = name.substr(0, pos);
demangled = demangle(substr);
} else {
substr = name.substr(0, pos);
demangled = (demangle(substr) + name.substr(pos)).str();
}
(*demangledSyms)[demangled].push_back(sym);
}
}

View File

@ -45,9 +45,7 @@ LLVM_ATTRIBUTE_UNUSED static inline void assertSymbols() {
// Returns a symbol for an error message.
static std::string maybeDemangleSymbol(StringRef symName) {
if (elf::config->demangle)
return demangle(symName.str());
return symName.str();
return elf::config->demangle ? demangle(symName.str()) : symName.str();
}
std::string lld::toString(const elf::Symbol &sym) {

View File

@ -32,7 +32,7 @@ static_assert(sizeof(SymbolUnion) == sizeof(Defined),
static std::string maybeDemangleSymbol(StringRef symName) {
if (config->demangle) {
symName.consume_front("_");
return demangle(symName.str());
return demangle(symName);
}
return symName.str();
}

View File

@ -35,7 +35,7 @@ std::string maybeDemangleSymbol(StringRef name) {
if (name == "__main_argc_argv")
return "main";
if (wasm::config->demangle)
return demangle(name.str());
return demangle(name);
return name.str();
}

View File

@ -344,6 +344,11 @@ Changes to Sanitizers
Other Changes
-------------
* ``llvm::demangle`` now takes a ``std::string_view`` rather than a
``const std::string&``. Be careful passing temporaries into
``llvm::demangle`` that don't outlive the expression using
``llvm::demangle``.
External Open Source Projects Using LLVM 15
===========================================

View File

@ -65,7 +65,7 @@ char *dlangDemangle(std::string_view MangledName);
/// \param MangledName - reference to string to demangle.
/// \returns - the demangled string, or a copy of the input string if no
/// demangling occurred.
std::string demangle(const std::string &MangledName);
std::string demangle(std::string_view MangledName);
bool nonMicrosoftDemangle(std::string_view MangledName, std::string &Result);

View File

@ -1605,7 +1605,7 @@ Error LVSymbolVisitor::visitKnownRecord(CVSymbol &Record, ProcSym &Proc) {
// We don't have a way to see if the symbol is compiler generated. Use
// the linkage name, to detect `scalar deleting destructor' functions.
std::string DemangledSymbol = demangle(std::string(LinkageName));
std::string DemangledSymbol = demangle(LinkageName);
if (DemangledSymbol.find("scalar deleting dtor") != std::string::npos) {
Function->setIsArtificial();
} else {

View File

@ -13,27 +13,27 @@
#include "llvm/Demangle/Demangle.h"
#include "llvm/Demangle/StringViewExtras.h"
#include <cstdlib>
#include <cstring>
#include <string_view>
using llvm::itanium_demangle::starts_with;
std::string llvm::demangle(const std::string &MangledName) {
std::string llvm::demangle(std::string_view MangledName) {
std::string Result;
const char *S = MangledName.c_str();
if (nonMicrosoftDemangle(MangledName, Result))
return Result;
if (S[0] == '_' && nonMicrosoftDemangle(MangledName.substr(1), Result))
if (starts_with(MangledName, '_') &&
nonMicrosoftDemangle(MangledName.substr(1), Result))
return Result;
if (char *Demangled = microsoftDemangle(S, nullptr, nullptr)) {
if (char *Demangled = microsoftDemangle(MangledName, nullptr, nullptr)) {
Result = Demangled;
std::free(Demangled);
return Result;
} else {
Result = MangledName;
}
return MangledName;
return Result;
}
static bool isItaniumEncoding(std::string_view S) {

View File

@ -441,8 +441,7 @@ void llvm::diagnoseDontCall(const CallInst &CI) {
}
void DiagnosticInfoDontCall::print(DiagnosticPrinter &DP) const {
DP << "call to " << demangle(getFunctionName().str())
<< " marked \"dontcall-";
DP << "call to " << demangle(getFunctionName()) << " marked \"dontcall-";
if (getSeverity() == DiagnosticSeverity::DS_Error)
DP << "error\"";
else

View File

@ -108,10 +108,7 @@ static Error getRelocationValueString(const ELFObjectFile<ELFT> *Obj,
Expected<StringRef> SymName = SI->getName();
if (!SymName)
return SymName.takeError();
if (Demangle)
Fmt << demangle(std::string(*SymName));
else
Fmt << *SymName;
Fmt << (Demangle ? demangle(*SymName) : *SymName);
}
} else {
Fmt << "*ABS*";

View File

@ -32,10 +32,8 @@ Error objdump::getXCOFFRelocationValueString(const XCOFFObjectFile &Obj,
if (!SymNameOrErr)
return SymNameOrErr.takeError();
std::string SymName = (*SymNameOrErr).str();
if (Demangle)
SymName = demangle(SymName);
std::string SymName =
Demangle ? demangle(*SymNameOrErr) : SymNameOrErr->str();
if (SymbolDescription)
SymName = getXCOFFSymbolDescription(createSymbolInfo(Obj, *SymI), SymName);

View File

@ -1545,7 +1545,7 @@ static void disassembleObject(const Target *TheTarget, ObjectFile &Obj,
if (Demangle) {
// Fetch the demangled names and store them locally.
for (const SymbolInfoTy &Symbol : SymbolsHere)
DemangledSymNamesHere.push_back(demangle(Symbol.Name.str()));
DemangledSymNamesHere.push_back(demangle(Symbol.Name));
// Now we've finished modifying that vector, it's safe to make
// a vector of StringRefs pointing into it.
SymNamesHere.insert(SymNamesHere.begin(), DemangledSymNamesHere.begin(),
@ -1906,9 +1906,8 @@ static void disassembleObject(const Target *TheTarget, ObjectFile &Obj,
if (TargetSym != nullptr) {
uint64_t TargetAddress = TargetSym->Addr;
uint64_t Disp = Target - TargetAddress;
std::string TargetName = TargetSym->Name.str();
if (Demangle)
TargetName = demangle(TargetName);
std::string TargetName = Demangle ? demangle(TargetSym->Name)
: TargetSym->Name.str();
*TargetOS << " <";
if (!Disp) {
@ -2508,10 +2507,8 @@ void objdump::printSymbol(const ObjectFile &O, const SymbolRef &Symbol,
if (NameOrErr) {
outs() << " (csect:";
std::string SymName(NameOrErr.get());
if (Demangle)
SymName = demangle(SymName);
std::string SymName =
Demangle ? demangle(*NameOrErr) : NameOrErr->str();
if (SymbolDescription)
SymName = getXCOFFSymbolDescription(createSymbolInfo(O, *SymRef),
@ -2565,10 +2562,7 @@ void objdump::printSymbol(const ObjectFile &O, const SymbolRef &Symbol,
outs() << " .hidden";
}
std::string SymName(Name);
if (Demangle)
SymName = demangle(SymName);
std::string SymName = Demangle ? demangle(Name) : Name.str();
if (O.isXCOFF() && SymbolDescription)
SymName = getXCOFFSymbolDescription(createSymbolInfo(O, Symbol), SymName);

View File

@ -908,7 +908,7 @@ ELFDumper<ELFT>::getShndxTable(const Elf_Shdr *Symtab) const {
}
static std::string maybeDemangle(StringRef Name) {
return opts::Demangle ? demangle(std::string(Name)) : Name.str();
return opts::Demangle ? demangle(Name) : Name.str();
}
template <typename ELFT>

View File

@ -107,7 +107,7 @@ static std::string getPrintableName(StringRef Name) {
std::string OutputName = "'";
OutputName += Name;
OutputName += "'";
std::string DemangledName(demangle(Name.str()));
std::string DemangledName(demangle(Name));
if (Name != DemangledName) {
OutputName += " aka ";
OutputName += DemangledName;