[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 13:15:51 PDT 2015


I see there's SBType, does this represent something different?  I was
thinking you could make a method like

SBType *
SBTarget::LookupType(const char* type_name, eLanguage lang);

Even if it didn't support every possible usage of the "type lookup"
command, it would be a start.

At one point on the list it was discussed whether tests which use runCmd
and then matching the output should be separated from the rest of the test
suite, so there's a more clearly enforced distinction about which tests use
the command API and which tests use the python API.  At least Jim thought
that was a good idea and supported the move, but nobody else really chimed
in.  If you agree, maybe you could be the first?  :)  Something like
lldb/test/commands/type-lookup.  Eventually the goal would just be to have
3 top level directories,

lldb
|__test
    |__commands
    |__python-api
    |__unit-tests

With the existing sub-trees divided up accordingly between the 3.   (This
is all assuming of course that making the SBTarget::LookupType method I
suggested earlier doesn't work for some reason)

On Thu, Oct 1, 2015 at 1:01 PM Enrico Granata <egranata at apple.com> wrote:

> On Oct 1, 2015, at 12:49 PM, Zachary Turner <zturner at google.com> wrote:
>
> Hi Enrico,
>
> Could you add some tests for this?
>
>
> Sure. I am still churning through a thing or two before declaring victory,
> but I can add tests as I make progress
>
>  python API tests and appropriate methods added to SBTarget
>
>
> There currently is no SB API component to this. It is a purely
> command-line facility.
> If you feel it would be useful to have SB API for this, it will need to be
> designed (e.g. “type lookup” is allowed to transact in things that are not
> strictly speaking compiler types - we have no API way to represent this
> kind of concept)
>
> 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
>>
>
>
> Thanks,
> *- Enrico*
> 📩 egranata@.com ☎️ 27683
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-commits/attachments/20151001/2ec73d15/attachment-0001.html>


More information about the lldb-commits mailing list