[Lldb-commits] [PATCH] D115126: [LLDB] Add unit tests for Editline keyboard shortcuts

2021-12-05 Thread Neal via Phabricator via lldb-commits
nealsid updated this revision to Diff 391976.
nealsid added a comment.

Fix casing typo in friend class declaration.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D115126/new/

https://reviews.llvm.org/D115126

Files:
  lldb/include/lldb/Host/Editline.h
  lldb/source/Host/common/Editline.cpp
  lldb/unittests/Editline/EditlineTest.cpp

Index: lldb/unittests/Editline/EditlineTest.cpp
===
--- lldb/unittests/Editline/EditlineTest.cpp
+++ lldb/unittests/Editline/EditlineTest.cpp
@@ -28,7 +28,10 @@
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/StringList.h"
 
+#define ESCAPE "\x1b"
+
 using namespace lldb_private;
+using namespace testing;
 
 namespace {
 const size_t TIMEOUT_MILLIS = 5000;
@@ -80,6 +83,8 @@
 
   void ConsumeAllOutput();
 
+  const std::string GetEditlineOutput() { return testOutputBuffer.str(); }
+
 private:
   bool IsInputComplete(lldb_private::Editline *editline,
lldb_private::StringList );
@@ -91,6 +96,7 @@
   int _pty_secondary_fd;
 
   std::unique_ptr _el_secondary_file;
+  std::stringstream testOutputBuffer;
 };
 
 EditlineAdapter::EditlineAdapter()
@@ -110,11 +116,21 @@
   EXPECT_THAT_ERROR(_pty.OpenSecondary(O_RDWR), llvm::Succeeded());
   _pty_secondary_fd = _pty.GetSecondaryFileDescriptor();
 
-  _el_secondary_file.reset(new FilePointer(fdopen(_pty_secondary_fd, "rw")));
+  _el_secondary_file.reset(new FilePointer(fdopen(_pty_secondary_fd, "w+")));
   EXPECT_FALSE(nullptr == *_el_secondary_file);
   if (*_el_secondary_file == nullptr)
 return;
 
+  // We have to set the output stream we pass to Editline as not using
+  // buffered I/O.  Otherwise we are missing editline's output when we
+  // close the stream in the keybinding test (i.e. the EOF comes
+  // before data previously written to the stream by editline).  This
+  // behavior isn't as I understand the spec becuse fclose should
+  // flush the stream, but my best guess is that it's some unexpected
+  // interaction with stream I/O and ptys.
+  EXPECT_EQ(setvbuf(*_el_secondary_file, nullptr, _IONBF, 0), 0)
+  << "Could not set editline output stream to use unbuffered I/O.";
+
   // Create an Editline instance.
   _editline_sp.reset(new lldb_private::Editline(
   "gtest editor", *_el_secondary_file, *_el_secondary_file,
@@ -207,7 +223,7 @@
 void EditlineAdapter::ConsumeAllOutput() {
   FilePointer output_file(fdopen(_pty_primary_fd, "r"));
 
-  int ch;
+  char ch;
   while ((ch = fgetc(output_file)) != EOF) {
 #if EDITLINE_TEST_DUMP_OUTPUT
 char display_str[] = {0, 0, 0};
@@ -229,15 +245,15 @@
   break;
 }
 printf(" 0x%02x (%03d) (%s)\n", ch, ch, display_str);
-// putc(ch, stdout);
 #endif
+testOutputBuffer << ch;
   }
 }
 
 class EditlineTestFixture : public ::testing::Test {
   SubsystemRAII subsystems;
   EditlineAdapter _el_adapter;
-  std::shared_ptr _sp_output_thread;
+  std::thread _sp_output_thread;
 
 public:
   static void SetUpTestCase() {
@@ -252,14 +268,13 @@
   return;
 
 // Dump output.
-_sp_output_thread =
-std::make_shared([&] { _el_adapter.ConsumeAllOutput(); });
+_sp_output_thread = std::thread([&] { _el_adapter.ConsumeAllOutput(); });
   }
 
   void TearDown() override {
 _el_adapter.CloseInput();
-if (_sp_output_thread)
-  _sp_output_thread->join();
+if (_sp_output_thread.joinable())
+  _sp_output_thread.join();
   }
 
   EditlineAdapter () { return _el_adapter; }
@@ -309,4 +324,133 @@
   EXPECT_THAT(reported_lines, testing::ContainerEq(input_lines));
 }
 
+namespace lldb_private {
+
+// Parameter structure for parameterized tests.
+struct KeybindingTestValue {
+  // A number that is used to name the test, so test output can be
+  // mapped back to a specific input.
+  const std::string testNumber;
+  // Whether this keyboard shortcut is only bound in multi-line mode.
+  bool multilineOnly;
+  // The actual key sequence.
+  const std::string keySequence;
+  // The command the key sequence is supposed to execute.
+  const std::string commandName;
+  // This is initialized to the keySequence by default, but gtest has
+  // some errors when the test name as created by the overloaded
+  // operator<< has embedded newlines.  This is even true when we
+  // specify a custom test name function, as we do below when we
+  // instantiate the test case.  In cases where the keyboard shortcut
+  // has a newline or carriage return, this field in the struct can be
+  // set to something that is printable.
+  const std::string  = keySequence;
+};
+
+std::ostream <<(std::ostream , const KeybindingTestValue ) {
+  return os << "{" << kbtv.printableKeySequence << "  =>  " << kbtv.commandName
+<< " (multiline only: " << kbtv.multilineOnly << ")}";
+}
+
+// The keyboard shortcuts that we're testing.
+const KeybindingTestValue keySequences[] = {
+{"1", false, "^w", "ed-delete-prev-word"},
+  

[Lldb-commits] [PATCH] D115126: [LLDB} Add unit tests for Editline keyboard shortcuts

2021-12-05 Thread Neal via Phabricator via lldb-commits
nealsid created this revision.
nealsid added a reviewer: LLDB.
nealsid added a project: LLDB.
Herald added a subscriber: JDevlieghere.
nealsid requested review of this revision.
Herald added a subscriber: lldb-commits.

This patch adds tests that verify keyboard shortcuts are set up for 
multi-line/single-line mode.  Along the way I also added a few other small 
changes:

- Removed usage of shared_ptr in a case where object ownership was not shared.
- Changed a file's open mode to be read/write.
- Removed non-emacs configuration of keyboard shortcuts, because Editline 
config is hardcoded to "emacs" in ConfigureEditor.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115126

Files:
  lldb/include/lldb/Host/Editline.h
  lldb/source/Host/common/Editline.cpp
  lldb/unittests/Editline/EditlineTest.cpp

Index: lldb/unittests/Editline/EditlineTest.cpp
===
--- lldb/unittests/Editline/EditlineTest.cpp
+++ lldb/unittests/Editline/EditlineTest.cpp
@@ -28,7 +28,10 @@
 #include "lldb/Utility/Status.h"
 #include "lldb/Utility/StringList.h"
 
+#define ESCAPE "\x1b"
+
 using namespace lldb_private;
+using namespace testing;
 
 namespace {
 const size_t TIMEOUT_MILLIS = 5000;
@@ -80,6 +83,8 @@
 
   void ConsumeAllOutput();
 
+  const std::string GetEditlineOutput() { return testOutputBuffer.str(); }
+
 private:
   bool IsInputComplete(lldb_private::Editline *editline,
lldb_private::StringList );
@@ -91,6 +96,7 @@
   int _pty_secondary_fd;
 
   std::unique_ptr _el_secondary_file;
+  std::stringstream testOutputBuffer;
 };
 
 EditlineAdapter::EditlineAdapter()
@@ -110,11 +116,21 @@
   EXPECT_THAT_ERROR(_pty.OpenSecondary(O_RDWR), llvm::Succeeded());
   _pty_secondary_fd = _pty.GetSecondaryFileDescriptor();
 
-  _el_secondary_file.reset(new FilePointer(fdopen(_pty_secondary_fd, "rw")));
+  _el_secondary_file.reset(new FilePointer(fdopen(_pty_secondary_fd, "w+")));
   EXPECT_FALSE(nullptr == *_el_secondary_file);
   if (*_el_secondary_file == nullptr)
 return;
 
+  // We have to set the output stream we pass to Editline as not using
+  // buffered I/O.  Otherwise we are missing editline's output when we
+  // close the stream in the keybinding test (i.e. the EOF comes
+  // before data previously written to the stream by editline).  This
+  // behavior isn't as I understand the spec becuse fclose should
+  // flush the stream, but my best guess is that it's some unexpected
+  // interaction with stream I/O and ptys.
+  EXPECT_EQ(setvbuf(*_el_secondary_file, nullptr, _IONBF, 0), 0)
+  << "Could not set editline output stream to use unbuffered I/O.";
+
   // Create an Editline instance.
   _editline_sp.reset(new lldb_private::Editline(
   "gtest editor", *_el_secondary_file, *_el_secondary_file,
@@ -207,7 +223,7 @@
 void EditlineAdapter::ConsumeAllOutput() {
   FilePointer output_file(fdopen(_pty_primary_fd, "r"));
 
-  int ch;
+  char ch;
   while ((ch = fgetc(output_file)) != EOF) {
 #if EDITLINE_TEST_DUMP_OUTPUT
 char display_str[] = {0, 0, 0};
@@ -229,15 +245,15 @@
   break;
 }
 printf(" 0x%02x (%03d) (%s)\n", ch, ch, display_str);
-// putc(ch, stdout);
 #endif
+testOutputBuffer << ch;
   }
 }
 
 class EditlineTestFixture : public ::testing::Test {
   SubsystemRAII subsystems;
   EditlineAdapter _el_adapter;
-  std::shared_ptr _sp_output_thread;
+  std::thread _sp_output_thread;
 
 public:
   static void SetUpTestCase() {
@@ -252,14 +268,13 @@
   return;
 
 // Dump output.
-_sp_output_thread =
-std::make_shared([&] { _el_adapter.ConsumeAllOutput(); });
+_sp_output_thread = std::thread([&] { _el_adapter.ConsumeAllOutput(); });
   }
 
   void TearDown() override {
 _el_adapter.CloseInput();
-if (_sp_output_thread)
-  _sp_output_thread->join();
+if (_sp_output_thread.joinable())
+  _sp_output_thread.join();
   }
 
   EditlineAdapter () { return _el_adapter; }
@@ -309,4 +324,133 @@
   EXPECT_THAT(reported_lines, testing::ContainerEq(input_lines));
 }
 
+namespace lldb_private {
+
+// Parameter structure for parameterized tests.
+struct KeybindingTestValue {
+  // A number that is used to name the test, so test output can be
+  // mapped back to a specific input.
+  const std::string testNumber;
+  // Whether this keyboard shortcut is only bound in multi-line mode.
+  bool multilineOnly;
+  // The actual key sequence.
+  const std::string keySequence;
+  // The command the key sequence is supposed to execute.
+  const std::string commandName;
+  // This is initialized to the keySequence by default, but gtest has
+  // some errors when the test name as created by the overloaded
+  // operator<< has embedded newlines.  This is even true when we
+  // specify a custom test name function, as we do below when we
+  // instantiate the test case.  In cases where the keyboard shortcut
+  // has a newline or carriage return, this field in the struct can be
+ 

[Lldb-commits] [PATCH] D85719: Initialize static const fields in the AST for expression evaluation

2021-12-05 Thread Raphael Isemann via Phabricator via lldb-commits
teemperor added a comment.

Btw, that patch that I referenced hasn't landed yet (it just lacks the tests 
and probably rebasing), but I'm OOO for an unknown duration so feel free to 
land it yourself.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D85719/new/

https://reviews.llvm.org/D85719

___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits


[Lldb-commits] [PATCH] D114627: [lldb] add new overload for SymbolFile::FindTypes that accepts a scope

2021-12-05 Thread Lasse Folger via Phabricator via lldb-commits
lassefolger updated this revision to Diff 391896.
lassefolger added a comment.

rebased on nfc and completed implementation to expose function in API


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D114627/new/

https://reviews.llvm.org/D114627

Files:
  lldb/include/lldb/Core/Module.h
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/source/Core/Module.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  lldb/source/Symbol/SymbolFile.cpp

Index: lldb/source/Symbol/SymbolFile.cpp
===
--- lldb/source/Symbol/SymbolFile.cpp
+++ lldb/source/Symbol/SymbolFile.cpp
@@ -135,6 +135,19 @@
 llvm::DenseSet _symbol_files,
 TypeMap ) {}
 
+void SymbolFile::FindTypes(
+ConstString basename, ConstString scope,
+const CompilerDeclContext _decl_ctx, uint32_t max_matches,
+llvm::DenseSet _symbol_files,
+TypeMap ) {
+  FindTypes(basename, parent_decl_ctx, max_matches, searched_symbol_files,
+types);
+  TypeClass type_class = eTypeClassAny;
+  types.RemoveMismatchedTypes(std::string(basename.GetCString()),
+  std::string(scope.GetCString()), type_class,
+  true);
+}
+
 void SymbolFile::FindTypes(llvm::ArrayRef pattern,
LanguageSet languages,
llvm::DenseSet _symbol_files,
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -191,6 +191,13 @@
   const std::string _qualified_name,
   std::vector _names) override;
 
+  void
+  FindTypes(lldb_private::ConstString name, lldb_private::ConstString scope,
+const lldb_private::CompilerDeclContext _decl_ctx,
+uint32_t max_matches,
+llvm::DenseSet _symbol_files,
+lldb_private::TypeMap ) override;
+
   void
   FindTypes(lldb_private::ConstString name,
 const lldb_private::CompilerDeclContext _decl_ctx,
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -9,6 +9,7 @@
 #include "SymbolFileDWARF.h"
 
 #include "llvm/ADT/Optional.h"
+#include "llvm/ADT/StringRef.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/Support/Threading.h"
 
@@ -21,6 +22,7 @@
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/Value.h"
 #include "lldb/Utility/ArchSpec.h"
+#include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/RegularExpression.h"
 #include "lldb/Utility/Scalar.h"
 #include "lldb/Utility/StreamString.h"
@@ -2419,6 +2421,15 @@
 uint32_t max_matches,
 llvm::DenseSet _symbol_files,
 TypeMap ) {
+  FindTypes(name, ConstString(), parent_decl_ctx, max_matches,
+searched_symbol_files, types);
+}
+
+void SymbolFileDWARF::FindTypes(
+ConstString name, ConstString scope,
+const CompilerDeclContext _decl_ctx, uint32_t max_matches,
+llvm::DenseSet _symbol_files,
+TypeMap ) {
   std::lock_guard guard(GetModuleMutex());
   // Make sure we haven't already searched this SymbolFile before.
   if (!searched_symbol_files.insert(this).second)
@@ -2445,10 +2456,21 @@
   if (!DeclContextMatchesThisSymbolFile(parent_decl_ctx))
 return;
 
+  // prepare string to check against in case this is a fully qualified search
+  bool has_scope = !scope.IsEmpty();
+  llvm::StringRef sc(scope.GetStringRef());
+  std::string storage;
+
   m_index->GetTypes(name, [&](DWARFDIE die) {
 if (!DIEInDeclContext(parent_decl_ctx, die))
   return true; // The containing decl contexts don't match
 
+if (has_scope) {
+  const char *qn = die.GetQualifiedName(storage);
+  if (qn && !llvm::StringRef(qn).startswith(sc))
+return true;
+}
+
 Type *matching_type = ResolveType(die, true, true);
 if (!matching_type)
   return true;
Index: lldb/source/Core/Module.cpp
===
--- lldb/source/Core/Module.cpp
+++ lldb/source/Core/Module.cpp
@@ -944,6 +944,17 @@
searched_symbol_files, types);
 }
 
+void Module::FindTypes_Impl(
+ConstString name, ConstString scope,
+const CompilerDeclContext _decl_ctx, size_t max_matches,
+llvm::DenseSet _symbol_files,
+TypeMap ) {
+  LLDB_SCOPED_TIMER();
+  if (SymbolFile *symbols = GetSymbolFile())
+symbols->FindTypes(name, scope, parent_decl_ctx, max_matches,
+   searched_symbol_files, types);
+}
+
 void Module::FindTypesInNamespace(ConstString type_name,
   const CompilerDeclContext _decl_ctx,

[Lldb-commits] [PATCH] D115110: [lldb][nfc] clang-format some files as preperation for https://reviews.llvm.org/D114627

2021-12-05 Thread Lasse Folger via Phabricator via lldb-commits
lassefolger created this revision.
lassefolger requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D115110

Files:
  lldb/include/lldb/Core/Module.h
  lldb/include/lldb/Symbol/SymbolFile.h
  lldb/source/Core/Module.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
  lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
  lldb/source/Symbol/SymbolFile.cpp

Index: lldb/source/Symbol/SymbolFile.cpp
===
--- lldb/source/Symbol/SymbolFile.cpp
+++ lldb/source/Symbol/SymbolFile.cpp
@@ -147,9 +147,11 @@
   // We assert that we have to module lock by trying to acquire the lock from a
   // different thread. Note that we must abort if the result is true to
   // guarantee correctness.
-  assert(std::async(std::launch::async,
-[this] { return this->GetModuleMutex().try_lock(); })
- .get() == false &&
+  assert(std::async(
+ std::launch::async,
+ [this] {
+   return this->GetModuleMutex().try_lock();
+ }).get() == false &&
  "Module is not locked");
 #endif
 }
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
@@ -253,8 +253,8 @@
   ExternalTypeModuleMap;
 
   /// Return the list of Clang modules imported by this SymbolFile.
-  const ExternalTypeModuleMap& getExternalTypeModules() const {
-  return m_external_type_modules;
+  const ExternalTypeModuleMap () const {
+return m_external_type_modules;
   }
 
   virtual DWARFDIE GetDIE(const DIERef _ref);
@@ -328,7 +328,6 @@
 return m_parse_time;
   }
 
-
 protected:
   typedef llvm::DenseMap
   DIEToTypePtr;
@@ -428,9 +427,10 @@
   virtual lldb::TypeSP
   FindDefinitionTypeForDWARFDeclContext(const DWARFDeclContext _decl_ctx);
 
-  virtual lldb::TypeSP FindCompleteObjCDefinitionTypeForDIE(
-  const DWARFDIE , lldb_private::ConstString type_name,
-  bool must_be_implementation);
+  virtual lldb::TypeSP
+  FindCompleteObjCDefinitionTypeForDIE(const DWARFDIE ,
+   lldb_private::ConstString type_name,
+   bool must_be_implementation);
 
   lldb_private::Symbol *
   GetObjCClassSymbol(lldb_private::ConstString objc_class_name);
Index: lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1115,7 +1115,8 @@
   if (const char *include_path = module_die.GetAttributeValueAsString(
   DW_AT_LLVM_include_path, nullptr)) {
 FileSpec include_spec(include_path, dwarf_cu->GetPathStyle());
-MakeAbsoluteAndRemap(include_spec, *dwarf_cu, m_objfile_sp->GetModule());
+MakeAbsoluteAndRemap(include_spec, *dwarf_cu,
+ m_objfile_sp->GetModule());
 module.search_path = ConstString(include_spec.GetPath());
   }
   if (const char *sysroot = dwarf_cu->DIE().GetAttributeValueAsString(
@@ -1942,7 +1943,7 @@
   block_die = function_die.LookupDeepestBlock(file_vm_addr);
   }
 
-  if (!sc.function || ! lookup_block)
+  if (!sc.function || !lookup_block)
 return;
 
   Block  = sc.function->GetBlock(true);
@@ -2330,7 +2331,8 @@
   if (log) {
 GetObjectFile()->GetModule()->LogMessage(
 log,
-"SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, sc_list)",
+"SymbolFileDWARF::FindFunctions (name=\"%s\", name_type_mask=0x%x, "
+"sc_list)",
 name.GetCString(), name_type_mask);
   }
 
@@ -2363,8 +2365,7 @@
 log,
 "SymbolFileDWARF::FindFunctions (name=\"%s\", "
 "name_type_mask=0x%x, include_inlines=%d, sc_list) => %u",
-name.GetCString(), name_type_mask, include_inlines,
-num_matches);
+name.GetCString(), name_type_mask, include_inlines, num_matches);
   }
 }
 
Index: lldb/source/Core/Module.cpp
===
--- lldb/source/Core/Module.cpp
+++ lldb/source/Core/Module.cpp
@@ -233,8 +233,8 @@
 Module::Module(const FileSpec _spec, const ArchSpec ,
const ConstString *object_name, lldb::offset_t object_offset,
const llvm::sys::TimePoint<> _mod_time)
-: m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)), m_arch(arch),
-  m_file(file_spec), m_object_offset(object_offset),
+: m_mod_time(FileSystem::Instance().GetModificationTime(file_spec)),
+  m_arch(arch), m_file(file_spec), m_object_offset(object_offset),