summaryrefslogtreecommitdiff
path: root/source/Plugins/Language/CPlusPlus
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2018-07-28 11:09:23 +0000
committerDimitry Andric <dim@FreeBSD.org>2018-07-28 11:09:23 +0000
commitf73363f1dd94996356cefbf24388f561891acf0b (patch)
treee3c31248bdb36eaec5fd833490d4278162dba2a0 /source/Plugins/Language/CPlusPlus
parent160ee69dd7ae18978f4068116777639ea98dc951 (diff)
downloadsrc-test2-f73363f1dd94996356cefbf24388f561891acf0b.tar.gz
src-test2-f73363f1dd94996356cefbf24388f561891acf0b.zip
Notes
Diffstat (limited to 'source/Plugins/Language/CPlusPlus')
-rw-r--r--source/Plugins/Language/CPlusPlus/BlockPointer.cpp5
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp46
-rw-r--r--source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp36
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxx.cpp14
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxList.cpp8
-rw-r--r--source/Plugins/Language/CPlusPlus/LibCxxMap.cpp4
-rw-r--r--source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp29
7 files changed, 82 insertions, 60 deletions
diff --git a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
index 5e8f051dec98..82b7ac1675fa 100644
--- a/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
+++ b/source/Plugins/Language/CPlusPlus/BlockPointer.cpp
@@ -147,9 +147,8 @@ public:
return child_sp;
}
- // return true if this object is now safe to use forever without
- // ever updating again; the typical (and tested) answer here is
- // 'false'
+ // return true if this object is now safe to use forever without ever
+ // updating again; the typical (and tested) answer here is 'false'
bool Update() override { return false; }
// maybe return false if the block pointer is, say, null
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
index 51ed88065c84..2c63e6467d4c 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusLanguage.cpp
@@ -120,10 +120,9 @@ static bool ReverseFindMatchingChars(const llvm::StringRef &s,
static bool IsTrivialBasename(const llvm::StringRef &basename) {
// Check that the basename matches with the following regular expression
- // "^~?([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.
+ // "^~?([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;
@@ -151,10 +150,9 @@ static bool IsTrivialBasename(const llvm::StringRef &basename) {
}
bool CPlusPlusLanguage::MethodName::TrySimplifiedParse() {
- // This method tries to parse simple method definitions
- // which are presumably most comman in user programs.
- // Definitions that can be parsed by this function don't have return types
- // and templates in the name.
+ // This method tries to parse simple method definitions which are presumably
+ // most comman in user programs. Definitions that can be parsed by this
+ // function don't have return types and templates in the name.
// A::B::C::fun(std::vector<T> &) const
size_t arg_start, arg_end;
llvm::StringRef full(m_full.GetCString());
@@ -251,13 +249,17 @@ std::string CPlusPlusLanguage::MethodName::GetScopeQualifiedName() {
}
bool CPlusPlusLanguage::IsCPPMangledName(const char *name) {
- // FIXME, we should really run through all the known C++ Language plugins and
- // ask each one if
- // this is a C++ mangled name, but we can put that off till there is actually
- // more than one
- // we care about.
-
- return (name != nullptr && name[0] == '_' && name[1] == 'Z');
+ // FIXME!! we should really run through all the known C++ Language plugins
+ // and ask each one if this is a C++ mangled name
+
+ if (name == nullptr)
+ return false;
+
+ // MSVC style mangling
+ if (name[0] == '?')
+ return true;
+
+ return (name[0] != '\0' && name[0] == '_' && name[1] == 'Z');
}
bool CPlusPlusLanguage::ExtractContextAndIdentifier(
@@ -307,13 +309,15 @@ static ConstString SubsPrimitiveParmItanium(llvm::StringRef mangled,
// FastDemangle will call our hook for each instance of a primitive type,
// allowing us to perform substitution
- const char *const demangled =
+ char *const demangled =
FastDemangle(mangled.str().c_str(), mangled.size(), swap_parms_hook);
if (log)
log->Printf("substituted mangling for %s:{%s} %s:{%s}\n",
mangled.str().c_str(), demangled, output_buf.c_str(),
FastDemangle(output_buf.c_str()));
+ // FastDemangle malloc'd this string.
+ free(demangled);
return output_buf == mangled ? ConstString() : ConstString(output_buf);
}
@@ -419,18 +423,20 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
SyntheticChildren::Flags stl_synth_flags;
stl_synth_flags.SetCascades(true).SetSkipPointers(false).SetSkipReferences(
false);
+ SyntheticChildren::Flags stl_deref_flags = stl_synth_flags;
+ stl_deref_flags.SetFrontEndWantsDereference();
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxBitsetSyntheticFrontEndCreator,
"libc++ std::bitset synthetic children",
- ConstString("^std::__(ndk)?1::bitset<.+>(( )?&)?$"), stl_synth_flags,
+ ConstString("^std::__(ndk)?1::bitset<.+>(( )?&)?$"), stl_deref_flags,
true);
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxStdVectorSyntheticFrontEndCreator,
"libc++ std::vector synthetic children",
- ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_synth_flags,
+ ConstString("^std::__(ndk)?1::vector<.+>(( )?&)?$"), stl_deref_flags,
true);
AddCXXSynthetic(
cpp_category_sp,
@@ -453,13 +459,13 @@ static void LoadLibCxxFormatters(lldb::TypeCategoryImplSP cpp_category_sp) {
cpp_category_sp,
lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
"libc++ std::set synthetic children",
- ConstString("^std::__(ndk)?1::set<.+> >(( )?&)?$"), stl_synth_flags,
+ ConstString("^std::__(ndk)?1::set<.+> >(( )?&)?$"), stl_deref_flags,
true);
AddCXXSynthetic(
cpp_category_sp,
lldb_private::formatters::LibcxxStdMapSyntheticFrontEndCreator,
"libc++ std::multiset synthetic children",
- ConstString("^std::__(ndk)?1::multiset<.+> >(( )?&)?$"), stl_synth_flags,
+ ConstString("^std::__(ndk)?1::multiset<.+> >(( )?&)?$"), stl_deref_flags,
true);
AddCXXSynthetic(
cpp_category_sp,
diff --git a/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp b/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
index aebea6ae3569..b32fe9588965 100644
--- a/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
+++ b/source/Plugins/Language/CPlusPlus/CPlusPlusNameParser.cpp
@@ -25,8 +25,8 @@ Optional<ParsedFunction> CPlusPlusNameParser::ParseAsFunctionDefinition() {
m_next_token_index = 0;
Optional<ParsedFunction> result(None);
- // Try to parse the name as function without a return type specified
- // e.g. main(int, char*[])
+ // Try to parse the name as function without a return type specified e.g.
+ // main(int, char*[])
{
Bookmark start_position = SetBookmark();
result = ParseFunctionImpl(false);
@@ -34,8 +34,8 @@ Optional<ParsedFunction> CPlusPlusNameParser::ParseAsFunctionDefinition() {
return result;
}
- // Try to parse the name as function with function pointer return type
- // e.g. void (*get_func(const char*))()
+ // Try to parse the name as function with function pointer return type e.g.
+ // void (*get_func(const char*))()
result = ParseFuncPtr(true);
if (result)
return result;
@@ -183,13 +183,13 @@ bool CPlusPlusNameParser::ConsumeTemplateArgs() {
Advance();
// Consuming template arguments is a bit trickier than consuming function
- // arguments, because '<' '>' brackets are not always trivially balanced.
- // In some rare cases tokens '<' and '>' can appear inside template arguments
- // as arithmetic or shift operators not as template brackets.
- // Examples: std::enable_if<(10u)<(64), bool>
+ // arguments, because '<' '>' brackets are not always trivially balanced. In
+ // some rare cases tokens '<' and '>' can appear inside template arguments as
+ // arithmetic or shift operators not as template brackets. Examples:
+ // std::enable_if<(10u)<(64), bool>
// f<A<operator<(X,Y)::Subclass>>
- // Good thing that compiler makes sure that really ambiguous cases of
- // '>' usage should be enclosed within '()' brackets.
+ // Good thing that compiler makes sure that really ambiguous cases of '>'
+ // usage should be enclosed within '()' brackets.
int template_counter = 1;
bool can_open_template = false;
while (HasMoreTokens() && template_counter > 0) {
@@ -208,9 +208,9 @@ bool CPlusPlusNameParser::ConsumeTemplateArgs() {
case tok::less:
// '<' is an attempt to open a subteamplte
// check if parser is at the point where it's actually possible,
- // otherwise it's just a part of an expression like 'sizeof(T)<(10)'.
- // No need to do the same for '>' because compiler actually makes sure
- // that '>' always surrounded by brackets to avoid ambiguity.
+ // otherwise it's just a part of an expression like 'sizeof(T)<(10)'. No
+ // need to do the same for '>' because compiler actually makes sure that
+ // '>' always surrounded by brackets to avoid ambiguity.
if (can_open_template)
++template_counter;
can_open_template = false;
@@ -242,8 +242,7 @@ bool CPlusPlusNameParser::ConsumeTemplateArgs() {
}
}
- assert(template_counter >= 0);
- if (template_counter > 0) {
+ if (template_counter != 0) {
return false;
}
start_position.Remove();
@@ -389,10 +388,9 @@ void CPlusPlusNameParser::SkipFunctionQualifiers() {
bool CPlusPlusNameParser::ConsumeBuiltinType() {
bool result = false;
bool continue_parsing = true;
- // Built-in types can be made of a few keywords
- // like 'unsigned long long int'. This function
- // consumes all built-in type keywords without
- // checking if they make sense like 'unsigned char void'.
+ // Built-in types can be made of a few keywords like 'unsigned long long
+ // int'. This function consumes all built-in type keywords without checking
+ // if they make sense like 'unsigned char void'.
while (continue_parsing && HasMoreTokens()) {
switch (Peek().getKind()) {
case tok::kw_short:
diff --git a/source/Plugins/Language/CPlusPlus/LibCxx.cpp b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
index f6d1f18cb596..95e02a473cd7 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxx.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxx.cpp
@@ -123,12 +123,11 @@ bool lldb_private::formatters::LibCxxMapIteratorSyntheticFrontEnd::Update() {
static ConstString g___i_("__i_");
- // this must be a ValueObject* because it is a child of the ValueObject we are
- // producing children for
- // it if were a ValueObjectSP, we would end up with a loop (iterator ->
- // synthetic -> child -> parent == iterator)
- // and that would in turn leak memory by never allowing the ValueObjects to
- // die and free their memory
+ // this must be a ValueObject* because it is a child of the ValueObject we
+ // are producing children for it if were a ValueObjectSP, we would end up
+ // with a loop (iterator -> synthetic -> child -> parent == iterator) and
+ // that would in turn leak memory by never allowing the ValueObjects to die
+ // and free their memory
m_pair_ptr = valobj_sp
->GetValueForExpressionPath(
".__i_.__ptr_->__value_", nullptr, nullptr,
@@ -386,7 +385,8 @@ enum LibcxxStringLayoutMode {
};
// this function abstracts away the layout and mode details of a libc++ string
-// and returns the address of the data and the size ready for callers to consume
+// and returns the address of the data and the size ready for callers to
+// consume
static bool ExtractLibcxxStringInfo(ValueObject &valobj,
ValueObjectSP &location_sp,
uint64_t &size) {
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
index 6407ae129ad7..6066f14b18cc 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxList.cpp
@@ -206,8 +206,7 @@ bool AbstractListFrontEnd::HasLoop(size_t count) {
if (m_loop_detected == 0) {
// This is the first time we are being run (after the last update). Set up
- // the loop
- // invariant for the first element.
+ // the loop invariant for the first element.
m_slow_runner = ListEntry(m_head).next();
m_fast_runner = m_slow_runner.next();
m_loop_detected = 1;
@@ -215,9 +214,8 @@ bool AbstractListFrontEnd::HasLoop(size_t count) {
// Loop invariant:
// Loop detection has been run over the first m_loop_detected elements. If
- // m_slow_runner ==
- // m_fast_runner then the loop has been detected after m_loop_detected
- // elements.
+ // m_slow_runner == m_fast_runner then the loop has been detected after
+ // m_loop_detected elements.
const size_t steps_to_run = std::min(count, m_count);
while (m_loop_detected < steps_to_run && m_slow_runner && m_fast_runner &&
m_slow_runner != m_fast_runner) {
diff --git a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
index be96a6d95bcd..8f82bdcbfd59 100644
--- a/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibCxxMap.cpp
@@ -382,8 +382,8 @@ lldb_private::formatters::LibcxxStdMapSyntheticFrontEnd::GetChildAtIndex(
return lldb::ValueObjectSP();
}
} else {
- // because of the way our debug info is made, we need to read item 0 first
- // so that we can cache information used to generate other elements
+ // because of the way our debug info is made, we need to read item 0
+ // first so that we can cache information used to generate other elements
if (m_skip_size == UINT32_MAX)
GetChildAtIndex(0);
if (m_skip_size == UINT32_MAX) {
diff --git a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
index b6d664df16ef..9d46e3e3ee58 100644
--- a/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
+++ b/source/Plugins/Language/CPlusPlus/LibStdcppUniquePointer.cpp
@@ -43,6 +43,8 @@ private:
ValueObjectSP m_ptr_obj;
ValueObjectSP m_obj_obj;
ValueObjectSP m_del_obj;
+
+ ValueObjectSP GetTuple();
};
} // end of anonymous namespace
@@ -53,17 +55,36 @@ LibStdcppUniquePtrSyntheticFrontEnd::LibStdcppUniquePtrSyntheticFrontEnd(
Update();
}
-bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
+ValueObjectSP LibStdcppUniquePtrSyntheticFrontEnd::GetTuple() {
ValueObjectSP valobj_backend_sp = m_backend.GetSP();
+
if (!valobj_backend_sp)
- return false;
+ return nullptr;
ValueObjectSP valobj_sp = valobj_backend_sp->GetNonSyntheticValue();
if (!valobj_sp)
- return false;
+ return nullptr;
- ValueObjectSP tuple_sp =
+ ValueObjectSP obj_child_sp =
valobj_sp->GetChildMemberWithName(ConstString("_M_t"), true);
+ if (!obj_child_sp)
+ return nullptr;
+
+ ValueObjectSP obj_subchild_sp =
+ obj_child_sp->GetChildMemberWithName(ConstString("_M_t"), true);
+
+ // if there is a _M_t subchild, the tuple is found in the obj_subchild_sp
+ // (for libstdc++ 6.0.23).
+ if (obj_subchild_sp) {
+ return obj_subchild_sp;
+ }
+
+ return obj_child_sp;
+}
+
+bool LibStdcppUniquePtrSyntheticFrontEnd::Update() {
+ ValueObjectSP tuple_sp = GetTuple();
+
if (!tuple_sp)
return false;