aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm/tools/lldb/source/Target/CPPLanguageRuntime.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/tools/lldb/source/Target/CPPLanguageRuntime.cpp')
-rw-r--r--contrib/llvm/tools/lldb/source/Target/CPPLanguageRuntime.cpp78
1 files changed, 56 insertions, 22 deletions
diff --git a/contrib/llvm/tools/lldb/source/Target/CPPLanguageRuntime.cpp b/contrib/llvm/tools/lldb/source/Target/CPPLanguageRuntime.cpp
index f5b7f7fc41a6..f048c6706a9b 100644
--- a/contrib/llvm/tools/lldb/source/Target/CPPLanguageRuntime.cpp
+++ b/contrib/llvm/tools/lldb/source/Target/CPPLanguageRuntime.cpp
@@ -11,6 +11,8 @@
#include <string.h>
+#include "llvm/ADT/StringRef.h"
+
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/UniqueCStringMap.h"
#include "lldb/Target/ExecutionContext.h"
@@ -190,30 +192,17 @@ CPPLanguageRuntime::IsCPPMangledName (const char *name)
}
bool
-CPPLanguageRuntime::StripNamespacesFromVariableName (const char *name, const char *&base_name_start, const char *&base_name_end)
+CPPLanguageRuntime::ExtractContextAndIdentifier (const char *name, llvm::StringRef &context, llvm::StringRef &identifier)
{
- if (base_name_end == NULL)
- base_name_end = name + strlen (name);
-
- const char *last_colon = strrchr (name, ':');
-
- if (last_colon == NULL)
- {
- base_name_start = name;
- return true;
- }
-
- // Can't have a C++ name that begins with a single ':', nor contains an internal single ':'
- if (last_colon == name)
- return false;
- else if (last_colon[-1] != ':')
- return false;
- else
+ static RegularExpression g_basename_regex("^(([A-Za-z_][A-Za-z_0-9]*::)*)([A-Za-z_][A-Za-z_0-9]*)$");
+ RegularExpression::Match match(4);
+ if (g_basename_regex.Execute (name, &match))
{
- // FIXME: should check if there is
- base_name_start = last_colon + 1;
+ match.GetMatchAtIndex(name, 1, context);
+ match.GetMatchAtIndex(name, 3, identifier);
return true;
}
+ return false;
}
uint32_t
@@ -282,6 +271,7 @@ ReverseFindMatchingChars (const llvm::StringRef &s,
return false;
}
+
void
CPPLanguageRuntime::MethodName::Parse()
{
@@ -306,6 +296,7 @@ CPPLanguageRuntime::MethodName::Parse()
if (arg_start > 0)
{
size_t basename_end = arg_start;
+ size_t context_start = 0;
size_t context_end = llvm::StringRef::npos;
if (basename_end > 0 && full[basename_end-1] == '>')
{
@@ -314,16 +305,35 @@ CPPLanguageRuntime::MethodName::Parse()
size_t template_start, template_end;
llvm::StringRef lt_gt("<>", 2);
if (ReverseFindMatchingChars (full, lt_gt, template_start, template_end, basename_end))
+ {
context_end = full.rfind(':', template_start);
+ if (context_end == llvm::StringRef::npos)
+ {
+ // Check for templated functions that include return type like:
+ // 'void foo<Int>()'
+ context_end = full.rfind(' ', template_start);
+ if (context_end != llvm::StringRef::npos)
+ {
+ context_start = context_end;
+ }
+ }
+ }
+ else
+ {
+ context_end = full.rfind(':', basename_end);
+ }
}
- if (context_end == llvm::StringRef::npos)
+ else if (context_end == llvm::StringRef::npos)
+ {
context_end = full.rfind(':', basename_end);
+ }
if (context_end == llvm::StringRef::npos)
m_basename = full.substr(0, basename_end);
else
{
- m_context = full.substr(0, context_end - 1);
+ if (context_start < context_end)
+ m_context = full.substr(context_start, context_end - 1);
const size_t basename_begin = context_end + 1;
m_basename = full.substr(basename_begin, basename_end - basename_begin);
}
@@ -343,6 +353,30 @@ CPPLanguageRuntime::MethodName::Parse()
// printf (" arguments = '%s'\n", m_arguments.str().c_str());
// if (!m_qualifiers.empty())
// printf ("qualifiers = '%s'\n", m_qualifiers.str().c_str());
+
+ // Make sure we have a valid C++ basename with optional template args
+ static RegularExpression g_identifier_regex("^~?([A-Za-z_][A-Za-z_0-9]*)(<.*>)?$");
+ std::string basename_str(m_basename.str());
+ bool basename_is_valid = g_identifier_regex.Execute (basename_str.c_str(), NULL);
+ if (!basename_is_valid)
+ {
+ // Check for C++ operators
+ if (m_basename.startswith("operator"))
+ {
+ static RegularExpression g_operator_regex("^(operator)( ?)([A-Za-z_][A-Za-z_0-9]*|\\(\\)|\\[\\]|[\\^<>=!\\/*+-]+)(<.*>)?(\\[\\])?$");
+ basename_is_valid = g_operator_regex.Execute(basename_str.c_str(), NULL);
+ }
+ }
+ if (!basename_is_valid)
+ {
+ // The C++ basename doesn't match our regular expressions so this can't
+ // be a valid C++ method, clear everything out and indicate an error
+ m_context = llvm::StringRef();
+ m_basename = llvm::StringRef();
+ m_arguments = llvm::StringRef();
+ m_qualifiers = llvm::StringRef();
+ m_parse_error = true;
+ }
}
else
{