forked from OSchip/llvm-project
new flag -P to type synth add lets you type a Python class interactively
added a final newline to fooSynthProvider.py new option to automatically save user input in InputReaderEZ checking for NULL pointers in several new places llvm-svn: 135916
This commit is contained in:
parent
6d28d7f2a3
commit
c53114e30a
|
@ -303,7 +303,7 @@ public:
|
|||
virtual uint32_t
|
||||
CalculateNumChildren()
|
||||
{
|
||||
if (m_wrapper == NULL)
|
||||
if (m_wrapper == NULL || m_interpreter == NULL)
|
||||
return 0;
|
||||
return m_interpreter->CalculateNumChildren(m_wrapper);
|
||||
}
|
||||
|
@ -311,7 +311,7 @@ public:
|
|||
virtual lldb::ValueObjectSP
|
||||
GetChildAtIndex (uint32_t idx, bool can_create)
|
||||
{
|
||||
if (m_wrapper == NULL)
|
||||
if (m_wrapper == NULL || m_interpreter == NULL)
|
||||
return lldb::ValueObjectSP();
|
||||
|
||||
PyObject* py_return = (PyObject*)m_interpreter->GetChildAtIndex(m_wrapper, idx);
|
||||
|
@ -323,7 +323,7 @@ public:
|
|||
|
||||
lldb::SBValue *sb_ptr = m_interpreter->CastPyObjectToSBValue(py_return);
|
||||
|
||||
if (py_return == NULL)
|
||||
if (py_return == NULL || sb_ptr == NULL)
|
||||
return lldb::ValueObjectSP();
|
||||
|
||||
return sb_ptr->m_opaque_sp;
|
||||
|
@ -332,7 +332,7 @@ public:
|
|||
virtual uint32_t
|
||||
GetIndexOfChildWithName (const ConstString &name)
|
||||
{
|
||||
if (m_wrapper == NULL)
|
||||
if (m_wrapper == NULL || m_interpreter == NULL)
|
||||
return UINT32_MAX;
|
||||
return m_interpreter->GetIndexOfChildWithName(m_wrapper, name.GetCString());
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "lldb/lldb-public.h"
|
||||
#include "lldb/lldb-enumerations.h"
|
||||
#include "lldb/Core/Error.h"
|
||||
#include "lldb/Core/StringList.h"
|
||||
#include "lldb/Host/Predicate.h"
|
||||
|
||||
|
||||
|
@ -63,11 +64,13 @@ public:
|
|||
char* m_end_token;
|
||||
char* m_prompt;
|
||||
bool m_echo;
|
||||
bool m_save_user_input;
|
||||
public:
|
||||
InitializationParameters() :
|
||||
m_baton(NULL),
|
||||
m_token_size(lldb::eInputReaderGranularityLine),
|
||||
m_echo(true)
|
||||
m_echo(true),
|
||||
m_save_user_input(false)
|
||||
{
|
||||
SetEndToken("DONE");
|
||||
SetPrompt("> ");
|
||||
|
@ -80,6 +83,13 @@ public:
|
|||
return *this;
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetSaveUserInput(bool s)
|
||||
{
|
||||
m_save_user_input = s;
|
||||
return *this;
|
||||
}
|
||||
|
||||
InitializationParameters&
|
||||
SetBaton(void* b)
|
||||
{
|
||||
|
@ -191,6 +201,18 @@ public:
|
|||
{
|
||||
return m_echo;
|
||||
}
|
||||
|
||||
StringList&
|
||||
GetUserInput()
|
||||
{
|
||||
return m_user_input;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
GetSaveUserInput()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Subclasses _can_ override this function to get input as it comes in
|
||||
// without any granularity
|
||||
|
@ -239,6 +261,8 @@ protected:
|
|||
bool m_echo;
|
||||
bool m_active;
|
||||
Predicate<bool> m_reader_done;
|
||||
StringList m_user_input;
|
||||
bool m_save_user_input;
|
||||
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (InputReader);
|
||||
|
|
|
@ -75,6 +75,12 @@ public:
|
|||
virtual void
|
||||
DoneHandler(HandlerData&) {}
|
||||
|
||||
virtual bool
|
||||
GetSaveUserInput()
|
||||
{
|
||||
return m_save_user_input;
|
||||
}
|
||||
|
||||
protected:
|
||||
friend class Debugger;
|
||||
|
||||
|
|
|
@ -101,6 +101,12 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
virtual bool
|
||||
GenerateTypeSynthClass (StringList &input, StringList &output)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void*
|
||||
CreateSyntheticScriptedProvider (std::string class_name,
|
||||
lldb::ValueObjectSP valobj)
|
||||
|
|
|
@ -52,6 +52,9 @@ public:
|
|||
bool
|
||||
GenerateTypeScriptFunction (StringList &input, StringList &output);
|
||||
|
||||
bool
|
||||
GenerateTypeSynthClass (StringList &input, StringList &output);
|
||||
|
||||
// use this if the function code is just a one-liner script
|
||||
bool
|
||||
GenerateTypeScriptFunction (const char* oneliner, StringList &output);
|
||||
|
|
|
@ -691,7 +691,6 @@ CommandObjectTypeSummaryAdd::CollectPythonScript (ScriptAddOptions *options,
|
|||
result.AppendError("out of memory");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -2372,6 +2371,148 @@ CommandObjectTypeSynthClear::CommandOptions::g_option_table[] =
|
|||
// CommandObjectTypeSynthAdd
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
static const char *g_synth_addreader_instructions = "Enter your Python command(s). Type 'DONE' to end.\n"
|
||||
"You must define a Python class with three methods:\n"
|
||||
"def __init__(self, valobj, dict):\n"
|
||||
"def get_child_at_index(self, index):\n"
|
||||
"def get_child_index(self, name):\n"
|
||||
"class synthProvider:";
|
||||
|
||||
class TypeSynthAddInputReader : public InputReaderEZ
|
||||
{
|
||||
private:
|
||||
DISALLOW_COPY_AND_ASSIGN (TypeSynthAddInputReader);
|
||||
public:
|
||||
TypeSynthAddInputReader(Debugger& debugger) :
|
||||
InputReaderEZ(debugger)
|
||||
{}
|
||||
|
||||
virtual
|
||||
~TypeSynthAddInputReader()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void ActivateHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
bool batch_mode = data.GetBatchMode();
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s\n", g_synth_addreader_instructions);
|
||||
if (data.reader.GetPrompt())
|
||||
out_stream->Printf ("%s", data.reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void ReactivateHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
bool batch_mode = data.GetBatchMode();
|
||||
if (data.reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", data.reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
virtual void GotTokenHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
bool batch_mode = data.GetBatchMode();
|
||||
if (data.bytes && data.bytes_len && data.baton)
|
||||
{
|
||||
((SynthAddOptions*)data.baton)->m_user_source.AppendString(data.bytes, data.bytes_len);
|
||||
}
|
||||
if (!data.reader.IsDone() && data.reader.GetPrompt() && !batch_mode)
|
||||
{
|
||||
out_stream->Printf ("%s", data.reader.GetPrompt());
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
virtual void InterruptHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
bool batch_mode = data.GetBatchMode();
|
||||
data.reader.SetIsDone (true);
|
||||
if (!batch_mode)
|
||||
{
|
||||
out_stream->Printf ("Warning: No command attached to breakpoint.\n");
|
||||
out_stream->Flush();
|
||||
}
|
||||
}
|
||||
virtual void EOFHandler(HandlerData& data)
|
||||
{
|
||||
data.reader.SetIsDone (true);
|
||||
}
|
||||
virtual void DoneHandler(HandlerData& data)
|
||||
{
|
||||
StreamSP out_stream = data.GetOutStream();
|
||||
SynthAddOptions *options_ptr = ((SynthAddOptions*)data.baton);
|
||||
if (!options_ptr)
|
||||
{
|
||||
out_stream->Printf ("Internal error #1: no script attached.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
|
||||
SynthAddOptions::SharedPointer options(options_ptr); // this will ensure that we get rid of the pointer when going out of scope
|
||||
|
||||
ScriptInterpreter *interpreter = data.reader.GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
|
||||
if (!interpreter)
|
||||
{
|
||||
out_stream->Printf ("Internal error #2: no script attached.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
StringList class_name_sl;
|
||||
if (!interpreter->GenerateTypeSynthClass (options->m_user_source,
|
||||
class_name_sl))
|
||||
{
|
||||
out_stream->Printf ("Internal error #3: no script attached.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
if (class_name_sl.GetSize() == 0)
|
||||
{
|
||||
out_stream->Printf ("Internal error #4: no script attached.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
const char *class_name = class_name_sl.GetStringAtIndex(0);
|
||||
if (!class_name || !class_name[0])
|
||||
{
|
||||
out_stream->Printf ("Internal error #5: no script attached.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
|
||||
// everything should be fine now, let's add the synth provider class
|
||||
|
||||
SyntheticChildrenSP synth_provider;
|
||||
synth_provider.reset(new SyntheticScriptProvider(options->m_cascade,
|
||||
options->m_skip_pointers,
|
||||
options->m_skip_references,
|
||||
std::string(class_name)));
|
||||
|
||||
|
||||
lldb::FormatCategorySP category;
|
||||
Debugger::Formatting::Categories::Get(ConstString(options->m_category), category);
|
||||
|
||||
for (size_t i = 0; i < options->m_target_types.GetSize(); i++) {
|
||||
const char *type_name = options->m_target_types.GetStringAtIndex(i);
|
||||
ConstString typeCS(type_name);
|
||||
if (typeCS)
|
||||
category->Filter()->Add(typeCS.GetCString(), synth_provider);
|
||||
else
|
||||
{
|
||||
out_stream->Printf ("Internal error #6: no script attached.\n");
|
||||
out_stream->Flush();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CommandObjectTypeSynthAdd : public CommandObject
|
||||
{
|
||||
|
||||
|
@ -2406,6 +2547,10 @@ private:
|
|||
break;
|
||||
case 'c':
|
||||
m_expr_paths.push_back(option_arg);
|
||||
has_child_list = true;
|
||||
break;
|
||||
case 'P':
|
||||
handwrite_python = true;
|
||||
break;
|
||||
case 'l':
|
||||
m_class_name = std::string(option_arg);
|
||||
|
@ -2438,6 +2583,8 @@ private:
|
|||
m_category = NULL;
|
||||
m_expr_paths.clear();
|
||||
is_class_based = false;
|
||||
handwrite_python = false;
|
||||
has_child_list = false;
|
||||
}
|
||||
|
||||
const OptionDefinition*
|
||||
|
@ -2462,6 +2609,10 @@ private:
|
|||
|
||||
bool is_class_based;
|
||||
|
||||
bool handwrite_python;
|
||||
|
||||
bool has_child_list;
|
||||
|
||||
typedef option_vector::iterator ExpressionPathsIterator;
|
||||
};
|
||||
|
||||
|
@ -2473,6 +2624,61 @@ private:
|
|||
return &m_options;
|
||||
}
|
||||
|
||||
void
|
||||
CollectPythonScript (SynthAddOptions *options,
|
||||
CommandReturnObject &result)
|
||||
{
|
||||
InputReaderSP reader_sp (new TypeSynthAddInputReader(m_interpreter.GetDebugger()));
|
||||
if (reader_sp && options)
|
||||
{
|
||||
|
||||
InputReaderEZ::InitializationParameters ipr;
|
||||
|
||||
Error err (reader_sp->Initialize (ipr.SetBaton(options).SetPrompt(" ")));
|
||||
if (err.Success())
|
||||
{
|
||||
m_interpreter.GetDebugger().PushInputReader (reader_sp);
|
||||
result.SetStatus (eReturnStatusSuccessFinishNoResult);
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError (err.AsCString());
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result.AppendError("out of memory");
|
||||
result.SetStatus (eReturnStatusFailed);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Execute_HandwritePython (Args& command, CommandReturnObject &result)
|
||||
{
|
||||
SynthAddOptions *options = new SynthAddOptions ( m_options.m_skip_pointers,
|
||||
m_options.m_skip_references,
|
||||
m_options.m_cascade,
|
||||
m_options.m_category);
|
||||
|
||||
const size_t argc = command.GetArgumentCount();
|
||||
|
||||
for (size_t i = 0; i < argc; i++) {
|
||||
const char* typeA = command.GetArgumentAtIndex(i);
|
||||
if (typeA && *typeA)
|
||||
options->m_target_types << typeA;
|
||||
else
|
||||
{
|
||||
result.AppendError("empty typenames not allowed");
|
||||
result.SetStatus(eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
CollectPythonScript(options,result);
|
||||
return result.Succeeded();
|
||||
}
|
||||
|
||||
bool
|
||||
Execute_ChildrenList (Args& command, CommandReturnObject &result)
|
||||
{
|
||||
|
@ -2606,10 +2812,18 @@ public:
|
|||
bool
|
||||
Execute (Args& command, CommandReturnObject &result)
|
||||
{
|
||||
if (m_options.is_class_based)
|
||||
if (m_options.handwrite_python)
|
||||
return Execute_HandwritePython(command, result);
|
||||
else if (m_options.is_class_based)
|
||||
return Execute_PythonClass(command, result);
|
||||
else
|
||||
else if (m_options.has_child_list)
|
||||
return Execute_ChildrenList(command, result);
|
||||
else
|
||||
{
|
||||
result.AppendError("must either provide a children list, a Python class name, or use -P and type a Python class line-by-line");
|
||||
result.SetStatus(eReturnStatusFailed);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -2622,6 +2836,7 @@ CommandObjectTypeSynthAdd::CommandOptions::g_option_table[] =
|
|||
{ LLDB_OPT_SET_ALL, false, "category", 'w', required_argument, NULL, 0, eArgTypeName, "Add this to the given category instead of the default one."},
|
||||
{ LLDB_OPT_SET_1, false, "child", 'c', required_argument, NULL, 0, eArgTypeName, "Include this expression path in the synthetic view."},
|
||||
{ LLDB_OPT_SET_2, false, "python-class", 'l', required_argument, NULL, 0, eArgTypeName, "Use this Python class to produce synthetic children."},
|
||||
{ LLDB_OPT_SET_3, false, "input-python", 'P', no_argument, NULL, 0, eArgTypeBoolean, "Type Python code to generate a class that provides synthetic children."},
|
||||
{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -70,6 +70,37 @@ public:
|
|||
|
||||
};
|
||||
|
||||
class SynthAddOptions
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
bool m_skip_pointers;
|
||||
bool m_skip_references;
|
||||
bool m_cascade;
|
||||
StringList m_user_source;
|
||||
StringList m_target_types;
|
||||
|
||||
const char* m_category;
|
||||
|
||||
SynthAddOptions(bool sptr,
|
||||
bool sref,
|
||||
bool casc,
|
||||
const char* catg) :
|
||||
m_skip_pointers(sptr),
|
||||
m_skip_references(sref),
|
||||
m_cascade(casc),
|
||||
m_user_source(),
|
||||
m_target_types(),
|
||||
m_category(catg)
|
||||
{
|
||||
}
|
||||
|
||||
typedef lldb::SharedPtr<SynthAddOptions>::Type SharedPointer;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class CommandObjectType : public CommandObjectMultiword
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -164,15 +164,26 @@ SyntheticScriptProvider::FrontEnd::FrontEnd(std::string pclass,
|
|||
SyntheticChildrenFrontEnd(be),
|
||||
m_python_class(pclass)
|
||||
{
|
||||
if (be.get() == NULL)
|
||||
{
|
||||
m_interpreter = NULL;
|
||||
m_wrapper = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
m_interpreter = be->GetUpdatePoint().GetTarget()->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
|
||||
m_wrapper = (PyObject*)m_interpreter->CreateSyntheticScriptedProvider(m_python_class, m_backend);
|
||||
|
||||
if (m_interpreter == NULL)
|
||||
m_wrapper = NULL;
|
||||
else
|
||||
m_wrapper = (PyObject*)m_interpreter->CreateSyntheticScriptedProvider(m_python_class, m_backend);
|
||||
}
|
||||
|
||||
std::string
|
||||
SyntheticScriptProvider::GetDescription()
|
||||
{
|
||||
StreamString sstr;
|
||||
sstr.Printf("%s%s%s Python class: %s",
|
||||
sstr.Printf("%s%s%s Python class %s",
|
||||
m_cascades ? "" : " (not cascading)",
|
||||
m_skip_pointers ? " (skip pointers)" : "",
|
||||
m_skip_references ? " (skip references)" : "",
|
||||
|
|
|
@ -25,7 +25,9 @@ InputReader::InputReader (Debugger &debugger) :
|
|||
m_done (true),
|
||||
m_echo (true),
|
||||
m_active (false),
|
||||
m_reader_done (false)
|
||||
m_reader_done (false),
|
||||
m_user_input(),
|
||||
m_save_user_input(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,11 @@ InputReaderEZ::Callback_Impl(void *baton,
|
|||
reader.AsynchronousOutputWrittenHandler(hand_data);
|
||||
break;
|
||||
case eInputReaderGotToken:
|
||||
{
|
||||
if (reader.GetSaveUserInput())
|
||||
reader.GetUserInput().AppendString(bytes, bytes_len);
|
||||
reader.GotTokenHandler(hand_data);
|
||||
}
|
||||
break;
|
||||
case eInputReaderInterrupt:
|
||||
reader.InterruptHandler(hand_data);
|
||||
|
@ -78,11 +82,13 @@ InputReaderEZ::Initialize(void* baton,
|
|||
Error
|
||||
InputReaderEZ::Initialize(InitializationParameters& params)
|
||||
{
|
||||
return Initialize(params.m_baton,
|
||||
params.m_token_size,
|
||||
params.m_end_token,
|
||||
params.m_prompt,
|
||||
params.m_echo);
|
||||
Error ret = Initialize(params.m_baton,
|
||||
params.m_token_size,
|
||||
params.m_end_token,
|
||||
params.m_prompt,
|
||||
params.m_echo);
|
||||
m_save_user_input = params.m_save_user_input;
|
||||
return ret;
|
||||
}
|
||||
|
||||
InputReaderEZ::~InputReaderEZ ()
|
||||
|
|
|
@ -131,7 +131,7 @@ ValueObjectSynthetic::GetChildAtIndex (uint32_t idx, bool can_create)
|
|||
|
||||
if (iter == m_children_byindex.end())
|
||||
{
|
||||
if (can_create)
|
||||
if (can_create && m_synth_filter != NULL)
|
||||
{
|
||||
lldb::ValueObjectSP synth_guy = m_synth_filter->GetChildAtIndex (idx, can_create);
|
||||
m_children_byindex[idx]= synth_guy;
|
||||
|
@ -161,13 +161,16 @@ ValueObjectSynthetic::GetIndexOfChildWithName (const ConstString &name)
|
|||
{
|
||||
NameToIndexIterator iter = m_name_toindex.find(name.GetCString());
|
||||
|
||||
if (iter == m_name_toindex.end())
|
||||
if (iter == m_name_toindex.end() && m_synth_filter != NULL)
|
||||
{
|
||||
uint32_t index = m_synth_filter->GetIndexOfChildWithName (name);
|
||||
m_name_toindex[name.GetCString()] = index;
|
||||
return index;
|
||||
}
|
||||
return iter->second;
|
||||
else if (iter == m_name_toindex.end() && m_synth_filter == NULL)
|
||||
return UINT32_MAX;
|
||||
else /*if (iter != m_name_toindex.end())*/
|
||||
return iter->second;
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
@ -1249,6 +1249,54 @@ ScriptInterpreterPython::GenerateTypeScriptFunction (StringList &user_input, Str
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ScriptInterpreterPython::GenerateTypeSynthClass (StringList &user_input, StringList &output)
|
||||
{
|
||||
static int num_created_classes = 0;
|
||||
user_input.RemoveBlankLines ();
|
||||
int num_lines = user_input.GetSize ();
|
||||
StreamString sstr;
|
||||
|
||||
// Check to see if we have any data; if not, just return.
|
||||
if (user_input.GetSize() == 0)
|
||||
return false;
|
||||
|
||||
// Wrap all user input into a Python class
|
||||
|
||||
sstr.Printf ("lldb_autogen_python_type_synth_class_%d", num_created_classes);
|
||||
++num_created_classes;
|
||||
std::string auto_generated_class_name = sstr.GetData();
|
||||
|
||||
sstr.Clear();
|
||||
StringList auto_generated_class;
|
||||
|
||||
// Create the function name & definition string.
|
||||
|
||||
sstr.Printf ("class %s:", auto_generated_class_name.c_str());
|
||||
auto_generated_class.AppendString (sstr.GetData());
|
||||
|
||||
// Wrap everything up inside the class, increasing the indentation.
|
||||
|
||||
for (int i = 0; i < num_lines; ++i)
|
||||
{
|
||||
sstr.Clear ();
|
||||
sstr.Printf (" %s", user_input.GetStringAtIndex (i));
|
||||
auto_generated_class.AppendString (sstr.GetData());
|
||||
}
|
||||
|
||||
|
||||
// Verify that the results are valid Python.
|
||||
// (even though the method is ExportFunctionDefinitionToInterpreter, a class will actually be exported)
|
||||
// (TODO: rename that method to ExportDefinitionToInterpreter)
|
||||
if (!ExportFunctionDefinitionToInterpreter (auto_generated_class))
|
||||
return false;
|
||||
|
||||
// Store the name of the auto-generated class
|
||||
|
||||
output.AppendString (auto_generated_class_name.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
void*
|
||||
ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name,
|
||||
lldb::ValueObjectSP valobj)
|
||||
|
|
|
@ -13,4 +13,4 @@ class fooSynthProvider:
|
|||
if name == 'a':
|
||||
return 1;
|
||||
else:
|
||||
return 0;
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue