mirror of
https://github.com/intel/llvm.git
synced 2026-01-21 12:19:23 +08:00
<rdar://problem/10998370>
Improved the error message when we can find a function in the current program by printing the demangled name. Also added the ability to create lldb_private::Mangled instances with a ConstString when we already have a ConstString for a mangled or demangled name. Also added the ability to call SetValue with a ConstString and also without a boolean to indicate if the string is mangled where we will now auto-detect if the string is mangled. llvm-svn: 160450
This commit is contained in:
@@ -299,6 +299,46 @@ public:
|
||||
explicit
|
||||
Mangled (const char *name, bool is_mangled);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Construct with name.
|
||||
///
|
||||
/// Constructor with an optional string and a boolean indicating if it is
|
||||
/// the mangled version.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// The already const name to copy into this object.
|
||||
///
|
||||
/// @param[in] is_mangled
|
||||
/// If \b true then \a name is a mangled name, if \b false then
|
||||
/// \a name is demangled.
|
||||
//----------------------------------------------------------------------
|
||||
explicit
|
||||
Mangled (const ConstString &name, bool is_mangled);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Construct with name.
|
||||
///
|
||||
/// Constructor with an optional string and auto-detect if \a name is
|
||||
/// mangled or not.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// The already const name to copy into this object.
|
||||
//----------------------------------------------------------------------
|
||||
explicit
|
||||
Mangled (const char *name);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Construct with name.
|
||||
///
|
||||
/// Constructor with an optional string and auto-detect if \a name is
|
||||
/// mangled or not.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// The already const name to copy into this object.
|
||||
//----------------------------------------------------------------------
|
||||
explicit
|
||||
Mangled (const ConstString &name);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Destructor
|
||||
///
|
||||
@@ -513,6 +553,34 @@ public:
|
||||
void
|
||||
SetValue (const char *name, bool is_mangled);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Set the string value in this object.
|
||||
///
|
||||
/// If \a is_mangled is \b true, then the mangled named is set to \a
|
||||
/// name, else the demangled name is set to \a name.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// The already const version of the name for this object.
|
||||
///
|
||||
/// @param[in] is_mangled
|
||||
/// If \b true then \a name is a mangled name, if \b false then
|
||||
/// \a name is demangled.
|
||||
//----------------------------------------------------------------------
|
||||
void
|
||||
SetValue (const ConstString &name, bool is_mangled);
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/// Set the string value in this object.
|
||||
///
|
||||
/// This version auto detects if the string is mangled by inspecting the
|
||||
/// string value and looking for common mangling prefixes.
|
||||
///
|
||||
/// @param[in] name
|
||||
/// The already const version of the name for this object.
|
||||
//----------------------------------------------------------------------
|
||||
void
|
||||
SetValue (const ConstString &name);
|
||||
|
||||
private:
|
||||
//----------------------------------------------------------------------
|
||||
/// Mangled member variables.
|
||||
|
||||
@@ -21,6 +21,14 @@
|
||||
|
||||
using namespace lldb_private;
|
||||
|
||||
static inline bool
|
||||
cstring_is_mangled (const char *s)
|
||||
{
|
||||
if (s)
|
||||
return s[0] == '_' && s[1] == 'Z';
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma mark Mangled
|
||||
//----------------------------------------------------------------------
|
||||
// Default constructor
|
||||
@@ -45,6 +53,38 @@ Mangled::Mangled (const char *s, bool mangled) :
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Constructor with an optional string and a boolean indicating if it is
|
||||
// the mangled version.
|
||||
//----------------------------------------------------------------------
|
||||
Mangled::Mangled (const ConstString &s, bool mangled) :
|
||||
m_mangled(),
|
||||
m_demangled()
|
||||
{
|
||||
if (s)
|
||||
SetValue(s, mangled);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Constructor with an optional string where we try and auto detect if
|
||||
// the name is mangled or not by inspecting the string value
|
||||
//----------------------------------------------------------------------
|
||||
Mangled::Mangled (const char *s) :
|
||||
m_mangled(),
|
||||
m_demangled()
|
||||
{
|
||||
if (s && s[0])
|
||||
SetValue(ConstString(s));
|
||||
}
|
||||
|
||||
Mangled::Mangled (const ConstString &s) :
|
||||
m_mangled(),
|
||||
m_demangled()
|
||||
{
|
||||
if (s)
|
||||
SetValue(s);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Destructor
|
||||
//----------------------------------------------------------------------
|
||||
@@ -129,6 +169,53 @@ Mangled::SetValue (const char *s, bool mangled)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Mangled::SetValue (const ConstString &s, bool mangled)
|
||||
{
|
||||
if (s)
|
||||
{
|
||||
if (mangled)
|
||||
{
|
||||
m_demangled.Clear();
|
||||
m_mangled = s;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demangled = s;
|
||||
m_mangled.Clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demangled.Clear();
|
||||
m_mangled.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Mangled::SetValue (const ConstString &name)
|
||||
{
|
||||
if (name)
|
||||
{
|
||||
if (cstring_is_mangled(name.GetCString()))
|
||||
{
|
||||
m_demangled.Clear();
|
||||
m_mangled = name;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demangled = name;
|
||||
m_mangled.Clear();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_demangled.Clear();
|
||||
m_mangled.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// Generate the demangled name on demand using this accessor. Code in
|
||||
// this class will need to use this accessor if it wishes to decode
|
||||
@@ -148,17 +235,15 @@ Mangled::GetDemangledName () const
|
||||
"Mangled::GetDemangledName (m_mangled = %s)",
|
||||
m_mangled.GetCString());
|
||||
|
||||
// We already know mangled is valid from the above check,
|
||||
// lets just make sure it isn't empty...
|
||||
const char * mangled = m_mangled.AsCString();
|
||||
// Don't bother running anything that doesn't start with _Z through the demangler
|
||||
if (mangled[0] == '_' && mangled[1] == 'Z')
|
||||
// Don't bother running anything that isn't mangled
|
||||
const char *mangled_cstr = m_mangled.GetCString();
|
||||
if (cstring_is_mangled(mangled_cstr))
|
||||
{
|
||||
if (!m_mangled.GetMangledCounterpart(m_demangled))
|
||||
{
|
||||
// We didn't already mangle this name, demangle it and if all goes well
|
||||
// add it to our map.
|
||||
char *demangled_name = abi::__cxa_demangle (mangled, NULL, NULL, NULL);
|
||||
char *demangled_name = abi::__cxa_demangle (mangled_cstr, NULL, NULL, NULL);
|
||||
|
||||
if (demangled_name)
|
||||
{
|
||||
|
||||
@@ -229,7 +229,7 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun,
|
||||
{
|
||||
if (!m_decl_map->GetFunctionInfo (fun_decl, fun_addr))
|
||||
{
|
||||
lldb_private::ConstString alternate_mangling_const_str;
|
||||
lldb_private::ConstString altnernate_name;
|
||||
bool found_it = m_decl_map->GetFunctionAddress (name, fun_addr);
|
||||
if (!found_it)
|
||||
{
|
||||
@@ -240,27 +240,35 @@ IRForTarget::GetFunctionAddress (llvm::Function *fun,
|
||||
{
|
||||
std::string alternate_mangling("_ZNKSs");
|
||||
alternate_mangling.append (name_cstr + strlen("_ZNKSbIcE"));
|
||||
alternate_mangling_const_str.SetCString(alternate_mangling.c_str());
|
||||
found_it = m_decl_map->GetFunctionAddress (alternate_mangling_const_str, fun_addr);
|
||||
altnernate_name.SetCString(alternate_mangling.c_str());
|
||||
found_it = m_decl_map->GetFunctionAddress (altnernate_name, fun_addr);
|
||||
}
|
||||
}
|
||||
|
||||
if (!found_it)
|
||||
{
|
||||
lldb_private::Mangled mangled_name(name);
|
||||
lldb_private::Mangled alt_mangled_name(altnernate_name);
|
||||
if (log)
|
||||
{
|
||||
if (alternate_mangling_const_str)
|
||||
log->Printf("Function \"%s\" (alternate name \"%s\") has no address", name.GetCString(), alternate_mangling_const_str.GetCString());
|
||||
if (alt_mangled_name)
|
||||
log->Printf("Function \"%s\" (alternate name \"%s\") has no address",
|
||||
mangled_name.GetName().GetCString(),
|
||||
alt_mangled_name.GetName().GetCString());
|
||||
else
|
||||
log->Printf("Function \"%s\" had no address", name.GetCString());
|
||||
log->Printf("Function \"%s\" had no address",
|
||||
mangled_name.GetName().GetCString());
|
||||
}
|
||||
|
||||
if (m_error_stream)
|
||||
{
|
||||
if (alternate_mangling_const_str)
|
||||
m_error_stream->Printf("error: call to a function '%s' (alternate name '%s') that is not present in the target\n", name.GetCString(), alternate_mangling_const_str.GetCString());
|
||||
if (alt_mangled_name)
|
||||
m_error_stream->Printf("error: call to a function '%s' (alternate name '%s') that is not present in the target\n",
|
||||
mangled_name.GetName().GetCString(),
|
||||
alt_mangled_name.GetName().GetCString());
|
||||
else
|
||||
m_error_stream->Printf("error: call to a function '%s' that is not present in the target\n", name.GetCString());
|
||||
m_error_stream->Printf("error: call to a function '%s' that is not present in the target\n",
|
||||
mangled_name.GetName().GetCString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user