[Lldb-commits] [lldb] r363183 - [Expression] Add PersistentExpressionState::GetCompilerTypeFromPersistentDecl

Alex Langford via lldb-commits lldb-commits at lists.llvm.org
Wed Jun 12 10:47:07 PDT 2019


Author: xiaobai
Date: Wed Jun 12 10:47:06 2019
New Revision: 363183

URL: http://llvm.org/viewvc/llvm-project?rev=363183&view=rev
Log:
[Expression] Add PersistentExpressionState::GetCompilerTypeFromPersistentDecl

Summary:
PersistentStateExpressions (e.g. ClangPersistentVariables) have the
ability to define types using expressions that persist throughout the
debugging session. GetCompilerTypeFromPersistentDecl is a useful
operation to have if you need to use any of those persistently declared types,
like in CommandObjectMemory.

This decouples clang from CommandObjectMemory and decouples Plugins from
Commands in general.

Differential Revision: https://reviews.llvm.org/D62797

Modified:
    lldb/trunk/include/lldb/Expression/ExpressionVariable.h
    lldb/trunk/packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py
    lldb/trunk/source/Commands/CMakeLists.txt
    lldb/trunk/source/Commands/CommandObjectMemory.cpp
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
    lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h

Modified: lldb/trunk/include/lldb/Expression/ExpressionVariable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ExpressionVariable.h?rev=363183&r1=363182&r2=363183&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/ExpressionVariable.h (original)
+++ lldb/trunk/include/lldb/Expression/ExpressionVariable.h Wed Jun 12 10:47:06 2019
@@ -232,6 +232,9 @@ public:
   virtual void
   RemovePersistentVariable(lldb::ExpressionVariableSP variable) = 0;
 
+  virtual llvm::Optional<CompilerType>
+  GetCompilerTypeFromPersistentDecl(ConstString type_name) = 0;
+
   virtual lldb::addr_t LookupSymbol(ConstString name);
 
   void RegisterExecutionUnit(lldb::IRExecutionUnitSP &execution_unit_sp);

Modified: lldb/trunk/packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py?rev=363183&r1=363182&r2=363183&view=diff
==============================================================================
--- lldb/trunk/packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py (original)
+++ lldb/trunk/packages/Python/lldbsuite/test/expression_command/persistent_types/TestPersistentTypes.py Wed Jun 12 10:47:06 2019
@@ -56,6 +56,16 @@ class PersistenttypesTestCase(TestBase):
                 "d = 'l'"])  # persistent types are OK to use for memory read
 
         self.expect(
+            "memory read foo -t $foobar -x c",
+            substrs=[
+                '($foobar) 0x',
+                ' = ',
+                "a = 'H'",
+                "b = 'e'",
+                "c = 'l'",
+                "d = 'l'"])  # persistent types are OK to use for memory read
+
+        self.expect(
             "memory read foo -t foobar",
             substrs=[
                 '($foobar) 0x',

Modified: lldb/trunk/source/Commands/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CMakeLists.txt?rev=363183&r1=363182&r2=363183&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CMakeLists.txt (original)
+++ lldb/trunk/source/Commands/CMakeLists.txt Wed Jun 12 10:47:06 2019
@@ -41,7 +41,6 @@ add_lldb_library(lldbCommands
     lldbSymbol
     lldbTarget
     lldbUtility
-    lldbPluginExpressionParserClang
 
   LINK_COMPONENTS
     Support

Modified: lldb/trunk/source/Commands/CommandObjectMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectMemory.cpp?rev=363183&r1=363182&r2=363183&view=diff
==============================================================================
--- lldb/trunk/source/Commands/CommandObjectMemory.cpp (original)
+++ lldb/trunk/source/Commands/CommandObjectMemory.cpp Wed Jun 12 10:47:06 2019
@@ -6,16 +6,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "clang/AST/Decl.h"
-
 #include "CommandObjectMemory.h"
-#include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h"
 #include "lldb/Core/Debugger.h"
 #include "lldb/Core/DumpDataExtractor.h"
 #include "lldb/Core/Module.h"
 #include "lldb/Core/Section.h"
 #include "lldb/Core/ValueObjectMemory.h"
 #include "lldb/DataFormatters/ValueObjectPrinter.h"
+#include "lldb/Expression/ExpressionVariable.h"
 #include "lldb/Host/OptionParser.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandReturnObject.h"
@@ -23,15 +21,17 @@
 #include "lldb/Interpreter/OptionGroupFormat.h"
 #include "lldb/Interpreter/OptionGroupOutputFile.h"
 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
+#include "lldb/Interpreter/OptionValueLanguage.h"
 #include "lldb/Interpreter/OptionValueString.h"
 #include "lldb/Interpreter/Options.h"
-#include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Symbol/SymbolFile.h"
 #include "lldb/Symbol/TypeList.h"
+#include "lldb/Target/Language.h"
 #include "lldb/Target/MemoryHistory.h"
 #include "lldb/Target/MemoryRegionInfo.h"
 #include "lldb/Target/Process.h"
 #include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 #include "lldb/Utility/Args.h"
 #include "lldb/Utility/DataBufferHeap.h"
@@ -51,7 +51,9 @@ static constexpr OptionDefinition g_read
   {LLDB_OPT_SET_1, false, "num-per-line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNumberPerLine, "The number of items per line to display." },
   {LLDB_OPT_SET_2, false, "binary",       'b', OptionParser::eNoArgument,       nullptr, {}, 0, eArgTypeNone,          "If true, memory will be saved as binary. If false, the memory is saved save as an ASCII dump that "
                                                                                                                             "uses the format, size, count and number per line settings." },
-  {LLDB_OPT_SET_3, true , "type",         't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeNone,          "The name of a type to view memory as." },
+  {LLDB_OPT_SET_3 |
+   LLDB_OPT_SET_4, true , "type",         't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName,          "The name of a type to view memory as." },
+  {LLDB_OPT_SET_4, false, "language",     'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLanguage,          "The language of the type to view memory as."},
   {LLDB_OPT_SET_3, false, "offset",       'E', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeCount,         "How many elements of the specified type to skip before starting to display data." },
   {LLDB_OPT_SET_1 |
    LLDB_OPT_SET_2 |
@@ -63,7 +65,7 @@ class OptionGroupReadMemory : public Opt
 public:
   OptionGroupReadMemory()
       : m_num_per_line(1, 1), m_output_as_binary(false), m_view_as_type(),
-        m_offset(0, 0) {}
+        m_offset(0, 0), m_language_for_type(eLanguageTypeUnknown) {}
 
   ~OptionGroupReadMemory() override = default;
 
@@ -97,6 +99,10 @@ public:
       m_force = true;
       break;
 
+    case 'x':
+      error = m_language_for_type.SetValueFromString(option_value);
+      break;
+
     case 'E':
       error = m_offset.SetValueFromString(option_value);
       break;
@@ -115,6 +121,7 @@ public:
     m_view_as_type.Clear();
     m_force = false;
     m_offset.Clear();
+    m_language_for_type.Clear();
   }
 
   Status FinalizeSettings(Target *target, OptionGroupFormat &format_options) {
@@ -277,7 +284,8 @@ public:
 
   bool AnyOptionWasSet() const {
     return m_num_per_line.OptionWasSet() || m_output_as_binary ||
-           m_view_as_type.OptionWasSet() || m_offset.OptionWasSet();
+           m_view_as_type.OptionWasSet() || m_offset.OptionWasSet() ||
+           m_language_for_type.OptionWasSet();
   }
 
   OptionValueUInt64 m_num_per_line;
@@ -285,6 +293,7 @@ public:
   OptionValueString m_view_as_type;
   bool m_force;
   OptionValueUInt64 m_offset;
+  OptionValueLanguage m_language_for_type;
 };
 
 // Read memory from the inferior process
@@ -372,7 +381,7 @@ protected:
       return false;
     }
 
-    CompilerType clang_ast_type;
+    CompilerType compiler_type;
     Status error;
 
     const char *view_as_type_cstr =
@@ -472,26 +481,43 @@ protected:
                                     exact_match, 1, searched_symbol_files,
                                     type_list);
 
-      if (type_list.GetSize() == 0 && lookup_type_name.GetCString() &&
-          *lookup_type_name.GetCString() == '$') {
-        if (ClangPersistentVariables *persistent_vars =
-                llvm::dyn_cast_or_null<ClangPersistentVariables>(
-                    target->GetPersistentExpressionStateForLanguage(
-                        lldb::eLanguageTypeC))) {
-          clang::TypeDecl *tdecl = llvm::dyn_cast_or_null<clang::TypeDecl>(
-              persistent_vars->GetPersistentDecl(
-                  ConstString(lookup_type_name)));
-
-          if (tdecl) {
-            clang_ast_type.SetCompilerType(
-                ClangASTContext::GetASTContext(&tdecl->getASTContext()),
-                reinterpret_cast<lldb::opaque_compiler_type_t>(
-                    const_cast<clang::Type *>(tdecl->getTypeForDecl())));
+      if (type_list.GetSize() == 0 && lookup_type_name.GetCString()) {
+        LanguageType language_for_type =
+            m_memory_options.m_language_for_type.GetCurrentValue();
+        std::set<LanguageType> languages_to_check;
+        if (language_for_type != eLanguageTypeUnknown) {
+          languages_to_check.insert(language_for_type);
+        } else {
+          languages_to_check = Language::GetSupportedLanguages();
+        }
+
+        std::set<CompilerType> user_defined_types;
+        for (auto lang : languages_to_check) {
+          if (auto *persistent_vars =
+                  target->GetPersistentExpressionStateForLanguage(lang)) {
+            if (llvm::Optional<CompilerType> type =
+                    persistent_vars->GetCompilerTypeFromPersistentDecl(
+                        lookup_type_name)) {
+              user_defined_types.emplace(*type);
+            }
           }
         }
+
+        if (user_defined_types.size() > 1) {
+          result.AppendErrorWithFormat(
+              "Mutiple types found matching raw type '%s', please disambiguate "
+              "by specifying the language with -x",
+              lookup_type_name.GetCString());
+          result.SetStatus(eReturnStatusFailed);
+          return false;
+        }
+
+        if (user_defined_types.size() == 1) {
+          compiler_type = *user_defined_types.begin();
+        }
       }
 
-      if (!clang_ast_type.IsValid()) {
+      if (!compiler_type.IsValid()) {
         if (type_list.GetSize() == 0) {
           result.AppendErrorWithFormat("unable to find any types that match "
                                        "the raw type '%s' for full type '%s'\n",
@@ -501,14 +527,14 @@ protected:
           return false;
         } else {
           TypeSP type_sp(type_list.GetTypeAtIndex(0));
-          clang_ast_type = type_sp->GetFullCompilerType();
+          compiler_type = type_sp->GetFullCompilerType();
         }
       }
 
       while (pointer_count > 0) {
-        CompilerType pointer_type = clang_ast_type.GetPointerType();
+        CompilerType pointer_type = compiler_type.GetPointerType();
         if (pointer_type.IsValid())
-          clang_ast_type = pointer_type;
+          compiler_type = pointer_type;
         else {
           result.AppendError("unable make a pointer type\n");
           result.SetStatus(eReturnStatusFailed);
@@ -517,7 +543,7 @@ protected:
         --pointer_count;
       }
 
-      llvm::Optional<uint64_t> size = clang_ast_type.GetByteSize(nullptr);
+      llvm::Optional<uint64_t> size = compiler_type.GetByteSize(nullptr);
       if (!size) {
         result.AppendErrorWithFormat(
             "unable to get the byte size of the type '%s'\n",
@@ -547,7 +573,7 @@ protected:
       // options have been set
       addr = m_next_addr;
       total_byte_size = m_prev_byte_size;
-      clang_ast_type = m_prev_clang_ast_type;
+      compiler_type = m_prev_compiler_type;
       if (!m_format_options.AnyOptionWasSet() &&
           !m_memory_options.AnyOptionWasSet() &&
           !m_outfile_options.AnyOptionWasSet() &&
@@ -634,13 +660,13 @@ protected:
 
     DataBufferSP data_sp;
     size_t bytes_read = 0;
-    if (clang_ast_type.GetOpaqueQualType()) {
+    if (compiler_type.GetOpaqueQualType()) {
       // Make sure we don't display our type as ASCII bytes like the default
       // memory read
       if (!m_format_options.GetFormatValue().OptionWasSet())
         m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
 
-      llvm::Optional<uint64_t> size = clang_ast_type.GetByteSize(nullptr);
+      llvm::Optional<uint64_t> size = compiler_type.GetByteSize(nullptr);
       if (!size) {
         result.AppendError("can't get size of type");
         return false;
@@ -750,7 +776,7 @@ protected:
     m_prev_memory_options = m_memory_options;
     m_prev_outfile_options = m_outfile_options;
     m_prev_varobj_options = m_varobj_options;
-    m_prev_clang_ast_type = clang_ast_type;
+    m_prev_compiler_type = compiler_type;
 
     StreamFile outfile_stream;
     Stream *output_stream = nullptr;
@@ -800,14 +826,14 @@ protected:
     }
 
     ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
-    if (clang_ast_type.GetOpaqueQualType()) {
+    if (compiler_type.GetOpaqueQualType()) {
       for (uint32_t i = 0; i < item_count; ++i) {
         addr_t item_addr = addr + (i * item_byte_size);
         Address address(item_addr);
         StreamString name_strm;
         name_strm.Printf("0x%" PRIx64, item_addr);
         ValueObjectSP valobj_sp(ValueObjectMemory::Create(
-            exe_scope, name_strm.GetString(), address, clang_ast_type));
+            exe_scope, name_strm.GetString(), address, compiler_type));
         if (valobj_sp) {
           Format format = m_format_options.GetFormat();
           if (format != eFormatDefault)
@@ -877,7 +903,7 @@ protected:
   OptionGroupReadMemory m_prev_memory_options;
   OptionGroupOutputFile m_prev_outfile_options;
   OptionGroupValueObjectDisplay m_prev_varobj_options;
-  CompilerType m_prev_clang_ast_type;
+  CompilerType m_prev_compiler_type;
 };
 
 static constexpr OptionDefinition g_memory_find_option_table[] = {

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp?rev=363183&r1=363182&r2=363183&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.cpp Wed Jun 12 10:47:06 2019
@@ -9,6 +9,7 @@
 #include "ClangPersistentVariables.h"
 
 #include "lldb/Core/Value.h"
+#include "lldb/Symbol/ClangASTContext.h"
 #include "lldb/Target/Target.h"
 #include "lldb/Utility/DataExtractor.h"
 #include "lldb/Utility/Log.h"
@@ -52,6 +53,21 @@ void ClangPersistentVariables::RemovePer
     m_next_persistent_variable_id--;
 }
 
+llvm::Optional<CompilerType>
+ClangPersistentVariables::GetCompilerTypeFromPersistentDecl(
+    ConstString type_name) {
+  CompilerType compiler_type;
+  if (clang::TypeDecl *tdecl = llvm::dyn_cast_or_null<clang::TypeDecl>(
+          GetPersistentDecl(type_name))) {
+    compiler_type.SetCompilerType(
+        ClangASTContext::GetASTContext(&tdecl->getASTContext()),
+        reinterpret_cast<lldb::opaque_compiler_type_t>(
+            const_cast<clang::Type *>(tdecl->getTypeForDecl())));
+    return compiler_type;
+  }
+  return llvm::None;
+}
+
 void ClangPersistentVariables::RegisterPersistentDecl(ConstString name,
                                                       clang::NamedDecl *decl) {
   m_persistent_decls.insert(

Modified: lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h?rev=363183&r1=363182&r2=363183&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h (original)
+++ lldb/trunk/source/Plugins/ExpressionParser/Clang/ClangPersistentVariables.h Wed Jun 12 10:47:06 2019
@@ -50,6 +50,9 @@ public:
     return "$";
   }
 
+  llvm::Optional<CompilerType>
+  GetCompilerTypeFromPersistentDecl(ConstString type_name) override;
+
   void RegisterPersistentDecl(ConstString name, clang::NamedDecl *decl);
 
   clang::NamedDecl *GetPersistentDecl(ConstString name);




More information about the lldb-commits mailing list