forked from OSchip/llvm-project
RichManglingContext: Make m_ipd_str_len a local variable and simplify processIPDStrResult + polishing in test and Mangled
llvm-svn: 339440
This commit is contained in:
parent
3b92a17526
commit
d051416491
|
@ -25,10 +25,9 @@ namespace lldb_private {
|
|||
/// providers. See Mangled::DemangleWithRichManglingInfo()
|
||||
class RichManglingContext {
|
||||
public:
|
||||
RichManglingContext()
|
||||
: m_provider(None), m_ipd_buf_size(2048), m_ipd_str_len(0) {
|
||||
RichManglingContext() : m_provider(None), m_ipd_buf_size(2048) {
|
||||
m_ipd_buf = static_cast<char *>(std::malloc(m_ipd_buf_size));
|
||||
m_ipd_buf[m_ipd_str_len] = '\0';
|
||||
m_ipd_buf[0] = '\0';
|
||||
}
|
||||
|
||||
~RichManglingContext() { std::free(m_ipd_buf); }
|
||||
|
@ -65,6 +64,7 @@ public:
|
|||
/// most recent ParseXy() operation. The next ParseXy() call invalidates it.
|
||||
llvm::StringRef GetBufferRef() const {
|
||||
assert(m_provider != None && "Initialize a provider first");
|
||||
assert(m_buffer.data() != nullptr && "Parse first");
|
||||
return m_buffer;
|
||||
}
|
||||
|
||||
|
@ -81,7 +81,6 @@ private:
|
|||
llvm::ItaniumPartialDemangler m_ipd;
|
||||
char *m_ipd_buf;
|
||||
size_t m_ipd_buf_size;
|
||||
size_t m_ipd_str_len;
|
||||
|
||||
/// Members for PluginCxxLanguage
|
||||
/// Cannot forward declare inner class CPlusPlusLanguage::MethodName. The
|
||||
|
|
|
@ -261,9 +261,10 @@ static char *GetMSVCDemangledStr(const char *M) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static char *GetItaniumDemangledStr(const char *M,
|
||||
llvm::ItaniumPartialDemangler &ipd) {
|
||||
static char *GetItaniumDemangledStr(const char *M) {
|
||||
char *demangled_cstr = nullptr;
|
||||
|
||||
llvm::ItaniumPartialDemangler ipd;
|
||||
bool err = ipd.partialDemangle(M);
|
||||
if (!err) {
|
||||
// Default buffer and size (will realloc in case it's too small).
|
||||
|
@ -384,8 +385,7 @@ Mangled::GetDemangledName(lldb::LanguageType language) const {
|
|||
demangled_name = GetMSVCDemangledStr(mangled_name);
|
||||
break;
|
||||
case eManglingSchemeItanium: {
|
||||
llvm::ItaniumPartialDemangler ipd;
|
||||
demangled_name = GetItaniumDemangledStr(mangled_name, ipd);
|
||||
demangled_name = GetItaniumDemangledStr(mangled_name);
|
||||
break;
|
||||
}
|
||||
case eManglingSchemeNone:
|
||||
|
|
|
@ -89,37 +89,32 @@ bool RichManglingContext::IsFunction() const {
|
|||
}
|
||||
|
||||
void RichManglingContext::processIPDStrResult(char *ipd_res, size_t res_size) {
|
||||
// Error case: Clear the buffer.
|
||||
if (LLVM_UNLIKELY(ipd_res == nullptr)) {
|
||||
assert(res_size == m_ipd_buf_size &&
|
||||
"Failed IPD queries keep the original size in the N parameter");
|
||||
|
||||
// Error case: Clear the buffer.
|
||||
m_ipd_str_len = 0;
|
||||
m_ipd_buf[m_ipd_str_len] = '\0';
|
||||
} else {
|
||||
// IPD's res_size includes null terminator.
|
||||
size_t res_len = res_size - 1;
|
||||
assert(ipd_res[res_len] == '\0' &&
|
||||
"IPD returns null-terminated strings and we rely on that");
|
||||
|
||||
if (LLVM_UNLIKELY(ipd_res != m_ipd_buf)) {
|
||||
// Realloc case: Take over the new buffer.
|
||||
m_ipd_buf = ipd_res; // std::realloc freed or reused the old buffer.
|
||||
m_ipd_buf_size =
|
||||
res_size; // Actual buffer may be bigger, but we can't know.
|
||||
m_ipd_str_len = res_len;
|
||||
|
||||
Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE);
|
||||
if (log)
|
||||
log->Printf("ItaniumPartialDemangler Realloc: new buffer size %lu",
|
||||
m_ipd_buf_size);
|
||||
} else {
|
||||
// 99% case: Just remember the string length.
|
||||
m_ipd_str_len = res_len;
|
||||
}
|
||||
m_ipd_buf[0] = '\0';
|
||||
m_buffer = llvm::StringRef(m_ipd_buf, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
m_buffer = llvm::StringRef(m_ipd_buf, m_ipd_str_len);
|
||||
// IPD's res_size includes null terminator.
|
||||
assert(ipd_res[res_size - 1] == '\0' &&
|
||||
"IPD returns null-terminated strings and we rely on that");
|
||||
|
||||
// Update buffer/size on realloc.
|
||||
if (LLVM_UNLIKELY(ipd_res != m_ipd_buf || res_size > m_ipd_buf_size)) {
|
||||
m_ipd_buf = ipd_res; // std::realloc freed or reused the old buffer.
|
||||
m_ipd_buf_size = res_size; // May actually be bigger, but we can't know.
|
||||
|
||||
if (Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_DEMANGLE))
|
||||
LLDB_LOG(log, "ItaniumPartialDemangler Realloc: new buffer size is {0}",
|
||||
m_ipd_buf_size);
|
||||
}
|
||||
|
||||
// 99% case: Just remember the string length.
|
||||
m_buffer = llvm::StringRef(m_ipd_buf, res_size - 1);
|
||||
}
|
||||
|
||||
void RichManglingContext::ParseFunctionBaseName() {
|
||||
|
|
|
@ -79,10 +79,10 @@ TEST(RichManglingContextTest, SwitchProvider) {
|
|||
|
||||
TEST(RichManglingContextTest, IPDRealloc) {
|
||||
// The demangled name should fit into the Itanium default buffer.
|
||||
const char *short_mangled = "_ZN3foo3barEv";
|
||||
const char *ShortMangled = "_ZN3foo3barEv";
|
||||
|
||||
// The demangled name for this will certainly not fit into the default buffer.
|
||||
const char *long_mangled =
|
||||
const char *LongMangled =
|
||||
"_ZNK3shk6detail17CallbackPublisherIZNS_5ThrowERKNSt15__exception_"
|
||||
"ptr13exception_ptrEEUlOT_E_E9SubscribeINS0_9ConcatMapINS0_"
|
||||
"18CallbackSubscriberIZNS_6GetAllIiNS1_IZZNS_9ConcatMapIZNS_6ConcatIJNS1_"
|
||||
|
@ -100,15 +100,18 @@ TEST(RichManglingContextTest, IPDRealloc) {
|
|||
|
||||
RichManglingContext RMC;
|
||||
|
||||
// Demangle the short one and remember the buffer address.
|
||||
EXPECT_TRUE(RMC.FromItaniumName(ConstString(short_mangled)));
|
||||
// Demangle the short one.
|
||||
EXPECT_TRUE(RMC.FromItaniumName(ConstString(ShortMangled)));
|
||||
RMC.ParseFullName();
|
||||
const char *short_demangled_ptr = RMC.GetBufferRef().data();
|
||||
const char *ShortDemangled = RMC.GetBufferRef().data();
|
||||
|
||||
// Demangle the long one and make sure the buffer address changed.
|
||||
EXPECT_TRUE(RMC.FromItaniumName(ConstString(long_mangled)));
|
||||
// Demangle the long one.
|
||||
EXPECT_TRUE(RMC.FromItaniumName(ConstString(LongMangled)));
|
||||
RMC.ParseFullName();
|
||||
const char *long_demangled_ptr = RMC.GetBufferRef().data();
|
||||
const char *LongDemangled = RMC.GetBufferRef().data();
|
||||
|
||||
EXPECT_TRUE(short_demangled_ptr != long_demangled_ptr);
|
||||
// Make sure a new buffer was allocated or the default buffer was extended.
|
||||
bool AllocatedNewBuffer = (ShortDemangled != LongDemangled);
|
||||
bool ExtendedExistingBuffer = (strlen(LongDemangled) > 2048);
|
||||
EXPECT_TRUE(AllocatedNewBuffer || ExtendedExistingBuffer);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue