summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/API/SBTypeFormat.h18
-rw-r--r--lldb/include/lldb/DataFormatters/TypeFormat.h130
-rw-r--r--lldb/scripts/Python/interface/SBTypeFormat.i8
-rw-r--r--lldb/source/API/SBTypeFormat.cpp56
-rw-r--r--lldb/source/Commands/CommandObjectType.cpp32
-rw-r--r--lldb/source/Core/ValueObject.cpp4
-rw-r--r--lldb/source/DataFormatters/FormatManager.cpp2
-rw-r--r--lldb/source/DataFormatters/TypeFormat.cpp102
-rw-r--r--lldb/test/functionalities/data-formatter/data-formatter-enum-format/Makefile5
-rw-r--r--lldb/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py80
-rw-r--r--lldb/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp13
11 files changed, 399 insertions, 51 deletions
diff --git a/lldb/include/lldb/API/SBTypeFormat.h b/lldb/include/lldb/API/SBTypeFormat.h
index cd6345fbe6f..eb45ff2b0eb 100644
--- a/lldb/include/lldb/API/SBTypeFormat.h
+++ b/lldb/include/lldb/API/SBTypeFormat.h
@@ -22,6 +22,9 @@ public:
SBTypeFormat (lldb::Format format,
uint32_t options = 0); // see lldb::eTypeOption values
+
+ SBTypeFormat (const char* type,
+ uint32_t options = 0); // see lldb::eTypeOption values
SBTypeFormat (const lldb::SBTypeFormat &rhs);
@@ -33,6 +36,9 @@ public:
lldb::Format
GetFormat ();
+ const char*
+ GetTypeName ();
+
uint32_t
GetOptions();
@@ -40,6 +46,9 @@ public:
SetFormat (lldb::Format);
void
+ SetTypeName (const char*);
+
+ void
SetOptions (uint32_t);
bool
@@ -73,8 +82,15 @@ protected:
SBTypeFormat (const lldb::TypeFormatImplSP &);
+ enum class Type
+ {
+ eTypeKeepSame,
+ eTypeFormat,
+ eTypeEnum
+ };
+
bool
- CopyOnWrite_Impl();
+ CopyOnWrite_Impl(Type);
};
diff --git a/lldb/include/lldb/DataFormatters/TypeFormat.h b/lldb/include/lldb/DataFormatters/TypeFormat.h
index a0198498d01..20fa8f2d4e7 100644
--- a/lldb/include/lldb/DataFormatters/TypeFormat.h
+++ b/lldb/include/lldb/DataFormatters/TypeFormat.h
@@ -130,15 +130,12 @@ namespace lldb_private {
uint32_t m_flags;
};
- TypeFormatImpl (lldb::Format f = lldb::eFormatInvalid,
- const Flags& flags = Flags());
+ TypeFormatImpl (const Flags& flags = Flags());
typedef std::shared_ptr<TypeFormatImpl> SharedPointer;
typedef bool(*ValueCallback)(void*, ConstString, const lldb::TypeFormatImplSP&);
- ~TypeFormatImpl ()
- {
- }
+ virtual ~TypeFormatImpl () = default;
bool
Cascades () const
@@ -173,6 +170,66 @@ namespace lldb_private {
{
m_flags.SetSkipReferences(value);
}
+
+ uint32_t
+ GetOptions ()
+ {
+ return m_flags.GetValue();
+ }
+
+ void
+ SetOptions (uint32_t value)
+ {
+ m_flags.SetValue(value);
+ }
+
+ uint32_t&
+ GetRevision ()
+ {
+ return m_my_revision;
+ }
+
+ enum class Type
+ {
+ eTypeUnknown,
+ eTypeFormat,
+ eTypeEnum
+ };
+
+ virtual Type
+ GetType ()
+ {
+ return Type::eTypeUnknown;
+ }
+
+ // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for
+ // extended periods of time and we trust the ValueObject to stay around for as long as it is required
+ // for us to generate its value
+ virtual bool
+ FormatObject (ValueObject *valobj,
+ std::string& dest) const = 0;
+
+ virtual std::string
+ GetDescription() = 0;
+
+ protected:
+ Flags m_flags;
+ uint32_t m_my_revision;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl);
+ };
+
+ class TypeFormatImpl_Format : public TypeFormatImpl
+ {
+ public:
+ TypeFormatImpl_Format (lldb::Format f = lldb::eFormatInvalid,
+ const TypeFormatImpl::Flags& flags = Flags());
+
+ typedef std::shared_ptr<TypeFormatImpl_Format> SharedPointer;
+ typedef bool(*ValueCallback)(void*, ConstString, const TypeFormatImpl_Format::SharedPointer&);
+
+ virtual ~TypeFormatImpl_Format () = default;
lldb::Format
GetFormat () const
@@ -186,42 +243,69 @@ namespace lldb_private {
m_format = fmt;
}
- uint32_t
- GetOptions ()
+ virtual TypeFormatImpl::Type
+ GetType ()
{
- return m_flags.GetValue();
+ return TypeFormatImpl::Type::eTypeFormat;
+ }
+
+ virtual bool
+ FormatObject (ValueObject *valobj,
+ std::string& dest) const;
+
+ virtual std::string
+ GetDescription();
+
+ protected:
+ lldb::Format m_format;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl_Format);
+ };
+
+ class TypeFormatImpl_EnumType : public TypeFormatImpl
+ {
+ public:
+ TypeFormatImpl_EnumType (ConstString type_name = ConstString(""),
+ const TypeFormatImpl::Flags& flags = Flags());
+
+ typedef std::shared_ptr<TypeFormatImpl_EnumType> SharedPointer;
+ typedef bool(*ValueCallback)(void*, ConstString, const TypeFormatImpl_EnumType::SharedPointer&);
+
+ ~TypeFormatImpl_EnumType () = default;
+
+ ConstString
+ GetTypeName ()
+ {
+ return m_enum_type;
}
void
- SetOptions (uint32_t value)
+ SetTypeName (ConstString enum_type)
{
- m_flags.SetValue(value);
+ m_enum_type = enum_type;
}
- uint32_t&
- GetRevision ()
+ virtual TypeFormatImpl::Type
+ GetType ()
{
- return m_my_revision;
+ return TypeFormatImpl::Type::eTypeEnum;
}
- // we are using a ValueObject* instead of a ValueObjectSP because we do not need to hold on to this for
- // extended periods of time and we trust the ValueObject to stay around for as long as it is required
- // for us to generate its value
- bool
+ virtual bool
FormatObject (ValueObject *valobj,
std::string& dest) const;
- std::string
+ virtual std::string
GetDescription();
protected:
- Flags m_flags;
- lldb::Format m_format;
- uint32_t m_my_revision;
+ ConstString m_enum_type;
+ mutable std::map<void*,ClangASTType> m_types;
private:
- DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl);
- };
+ DISALLOW_COPY_AND_ASSIGN(TypeFormatImpl_EnumType);
+ };
} // namespace lldb_private
#endif // lldb_TypeFormat_h_
diff --git a/lldb/scripts/Python/interface/SBTypeFormat.i b/lldb/scripts/Python/interface/SBTypeFormat.i
index 9d2f1a675aa..4e4b69c3f1f 100644
--- a/lldb/scripts/Python/interface/SBTypeFormat.i
+++ b/lldb/scripts/Python/interface/SBTypeFormat.i
@@ -21,6 +21,8 @@ namespace lldb {
SBTypeFormat (lldb::Format format, uint32_t options = 0);
+ SBTypeFormat (const char* type, uint32_t options = 0);
+
SBTypeFormat (const lldb::SBTypeFormat &rhs);
~SBTypeFormat ();
@@ -34,6 +36,9 @@ namespace lldb {
lldb::Format
GetFormat ();
+ const char*
+ GetTypeName ();
+
uint32_t
GetOptions();
@@ -41,6 +46,9 @@ namespace lldb {
SetFormat (lldb::Format);
void
+ SetTypeName (const char*);
+
+ void
SetOptions (uint32_t);
bool
diff --git a/lldb/source/API/SBTypeFormat.cpp b/lldb/source/API/SBTypeFormat.cpp
index 34ab404a206..d3ec9bc00bd 100644
--- a/lldb/source/API/SBTypeFormat.cpp
+++ b/lldb/source/API/SBTypeFormat.cpp
@@ -25,7 +25,13 @@ m_opaque_sp()
SBTypeFormat::SBTypeFormat (lldb::Format format,
uint32_t options)
-: m_opaque_sp(TypeFormatImplSP(new TypeFormatImpl(format,options)))
+: m_opaque_sp(TypeFormatImplSP(new TypeFormatImpl_Format(format,options)))
+{
+}
+
+SBTypeFormat::SBTypeFormat (const char* type,
+ uint32_t options)
+: m_opaque_sp(TypeFormatImplSP(new TypeFormatImpl_EnumType(ConstString(type ? type : ""),options)))
{
}
@@ -47,11 +53,19 @@ SBTypeFormat::IsValid() const
lldb::Format
SBTypeFormat::GetFormat ()
{
- if (IsValid())
- return m_opaque_sp->GetFormat();
+ if (IsValid() && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeFormat)
+ return ((TypeFormatImpl_Format*)m_opaque_sp.get())->GetFormat();
return lldb::eFormatInvalid;
}
+const char*
+SBTypeFormat::GetTypeName ()
+{
+ if (IsValid() && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeEnum)
+ return ((TypeFormatImpl_EnumType*)m_opaque_sp.get())->GetTypeName().AsCString("");
+ return "";
+}
+
uint32_t
SBTypeFormat::GetOptions()
{
@@ -63,14 +77,21 @@ SBTypeFormat::GetOptions()
void
SBTypeFormat::SetFormat (lldb::Format fmt)
{
- if (CopyOnWrite_Impl())
- m_opaque_sp->SetFormat(fmt);
+ if (CopyOnWrite_Impl(Type::eTypeFormat))
+ ((TypeFormatImpl_Format*)m_opaque_sp.get())->SetFormat(fmt);
+}
+
+void
+SBTypeFormat::SetTypeName (const char* type)
+{
+ if (CopyOnWrite_Impl(Type::eTypeEnum))
+ ((TypeFormatImpl_EnumType*)m_opaque_sp.get())->SetTypeName(ConstString(type ? type : ""));
}
void
SBTypeFormat::SetOptions (uint32_t value)
{
- if (CopyOnWrite_Impl())
+ if (CopyOnWrite_Impl(Type::eTypeKeepSame))
m_opaque_sp->SetOptions(value);
}
@@ -143,13 +164,30 @@ SBTypeFormat::SBTypeFormat (const lldb::TypeFormatImplSP &typeformat_impl_sp) :
}
bool
-SBTypeFormat::CopyOnWrite_Impl()
+SBTypeFormat::CopyOnWrite_Impl(Type type)
{
if (!IsValid())
return false;
- if (m_opaque_sp.unique())
+
+ if (m_opaque_sp.unique() &&
+ ((type == Type::eTypeKeepSame) ||
+ (type == Type::eTypeFormat && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeFormat) ||
+ (type == Type::eTypeEnum && m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeEnum))
+ )
return true;
- SetSP(TypeFormatImplSP(new TypeFormatImpl(GetFormat(),GetOptions())));
+ if (type == Type::eTypeKeepSame)
+ {
+ if (m_opaque_sp->GetType() == TypeFormatImpl::Type::eTypeFormat)
+ type = Type::eTypeFormat;
+ else
+ type = Type::eTypeEnum;
+ }
+
+ if (type == Type::eTypeFormat)
+ SetSP(TypeFormatImplSP(new TypeFormatImpl_Format(GetFormat(),GetOptions())));
+ else
+ SetSP(TypeFormatImplSP(new TypeFormatImpl_EnumType(ConstString(GetTypeName()),GetOptions())));
+
return true;
}
diff --git a/lldb/source/Commands/CommandObjectType.cpp b/lldb/source/Commands/CommandObjectType.cpp
index d4bc9672f6a..8c7d239bc37 100644
--- a/lldb/source/Commands/CommandObjectType.cpp
+++ b/lldb/source/Commands/CommandObjectType.cpp
@@ -371,6 +371,7 @@ private:
m_skip_references = false;
m_regex = false;
m_category.assign("default");
+ m_custom_type_name.clear();
}
virtual Error
SetOptionValue (CommandInterpreter &interpreter,
@@ -400,6 +401,9 @@ private:
case 'x':
m_regex = true;
break;
+ case 't':
+ m_custom_type_name.assign(option_value);
+ break;
default:
error.SetErrorStringWithFormat ("unrecognized option '%c'", short_option);
break;
@@ -419,6 +423,7 @@ private:
bool m_skip_pointers;
bool m_regex;
std::string m_category;
+ std::string m_custom_type_name;
};
OptionGroupOptions m_option_group;
@@ -480,7 +485,7 @@ public:
);
// Add the "--format" to all options groups
- m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_ALL);
+ m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, LLDB_OPT_SET_1);
m_option_group.Append (&m_command_options);
m_option_group.Finalize();
@@ -504,7 +509,7 @@ protected:
}
const Format format = m_format_options.GetFormat();
- if (format == eFormatInvalid)
+ if (format == eFormatInvalid && m_command_options.m_custom_type_name.empty())
{
result.AppendErrorWithFormat ("%s needs a valid format.\n", m_cmd_name.c_str());
result.SetStatus(eReturnStatusFailed);
@@ -513,10 +518,16 @@ protected:
TypeFormatImplSP entry;
- entry.reset(new TypeFormatImpl(format,
- TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
- SetSkipPointers(m_command_options.m_skip_pointers).
- SetSkipReferences(m_command_options.m_skip_references)));
+ if (m_command_options.m_custom_type_name.empty())
+ entry.reset(new TypeFormatImpl_Format(format,
+ TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
+ SetSkipPointers(m_command_options.m_skip_pointers).
+ SetSkipReferences(m_command_options.m_skip_references)));
+ else
+ entry.reset(new TypeFormatImpl_EnumType(ConstString(m_command_options.m_custom_type_name.c_str()),
+ TypeFormatImpl::Flags().SetCascades(m_command_options.m_cascade).
+ SetSkipPointers(m_command_options.m_skip_pointers).
+ SetSkipReferences(m_command_options.m_skip_references)));
// now I have a valid format, let's add it to every type
@@ -562,11 +573,12 @@ protected:
OptionDefinition
CommandObjectTypeFormatAdd::CommandOptions::g_option_table[] =
{
- { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
- { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
- { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
- { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
+ { LLDB_OPT_SET_ALL, false, "category", 'w', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
+ { LLDB_OPT_SET_ALL, false, "cascade", 'C', OptionParser::eRequiredArgument, NULL, 0, eArgTypeBoolean, "If true, cascade through typedef chains."},
+ { LLDB_OPT_SET_ALL, false, "skip-pointers", 'p', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for pointers-to-type objects."},
+ { LLDB_OPT_SET_ALL, false, "skip-references", 'r', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Don't use this format for references-to-type objects."},
{ LLDB_OPT_SET_ALL, false, "regex", 'x', OptionParser::eNoArgument, NULL, 0, eArgTypeNone, "Type names are actually regular expressions."},
+ { LLDB_OPT_SET_2, false, "type", 't', OptionParser::eRequiredArgument, NULL, 0, eArgTypeName, "Format variables as if they were of this type."},
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
};
diff --git a/lldb/source/Core/ValueObject.cpp b/lldb/source/Core/ValueObject.cpp
index fc29f6dcc99..56ac7e134ab 100644
--- a/lldb/source/Core/ValueObject.cpp
+++ b/lldb/source/Core/ValueObject.cpp
@@ -1402,7 +1402,7 @@ bool
ValueObject::GetValueAsCString (lldb::Format format,
std::string& destination)
{
- return GetValueAsCString(TypeFormatImpl(format),destination);
+ return GetValueAsCString(TypeFormatImpl_Format(format),destination);
}
const char *
@@ -1439,7 +1439,7 @@ ValueObject::GetValueAsCString ()
{
m_last_format = my_format;
if (!format_sp)
- format_sp.reset(new TypeFormatImpl(my_format));
+ format_sp.reset(new TypeFormatImpl_Format(my_format));
if (GetValueAsCString(*format_sp.get(), m_value_str))
{
if (!m_value_did_change && m_old_value_valid)
diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp
index ca4603c94bb..41e2acb1c99 100644
--- a/lldb/source/DataFormatters/FormatManager.cpp
+++ b/lldb/source/DataFormatters/FormatManager.cpp
@@ -741,7 +741,7 @@ AddFormat (TypeCategoryImpl::SharedPointer category_sp,
TypeFormatImpl::Flags flags,
bool regex = false)
{
- lldb::TypeFormatImplSP format_sp(new TypeFormatImpl(format, flags));
+ lldb::TypeFormatImplSP format_sp(new TypeFormatImpl_Format(format, flags));
if (regex)
category_sp->GetRegexTypeFormatsContainer()->Add(RegularExpressionSP(new RegularExpression(type_name.AsCString())),format_sp);
diff --git a/lldb/source/DataFormatters/TypeFormat.cpp b/lldb/source/DataFormatters/TypeFormat.cpp
index 6a1a103b5af..a72f551c741 100644
--- a/lldb/source/DataFormatters/TypeFormat.cpp
+++ b/lldb/source/DataFormatters/TypeFormat.cpp
@@ -25,22 +25,30 @@
#include "lldb/DataFormatters/TypeFormat.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Symbol/ClangASTType.h"
+#include "lldb/Symbol/TypeList.h"
#include "lldb/Target/StackFrame.h"
#include "lldb/Target/Target.h"
using namespace lldb;
using namespace lldb_private;
-TypeFormatImpl::TypeFormatImpl (lldb::Format f,
- const Flags& flags) :
+TypeFormatImpl::TypeFormatImpl (const Flags& flags) :
m_flags(flags),
+m_my_revision(0)
+{
+}
+
+
+TypeFormatImpl_Format::TypeFormatImpl_Format (lldb::Format f,
+ const TypeFormatImpl::Flags& flags) :
+TypeFormatImpl(flags),
m_format (f)
{
}
bool
-TypeFormatImpl::FormatObject (ValueObject *valobj,
- std::string& dest) const
+TypeFormatImpl_Format::FormatObject (ValueObject *valobj,
+ std::string& dest) const
{
if (!valobj)
return false;
@@ -127,7 +135,7 @@ TypeFormatImpl::FormatObject (ValueObject *valobj,
}
std::string
-TypeFormatImpl::GetDescription()
+TypeFormatImpl_Format::GetDescription()
{
StreamString sstr;
sstr.Printf ("%s%s%s%s",
@@ -138,3 +146,87 @@ TypeFormatImpl::GetDescription()
return sstr.GetString();
}
+TypeFormatImpl_EnumType::TypeFormatImpl_EnumType (ConstString type_name,
+ const TypeFormatImpl::Flags& flags) :
+TypeFormatImpl(flags),
+m_enum_type(type_name),
+m_types()
+{
+}
+
+bool
+TypeFormatImpl_EnumType::FormatObject (ValueObject *valobj,
+ std::string& dest) const
+{
+ dest.clear();
+ if (!valobj)
+ return false;
+ if (valobj->GetClangType().IsAggregateType ())
+ return false;
+ ProcessSP process_sp;
+ TargetSP target_sp;
+ void* valobj_key = (process_sp = valobj->GetProcessSP()).get();
+ if (!valobj_key)
+ valobj_key = (target_sp = valobj->GetTargetSP()).get();
+ else
+ target_sp = process_sp->GetTarget().shared_from_this();
+ if (!valobj_key)
+ return false;
+ auto iter = m_types.find(valobj_key),
+ end = m_types.end();
+ ClangASTType valobj_enum_type;
+ if (iter == end)
+ {
+ // probably a redundant check
+ if (!target_sp)
+ return false;
+ const ModuleList& images(target_sp->GetImages());
+ SymbolContext sc;
+ TypeList types;
+ images.FindTypes(sc, m_enum_type, false, UINT32_MAX, types);
+ if (types.GetSize() == 0)
+ return false;
+ for (lldb::TypeSP type_sp : types.Types())
+ {
+ if (!type_sp)
+ continue;
+ if ( (type_sp->GetClangForwardType().GetTypeInfo() & ClangASTType::eTypeIsEnumeration) == ClangASTType::eTypeIsEnumeration)
+ {
+ valobj_enum_type = type_sp->GetClangFullType();
+ m_types.emplace(valobj_key,valobj_enum_type);
+ break;
+ }
+ }
+ }
+ else
+ valobj_enum_type = iter->second;
+ if (valobj_enum_type.IsValid() == false)
+ return false;
+ DataExtractor data;
+ valobj->GetData(data);
+ ExecutionContext exe_ctx (valobj->GetExecutionContextRef());
+ StreamString sstr;
+ valobj_enum_type.DumpTypeValue(&sstr,
+ lldb::eFormatEnum,
+ data,
+ 0,
+ data.GetByteSize(),
+ 0,
+ 0,
+ exe_ctx.GetBestExecutionContextScope());
+ if (!sstr.GetString().empty())
+ dest.swap(sstr.GetString());
+ return !dest.empty();
+}
+
+std::string
+TypeFormatImpl_EnumType::GetDescription()
+{
+ StreamString sstr;
+ sstr.Printf ("as type %s%s%s%s",
+ m_enum_type.AsCString("<invalid type>"),
+ Cascades() ? "" : " (not cascading)",
+ SkipsPointers() ? " (skip pointers)" : "",
+ SkipsReferences() ? " (skip references)" : "");
+ return sstr.GetString();
+}
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-enum-format/Makefile b/lldb/test/functionalities/data-formatter/data-formatter-enum-format/Makefile
new file mode 100644
index 00000000000..314f1cb2f07
--- /dev/null
+++ b/lldb/test/functionalities/data-formatter/data-formatter-enum-format/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py b/lldb/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py
new file mode 100644
index 00000000000..69e477dfc16
--- /dev/null
+++ b/lldb/test/functionalities/data-formatter/data-formatter-enum-format/TestDataFormatterEnumFormat.py
@@ -0,0 +1,80 @@
+"""
+Test lldb data formatter subsystem.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+import lldbutil
+
+class EnumFormatTestCase(TestBase):
+
+ mydir = TestBase.compute_mydir(__file__)
+
+ @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+ @dsym_test
+ def test_with_dsym_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDsym()
+ self.data_formatter_commands()
+
+ @dwarf_test
+ def test_with_dwarf_and_run_command(self):
+ """Test data formatter commands."""
+ self.buildDwarf()
+ self.data_formatter_commands()
+
+ def setUp(self):
+ # Call super's setUp().
+ TestBase.setUp(self)
+ # Find the line number to break at.
+ self.line = line_number('main.cpp', '// Set break point at this line.')
+
+ def data_formatter_commands(self):
+ """Test that that file and class static variables display correctly."""
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ lldbutil.run_break_set_by_file_and_line (self, "main.cpp", self.line, num_expected_locations=1, loc_exact=True)
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ # The stop reason of the thread should be breakpoint.
+ self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+ substrs = ['stopped',
+ 'stop reason = breakpoint'])
+
+ self.expect("frame variable",
+ substrs = ['(Foo) f = Case45',
+ '(int) x = 1',
+ '(int) y = 45',
+ '(int) z = 43'
+ ]);
+
+ # This is the function to remove the custom formats in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type format clear', check=False)
+ self.runCmd('type summary clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ self.runCmd("type format add --type Foo int")
+
+ # The type format list should show our custom formats.
+ self.expect("type format list -w default",
+ substrs = ['int: as type Foo'])
+
+ self.expect("frame variable",
+ substrs = ['(Foo) f = Case45',
+ '(int) x = Case1',
+ '(int) y = Case45',
+ '(int) z = 43'
+ ]);
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
diff --git a/lldb/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp b/lldb/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp
new file mode 100644
index 00000000000..6a8074ff9fb
--- /dev/null
+++ b/lldb/test/functionalities/data-formatter/data-formatter-enum-format/main.cpp
@@ -0,0 +1,13 @@
+enum Foo {
+ Case1 = 1,
+ Case2 = 2,
+ Case45 = 45
+};
+
+int main() {
+ Foo f = Case45;
+ int x = 1;
+ int y = 45;
+ int z = 43;
+ return 1; // Set break point at this line.
+}
OpenPOWER on IntegriCloud