diff options
author | Tamas Berghammer <tberghammer@google.com> | 2015-10-27 10:43:27 +0000 |
---|---|---|
committer | Tamas Berghammer <tberghammer@google.com> | 2015-10-27 10:43:27 +0000 |
commit | 9fa114705282d226ff3a3de6c8b270208c57de89 (patch) | |
tree | dab1aad2868bde324b6abba4a1a4a26f89daa79f /lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp | |
parent | 458e79b814b9998368b2306b09393b74f220f62d (diff) | |
download | llvm-9fa114705282d226ff3a3de6c8b270208c57de89.zip llvm-9fa114705282d226ff3a3de6c8b270208c57de89.tar.gz llvm-9fa114705282d226ff3a3de6c8b270208c57de89.tar.bz2 |
Some minor improvements on the symtab parsing code
* Remove an unneccessary re-computaion on arch spec from the ELF file
* Use a local cache to optimize name based section lookups in symtab
parsing
* Optimize C++ method basename validation with replacing a regex with
hand written code
These modifications reduce the time required to parse the symtab from
large applications by ~25% (tested with LLDB as inferior)
Differential revision: http://reviews.llvm.org/D14088
llvm-svn: 251402
Diffstat (limited to 'lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp')
-rw-r--r-- | lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp | 70 |
1 files changed, 45 insertions, 25 deletions
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp index b5634ec..2587cf4 100644 --- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp +++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp @@ -131,6 +131,49 @@ ReverseFindMatchingChars (const llvm::StringRef &s, return false; } +static bool +IsValidBasename(const llvm::StringRef& basename) +{ + // Check that the basename matches with the following regular expression or is an operator name: + // "^~?([A-Za-z_][A-Za-z_0-9]*)(<.*>)?$" + // We are using a hand written implementation because it is significantly more efficient then + // using the general purpose regular expression library. + size_t idx = 0; + if (basename.size() > 0 && basename[0] == '~') + idx = 1; + + if (basename.size() <= idx) + return false; // Empty string or "~" + + if (!std::isalpha(basename[idx]) && basename[idx] != '_') + return false; // First charater (after removing the possible '~'') isn't in [A-Za-z_] + + // Read all characters matching [A-Za-z_0-9] + ++idx; + while (idx < basename.size()) + { + if (!std::isalnum(basename[idx]) && basename[idx] != '_') + break; + ++idx; + } + + // We processed all characters. It is a vaild basename. + if (idx == basename.size()) + return true; + + // Check for basename with template arguments + // TODO: Improve the quality of the validation with validating the template arguments + if (basename[idx] == '<' && basename.back() == '>') + return true; + + // Check if the basename is a vaild C++ operator name + if (!basename.startswith("operator")) + return false; + + static RegularExpression g_operator_regex("^(operator)( ?)([A-Za-z_][A-Za-z_0-9]*|\\(\\)|\\[\\]|[\\^<>=!\\/*+-]+)(<.*>)?(\\[\\])?$"); + std::string basename_str(basename.str()); + return g_operator_regex.Execute(basename_str.c_str(), nullptr); +} void CPlusPlusLanguage::MethodName::Parse() @@ -201,30 +244,8 @@ CPlusPlusLanguage::MethodName::Parse() m_parse_error = true; return; } - -// if (!m_context.empty()) -// printf (" context = '%s'\n", m_context.str().c_str()); -// if (m_basename) -// printf (" basename = '%s'\n", m_basename.GetCString()); -// if (!m_arguments.empty()) -// 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) + + if (!IsValidBasename(m_basename)) { // 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 @@ -238,7 +259,6 @@ CPlusPlusLanguage::MethodName::Parse() else { m_parse_error = true; -// printf ("error: didn't find matching parens for arguments\n"); } } } |