[Lldb-commits] [lldb] r249047 - Add a 'type lookup' command. This command is meant to look up type information by name in a language-specific way.
Zachary Turner via lldb-commits
lldb-commits at lists.llvm.org
Thu Oct 1 12:49:01 PDT 2015
Hi Enrico,
Could you add some tests for this? python API tests and appropriate
methods added to SBTarget would be ideal.
On Thu, Oct 1, 2015 at 11:17 AM Enrico Granata via lldb-commits <
lldb-commits at lists.llvm.org> wrote:
> Author: enrico
> Date: Thu Oct 1 13:16:18 2015
> New Revision: 249047
>
> URL: http://llvm.org/viewvc/llvm-project?rev=249047&view=rev
> Log:
> Add a 'type lookup' command. This command is meant to look up type
> information by name in a language-specific way.
>
> Currently, it only supports Objective-C - C++ types can be looked up
> through debug info via 'image lookup -t', whereas ObjC types via this
> command are looked up by runtime introspection
>
> This behavior is in line with type lookup's behavior in Xcode 7, but I am
> definitely open to feedback as to what makes the most sense here
>
>
> Modified:
> lldb/trunk/include/lldb/Target/Language.h
> lldb/trunk/source/Commands/CommandObjectType.cpp
> lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.cpp
> lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.h
> lldb/trunk/source/Target/Language.cpp
>
> Modified: lldb/trunk/include/lldb/Target/Language.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Language.h?rev=249047&r1=249046&r2=249047&view=diff
>
> ==============================================================================
> --- lldb/trunk/include/lldb/Target/Language.h (original)
> +++ lldb/trunk/include/lldb/Target/Language.h Thu Oct 1 13:16:18 2015
> @@ -13,6 +13,8 @@
> // C Includes
> // C++ Includes
> #include <functional>
> +#include <memory>
> +#include <set>
> #include <vector>
>
> // Other libraries and framework includes
> @@ -29,6 +31,42 @@ class Language :
> public PluginInterface
> {
> public:
> +
> + class TypeScavenger
> + {
> + public:
> + class Result
> + {
> + public:
> + virtual bool
> + IsValid () = 0;
> +
> + virtual bool
> + DumpToStream (Stream& stream,
> + bool print_help_if_available) = 0;
> +
> + virtual ~Result() = default;
> + };
> +
> + typedef std::set<std::unique_ptr<Result>> ResultSet;
> +
> + virtual ~TypeScavenger () = default;
> +
> + size_t
> + Find (ExecutionContextScope *exe_scope,
> + const char *key,
> + ResultSet &results,
> + bool append = true);
> +
> + protected:
> + TypeScavenger () = default;
> +
> + virtual bool
> + Find_Impl (ExecutionContextScope *exe_scope,
> + const char *key,
> + ResultSet &results) = 0;
> + };
> +
> ~Language() override;
>
> static Language*
> @@ -65,6 +103,9 @@ public:
> virtual lldb_private::formatters::StringPrinter::EscapingHelper
> GetStringPrinterEscapingHelper
> (lldb_private::formatters::StringPrinter::GetPrintableElementType);
>
> + virtual std::unique_ptr<TypeScavenger>
> + GetTypeScavenger ();
> +
> // These are accessors for general information about the Languages
> lldb knows about:
>
> static lldb::LanguageType
> @@ -91,7 +132,6 @@ public:
>
> static bool
> LanguageIsPascal (lldb::LanguageType language);
> -
>
> protected:
> //------------------------------------------------------------------
>
> Modified: lldb/trunk/source/Commands/CommandObjectType.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectType.cpp?rev=249047&r1=249046&r2=249047&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/Commands/CommandObjectType.cpp (original)
> +++ lldb/trunk/source/Commands/CommandObjectType.cpp Thu Oct 1 13:16:18
> 2015
> @@ -4558,6 +4558,218 @@ CommandObjectTypeFilterAdd::CommandOptio
> { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
> };
>
> +//----------------------------------------------------------------------
> +// "type lookup"
> +//----------------------------------------------------------------------
> +class CommandObjectTypeLookup : public CommandObjectRaw
> +{
> +protected:
> +
> + class CommandOptions : public OptionGroup
> + {
> + public:
> +
> + CommandOptions () :
> + OptionGroup(),
> + m_show_help(false),
> + m_language(eLanguageTypeUnknown)
> + {}
> +
> + virtual
> + ~CommandOptions () {}
> +
> + virtual uint32_t
> + GetNumDefinitions ()
> + {
> + return 3;
> + }
> +
> + virtual const OptionDefinition*
> + GetDefinitions ()
> + {
> + return g_option_table;
> + }
> +
> + virtual Error
> + SetOptionValue (CommandInterpreter &interpreter,
> + uint32_t option_idx,
> + const char *option_value)
> + {
> + Error error;
> +
> + const int short_option =
> g_option_table[option_idx].short_option;
> +
> + switch (short_option)
> + {
> + case 'h':
> + m_show_help = true;
> + break;
> +
> + case 'l':
> + m_language =
> Language::GetLanguageTypeFromString(option_value);
> + break;
> +
> + default:
> + error.SetErrorStringWithFormat("invalid short option
> character '%c'", short_option);
> + break;
> + }
> +
> + return error;
> + }
> +
> + virtual void
> + OptionParsingStarting (CommandInterpreter &interpreter)
> + {
> + m_show_help = false;
> + m_language = eLanguageTypeUnknown;
> + }
> +
> + // Options table: Required for subclasses of Options.
> +
> + static OptionDefinition g_option_table[];
> + bool m_show_help;
> + lldb::LanguageType m_language;
> + };
> +
> + OptionGroupOptions m_option_group;
> + CommandOptions m_command_options;
> +
> +public:
> +
> + CommandObjectTypeLookup (CommandInterpreter &interpreter) :
> + CommandObjectRaw (interpreter,
> + "type lookup",
> + "Lookup a type by name in the select target.",
> + "type lookup <typename>",
> + eCommandRequiresTarget),
> + m_option_group(interpreter),
> + m_command_options()
> + {
> + m_option_group.Append(&m_command_options);
> + m_option_group.Finalize();
> + }
> +
> + virtual
> + ~CommandObjectTypeLookup ()
> + {
> + }
> +
> + virtual
> + Options *
> + GetOptions ()
> + {
> + return &m_option_group;
> + }
> +
> + virtual bool
> + DoExecute (const char *raw_command_line, CommandReturnObject &result)
> + {
> + if (!raw_command_line || !raw_command_line[0])
> + {
> + result.SetError("type lookup cannot be invoked without a type
> name as argument");
> + return false;
> + }
> +
> + m_option_group.NotifyOptionParsingStarting();
> +
> + const char * name_of_type = NULL;
> +
> + if (raw_command_line[0] == '-')
> + {
> + // We have some options and these options MUST end with --.
> + const char *end_options = NULL;
> + const char *s = raw_command_line;
> + while (s && s[0])
> + {
> + end_options = ::strstr (s, "--");
> + if (end_options)
> + {
> + end_options += 2; // Get past the "--"
> + if (::isspace (end_options[0]))
> + {
> + name_of_type = end_options;
> + while (::isspace (*name_of_type))
> + ++name_of_type;
> + break;
> + }
> + }
> + s = end_options;
> + }
> +
> + if (end_options)
> + {
> + Args args (llvm::StringRef(raw_command_line, end_options
> - raw_command_line));
> + if (!ParseOptions (args, result))
> + return false;
> +
> + Error error
> (m_option_group.NotifyOptionParsingFinished());
> + if (error.Fail())
> + {
> + result.AppendError (error.AsCString());
> + result.SetStatus (eReturnStatusFailed);
> + return false;
> + }
> + }
> + }
> + if (nullptr == name_of_type)
> + name_of_type = raw_command_line;
> +
> + TargetSP
> target_sp(GetCommandInterpreter().GetDebugger().GetSelectedTarget());
> + const bool fill_all_in = true;
> + ExecutionContext exe_ctx(target_sp.get(), fill_all_in);
> + ExecutionContextScope *best_scope =
> exe_ctx.GetBestExecutionContextScope();
> +
> + bool any_found = false;
> +
> + std::vector<Language*> languages;
> +
> + if (m_command_options.m_language == eLanguageTypeUnknown)
> + {
> + // FIXME: hardcoding languages is not good
> + languages.push_back(Language::FindPlugin(eLanguageTypeObjC));
> +
> languages.push_back(Language::FindPlugin(eLanguageTypeC_plus_plus));
> + }
> + else
> + {
> +
> languages.push_back(Language::FindPlugin(m_command_options.m_language));
> + }
> +
> + for (Language* language : languages)
> + {
> + if (!language)
> + continue;
> +
> + if (auto scavenger = language->GetTypeScavenger())
> + {
> + Language::TypeScavenger::ResultSet search_results;
> + if (scavenger->Find(best_scope, name_of_type,
> search_results) > 0)
> + {
> + for (const auto& search_result : search_results)
> + {
> + if (search_result && search_result->IsValid())
> + {
> + any_found = true;
> +
> search_result->DumpToStream(result.GetOutputStream(),
> this->m_command_options.m_show_help);
> + }
> + }
> + }
> + }
> + }
> +
> + result.SetStatus (any_found ?
> lldb::eReturnStatusSuccessFinishResult :
> lldb::eReturnStatusSuccessFinishNoResult);
> + return true;
> + }
> +
> +};
> +
> +OptionDefinition
> +CommandObjectTypeLookup::CommandOptions::g_option_table[] =
> +{
> + { LLDB_OPT_SET_ALL, false, "show-help", 'h',
> OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display
> available help for types"},
> + { LLDB_OPT_SET_ALL, false, "language", 'l',
> OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLanguage, "Which
> language's types should the search scope be"},
> + { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
> +};
> +
> template <typename FormatterType>
> class CommandObjectFormatterInfo : public CommandObjectRaw
> {
> @@ -4778,6 +4990,7 @@ CommandObjectType::CommandObjectType (Co
> #ifndef LLDB_DISABLE_PYTHON
> LoadSubCommand ("synthetic", CommandObjectSP (new
> CommandObjectTypeSynth (interpreter)));
> #endif
> + LoadSubCommand ("lookup", CommandObjectSP (new
> CommandObjectTypeLookup (interpreter)));
> }
>
>
>
> Modified: lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.cpp?rev=249047&r1=249046&r2=249047&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.cpp (original)
> +++ lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.cpp Thu Oct 1
> 13:16:18 2015
> @@ -656,3 +656,91 @@ ObjCLanguage::GetPossibleFormattersMatch
>
> return result;
> }
> +
> +std::unique_ptr<Language::TypeScavenger>
> +ObjCLanguage::GetTypeScavenger ()
> +{
> + class ObjCTypeScavenger : public Language::TypeScavenger
> + {
> + private:
> + class ObjCScavengerResult : public Language::TypeScavenger::Result
> + {
> + public:
> + ObjCScavengerResult (CompilerType type) :
> + Language::TypeScavenger::Result(),
> + m_compiler_type(type)
> + {
> + }
> +
> + bool
> + IsValid () override
> + {
> + return m_compiler_type.IsValid();
> + }
> +
> + bool
> + DumpToStream (Stream& stream,
> + bool print_help_if_available) override
> + {
> + if (IsValid())
> + {
> + m_compiler_type.DumpTypeDescription(&stream);
> + stream.EOL();
> + return true;
> + }
> + return false;
> + }
> +
> + virtual ~ObjCScavengerResult() = default;
> + private:
> + CompilerType m_compiler_type;
> + };
> +
> + protected:
> + ObjCTypeScavenger() = default;
> +
> + virtual ~ObjCTypeScavenger() = default;
> +
> + bool
> + Find_Impl (ExecutionContextScope *exe_scope,
> + const char *key,
> + ResultSet &results) override
> + {
> + bool result = false;
> +
> + Process* process = exe_scope->CalculateProcess().get();
> + if (process)
> + {
> + const bool create_on_demand = false;
> + auto objc_runtime =
> process->GetObjCLanguageRuntime(create_on_demand);
> + if (objc_runtime)
> + {
> + auto decl_vendor = objc_runtime->GetDeclVendor();
> + if (decl_vendor)
> + {
> + std::vector<clang::NamedDecl *> decls;
> + ConstString name(key);
> + decl_vendor->FindDecls(name, true, UINT32_MAX,
> decls);
> + for (auto decl : decls)
> + {
> + if (decl)
> + {
> + if (CompilerType candidate =
> ClangASTContext::GetTypeForDecl(decl))
> + {
> + result = true;
> +
> std::unique_ptr<Language::TypeScavenger::Result> result(new
> ObjCScavengerResult(candidate));
> + results.insert(std::move(result));
> + }
> + }
> + }
> + }
> + }
> + }
> + return result;
> + }
> +
> + friend class ObjCLanguage;
> + };
> +
> + return std::unique_ptr<TypeScavenger>(new ObjCTypeScavenger());
> +}
>
> Modified: lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.h
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.h?rev=249047&r1=249046&r2=249047&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.h (original)
> +++ lldb/trunk/source/Plugins/Language/ObjC/ObjCLanguage.h Thu Oct 1
> 13:16:18 2015
> @@ -146,6 +146,9 @@ public:
> std::vector<ConstString>
> GetPossibleFormattersMatches (ValueObject& valobj,
> lldb::DynamicValueType use_dynamic) override;
>
> + std::unique_ptr<TypeScavenger>
> + GetTypeScavenger () override;
> +
> //------------------------------------------------------------------
> // Static Functions
> //------------------------------------------------------------------
>
> Modified: lldb/trunk/source/Target/Language.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Language.cpp?rev=249047&r1=249046&r2=249047&view=diff
>
> ==============================================================================
> --- lldb/trunk/source/Target/Language.cpp (original)
> +++ lldb/trunk/source/Target/Language.cpp Thu Oct 1 13:16:18 2015
> @@ -287,6 +287,34 @@ Language::LanguageIsPascal (LanguageType
> }
> }
>
> +std::unique_ptr<Language::TypeScavenger>
> +Language::GetTypeScavenger ()
> +{
> + return nullptr;
> +}
> +
> +size_t
> +Language::TypeScavenger::Find (ExecutionContextScope *exe_scope,
> + const char *key,
> + ResultSet &results,
> + bool append)
> +{
> + if (!exe_scope || !exe_scope->CalculateTarget().get())
> + return false;
> +
> + if (!key || !key[0])
> + return false;
> +
> + if (!append)
> + results.clear();
> +
> + size_t old_size = results.size();
> +
> + if (this->Find_Impl(exe_scope, key, results))
> + return results.size() - old_size;
> + return 0;
> +}
> +
> //----------------------------------------------------------------------
> // Constructor
> //----------------------------------------------------------------------
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20151001/b1ee51cd/attachment-0001.html>
More information about the lldb-commits
mailing list