summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Language/CPlusPlus
diff options
context:
space:
mode:
authorAleksandr Urakov <aleksandr.urakov@jetbrains.com>2018-11-06 08:02:55 +0000
committerAleksandr Urakov <aleksandr.urakov@jetbrains.com>2018-11-06 08:02:55 +0000
commitc1e530ee92ce8e0e6aa67677c4d0843f94b3ee05 (patch)
tree96f72c82f06e7d4d56a25a836d7e8cfcaf0934d4 /lldb/source/Plugins/Language/CPlusPlus
parent908aabb783ce922021142dffd80676be6db0ebb0 (diff)
downloadbcm5719-llvm-c1e530ee92ce8e0e6aa67677c4d0843f94b3ee05.tar.gz
bcm5719-llvm-c1e530ee92ce8e0e6aa67677c4d0843f94b3ee05.zip
[PDB] Introduce `MSVCUndecoratedNameParser`
This patch introduces the simple MSVCUndecoratedNameParser. It is needed for parsing names of PDB symbols corresponding to template instantiations. For example, for the name `operator<<A>'::`2'::B::operator> we can't just split the name with :: (as it is implemented for now) to retrieve its scopes. This parser processes such names in a more correct way. Differential Revision: https://reviews.llvm.org/D52461 llvm-svn: 346213
Diffstat (limited to 'lldb/source/Plugins/Language/CPlusPlus')
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt1
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp5
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp98
-rw-r--r--lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h51
4 files changed, 155 insertions, 0 deletions
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
index 715334412f8..bc357aa52b8 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
+++ b/lldb/source/Plugins/Language/CPlusPlus/CMakeLists.txt
@@ -18,6 +18,7 @@ add_lldb_library(lldbPluginCPlusPlusLanguage PLUGIN
LibStdcpp.cpp
LibStdcppTuple.cpp
LibStdcppUniquePointer.cpp
+ MSVCUndecoratedNameParser.cpp
LINK_LIBS
lldbCore
diff --git a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index f437582fbd2..badfb948ed9 100644
--- a/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/lldb/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -41,6 +41,7 @@
#include "LibCxxAtomic.h"
#include "LibCxxVariant.h"
#include "LibStdcpp.h"
+#include "MSVCUndecoratedNameParser.h"
using namespace lldb;
using namespace lldb_private;
@@ -265,6 +266,10 @@ bool CPlusPlusLanguage::IsCPPMangledName(const char *name) {
bool CPlusPlusLanguage::ExtractContextAndIdentifier(
const char *name, llvm::StringRef &context, llvm::StringRef &identifier) {
+ if (MSVCUndecoratedNameParser::IsMSVCUndecoratedName(name))
+ return MSVCUndecoratedNameParser::ExtractContextAndIdentifier(name, context,
+ identifier);
+
CPlusPlusNameParser parser(name);
if (auto full_name = parser.ParseAsFullName()) {
identifier = full_name.getValue().basename;
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp b/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp
new file mode 100644
index 00000000000..d2207566de3
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.cpp
@@ -0,0 +1,98 @@
+//===-- MSVCUndecoratedNameParser.cpp ---------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "MSVCUndecoratedNameParser.h"
+
+#include <stack>
+
+MSVCUndecoratedNameParser::MSVCUndecoratedNameParser(llvm::StringRef name) {
+ std::size_t last_base_start = 0;
+
+ std::stack<std::size_t> stack;
+ unsigned int open_angle_brackets = 0;
+ for (size_t i = 0; i < name.size(); i++) {
+ switch (name[i]) {
+ case '<':
+ // Do not treat `operator<' and `operator<<' as templates
+ // (sometimes they represented as `<' and `<<' in the name).
+ if (i == last_base_start ||
+ i == last_base_start + 1 && name[last_base_start] == '<')
+ break;
+
+ stack.push(i);
+ open_angle_brackets++;
+
+ break;
+ case '>':
+ if (!stack.empty() && name[stack.top()] == '<') {
+ open_angle_brackets--;
+ stack.pop();
+ }
+
+ break;
+ case '`':
+ stack.push(i);
+
+ break;
+ case '\'':
+ while (!stack.empty()) {
+ std::size_t top = stack.top();
+ if (name[top] == '<')
+ open_angle_brackets--;
+
+ stack.pop();
+
+ if (name[top] == '`')
+ break;
+ }
+
+ break;
+ case ':':
+ if (open_angle_brackets)
+ break;
+ if (i == 0 || name[i - 1] != ':')
+ break;
+
+ m_specifiers.emplace_back(name.take_front(i - 1),
+ name.slice(last_base_start, i - 1));
+
+ last_base_start = i + 1;
+ default:
+ break;
+ }
+ }
+
+ m_specifiers.emplace_back(name, name.drop_front(last_base_start));
+}
+
+bool MSVCUndecoratedNameParser::IsMSVCUndecoratedName(llvm::StringRef name) {
+ return name.find('`') != llvm::StringRef::npos;
+}
+
+bool MSVCUndecoratedNameParser::ExtractContextAndIdentifier(
+ llvm::StringRef name, llvm::StringRef &context,
+ llvm::StringRef &identifier) {
+ MSVCUndecoratedNameParser parser(name);
+ llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
+
+ std::size_t count = specs.size();
+ identifier = count > 0 ? specs[count - 1].GetBaseName() : "";
+ context = count > 1 ? specs[count - 2].GetFullName() : "";
+
+ return count;
+}
+
+llvm::StringRef MSVCUndecoratedNameParser::DropScope(llvm::StringRef name) {
+ MSVCUndecoratedNameParser parser(name);
+ llvm::ArrayRef<MSVCUndecoratedNameSpecifier> specs = parser.GetSpecifiers();
+ if (specs.empty())
+ return "";
+
+ return specs[specs.size() - 1].GetBaseName();
+}
diff --git a/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h b/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h
new file mode 100644
index 00000000000..0c49100d8d4
--- /dev/null
+++ b/lldb/source/Plugins/Language/CPlusPlus/MSVCUndecoratedNameParser.h
@@ -0,0 +1,51 @@
+//===-- MSVCUndecoratedNameParser.h -----------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_MSVCUndecoratedNameParser_h_
+#define liblldb_MSVCUndecoratedNameParser_h_
+
+#include <vector>
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/StringRef.h"
+
+class MSVCUndecoratedNameSpecifier {
+public:
+ MSVCUndecoratedNameSpecifier(llvm::StringRef full_name,
+ llvm::StringRef base_name)
+ : m_full_name(full_name), m_base_name(base_name) {}
+
+ llvm::StringRef GetFullName() const { return m_full_name; }
+ llvm::StringRef GetBaseName() const { return m_base_name; }
+
+private:
+ llvm::StringRef m_full_name;
+ llvm::StringRef m_base_name;
+};
+
+class MSVCUndecoratedNameParser {
+public:
+ explicit MSVCUndecoratedNameParser(llvm::StringRef name);
+
+ llvm::ArrayRef<MSVCUndecoratedNameSpecifier> GetSpecifiers() const {
+ return m_specifiers;
+ }
+
+ static bool IsMSVCUndecoratedName(llvm::StringRef name);
+ static bool ExtractContextAndIdentifier(llvm::StringRef name,
+ llvm::StringRef &context,
+ llvm::StringRef &identifier);
+
+ static llvm::StringRef DropScope(llvm::StringRef name);
+
+private:
+ std::vector<MSVCUndecoratedNameSpecifier> m_specifiers;
+};
+
+#endif
OpenPOWER on IntegriCloud