[Lldb-commits] [PATCH] D126464: [lldb] Add support to load object files from thin archives

2022-05-30 Thread Kaining Zhong via Phabricator via lldb-commits
PRESIDENT810 updated this revision to Diff 432857.
PRESIDENT810 added a comment.

I have refactored my code so it should looks cleaner now, but I'm not sure how 
to add a test. It seems that adding a test for thin archive on macOS platforms 
can be not so straightforward. I see that in 
lldb/test/API/functionalities/archives/Makefile, the test suite is using 
libtool instead of ar to create archives on macOS platforms, and I don't know 
whether I can produce a thin archive with that. Also, ld on macOS platforms 
seems to be unable to identify thin archives (I'm using ld64.lld when testing 
my code locally).

I would really appreciate it if someone can provide some advice about how to 
implement such a test case here, thank you!


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

https://reviews.llvm.org/D126464

Files:
  lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
  lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h

Index: lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
===
--- lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
+++ lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
@@ -15,19 +15,24 @@
 #include "lldb/Utility/ConstString.h"
 #include "lldb/Utility/FileSpec.h"
 
+#include "llvm/Object/Archive.h"
 #include "llvm/Support/Chrono.h"
+#include "llvm/Support/Path.h"
 
 #include 
 #include 
 #include 
 
+enum class ArchiveType { Invalid, Archive, ThinArchive };
+
 class ObjectContainerBSDArchive : public lldb_private::ObjectContainer {
 public:
   ObjectContainerBSDArchive(const lldb::ModuleSP &module_sp,
 lldb::DataBufferSP &data_sp,
 lldb::offset_t data_offset,
 const lldb_private::FileSpec *file,
-lldb::offset_t offset, lldb::offset_t length);
+lldb::offset_t offset, lldb::offset_t length,
+ArchiveType archive_type);
 
   ~ObjectContainerBSDArchive() override;
 
@@ -54,7 +59,7 @@
 lldb::offset_t length,
 lldb_private::ModuleSpecList &specs);
 
-  static bool MagicBytesMatch(const lldb_private::DataExtractor &data);
+  static ArchiveType MagicBytesMatch(const lldb_private::DataExtractor &data);
 
   // Member Functions
   bool ParseHeader() override;
@@ -78,6 +83,10 @@
 
 void Clear();
 
+lldb::offset_t ExtractFromThin(const lldb_private::DataExtractor &data,
+   lldb::offset_t offset,
+   llvm::StringRef stringTable);
+
 lldb::offset_t Extract(const lldb_private::DataExtractor &data,
lldb::offset_t offset);
 /// Object name in the archive.
@@ -156,6 +165,8 @@
 
 lldb_private::DataExtractor &GetData() { return m_data; }
 
+ArchiveType GetArchiveType() { return m_archive_type; }
+
   protected:
 typedef lldb_private::UniqueCStringMap ObjectNameToIndexMap;
 // Member Variables
@@ -167,11 +178,14 @@
 lldb_private::DataExtractor m_data; ///< The data for this object container
 ///so we don't lose data if the .a files
 ///gets modified
+ArchiveType m_archive_type;
   };
 
   void SetArchive(Archive::shared_ptr &archive_sp);
 
   Archive::shared_ptr m_archive_sp;
+
+  ArchiveType m_archive_type;
 };
 
 #endif // LLDB_SOURCE_PLUGINS_OBJECTCONTAINER_BSD_ARCHIVE_OBJECTCONTAINERBSDARCHIVE_H
Index: lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
===
--- lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
+++ lldb/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
@@ -40,6 +40,8 @@
 using namespace lldb;
 using namespace lldb_private;
 
+using namespace llvm::object;
+
 LLDB_PLUGIN_DEFINE(ObjectContainerBSDArchive)
 
 ObjectContainerBSDArchive::Object::Object() : ar_name() {}
@@ -55,6 +57,74 @@
   file_size = 0;
 }
 
+lldb::offset_t ObjectContainerBSDArchive::Object::ExtractFromThin(
+const DataExtractor &data, lldb::offset_t offset,
+llvm::StringRef stringTable) {
+  size_t ar_name_len = 0;
+  std::string str;
+  char *err;
+
+  // File header
+  //
+  // The common format is as follows.
+  //
+  //  Offset  Length	NameFormat
+  //  0   16  File name   ASCII right padded with spaces (no spaces
+  //  allowed in file name)
+  //  16  12  File modDecimal as cstring right padded with
+  //  spaces
+  //  28  6   Owner IDDecimal as cstring right padded with
+  //  spaces
+  //  34  6   Group IDDecimal as cstring right padded wi

[Lldb-commits] [PATCH] D124731: [lldb] Consider binary as module of last resort

2022-05-30 Thread David Spickett via Phabricator via lldb-commits
DavidSpickett added a comment.

(I also keep an eye on the bots Omair was referring to) You can just reland 
this change as is (revert your revert) and if something else goes wrong you'll 
either get a failure email or we'll let you know.


Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D124731

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


[Lldb-commits] [PATCH] D126614: [lldb] [gdb-remote] Client support for using the non-stop protocol

2022-05-30 Thread Michał Górny via Phabricator via lldb-commits
mgorny updated this revision to Diff 432910.
mgorny added a comment.

Split the main tests into two variants: one that assumes that server runs in 
all-stop mode (like lldb-server), the other assuming it runs in non-stop mode 
(like gdbserver on Linux).


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

https://reviews.llvm.org/D126614

Files:
  lldb/packages/Python/lldbsuite/test/gdbclientutils.py
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.h
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
  lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
  lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemoteProperties.td
  lldb/source/Target/Process.cpp
  lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py

Index: lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py
===
--- lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py
+++ lldb/test/API/functionalities/gdb_remote_client/TestGDBRemoteClient.py
@@ -585,3 +585,168 @@
 }
 self.do_siginfo_test("remote-freebsd", "basic_eh_frame.yaml",
  data, expected)
+
+def test_QNonStop_query(self):
+class MyResponder(MockGDBServerResponder):
+vStopped_counter = 0
+
+def qSupported(self, client_supported):
+return "QNonStop+;" + super().qSupported(client_supported)
+
+def QNonStop(self, val):
+assert val == 1
+return "OK"
+
+def qfThreadInfo(self):
+return "m10,12"
+
+def qsThreadInfo(self):
+return "l"
+
+def vStopped(self):
+self.vStopped_counter += 1
+return ("OK" if self.vStopped_counter % 2 == 0
+else "T00;thread:10")
+
+self.dbg.HandleCommand(
+"settings set plugin.process.gdb-remote.use-non-stop-protocol true")
+self.addTearDownHook(lambda:
+self.runCmd(
+"settings set plugin.process.gdb-remote.use-non-stop-protocol "
+"false"))
+self.server.responder = MyResponder()
+target = self.dbg.CreateTarget("")
+process = self.connect(target)
+self.assertPacketLogContains(["QNonStop:1", "vStopped"])
+
+def test_QNonStop_run(self):
+class MyResponder(MockGDBServerResponder):
+vStopped_counter = 0
+
+def qSupported(self, client_supported):
+return "QNonStop+;" + super().qSupported(client_supported)
+
+def QNonStop(self, val):
+assert val == 1
+return "OK"
+
+def qfThreadInfo(self):
+return "m10,12"
+
+def qsThreadInfo(self):
+return "l"
+
+def vStopped(self):
+self.vStopped_counter += 1
+return ("OK" if self.vStopped_counter > 1
+else "T00;thread:10")
+
+def cont(self):
+self.vStopped_counter = 0
+return ["OK", "%Stop:T02;thread:12"]
+
+def vCtrlC(self):
+return "OK"
+
+self.dbg.HandleCommand(
+"settings set plugin.process.gdb-remote.use-non-stop-protocol true")
+self.addTearDownHook(lambda:
+self.runCmd(
+"settings set plugin.process.gdb-remote.use-non-stop-protocol "
+"false"))
+self.server.responder = MyResponder()
+target = self.dbg.CreateTarget("")
+process = self.connect(target)
+self.assertPacketLogContains(["QNonStop:1"])
+
+process.Continue()
+self.assertPacketLogContains(["vStopped", "vCtrlC"])
+self.assertEqual(process.GetSelectedThread().GetStopReason(),
+ lldb.eStopReasonSignal)
+self.assertEqual(process.GetSelectedThread().GetStopDescription(100),
+ "signal SIGINT")
+
+def test_QNonStop_run_non_stop_server(self):
+class MyResponder(MockGDBServerResponder):
+def qSupported(self, client_supported):
+return "QNonStop+;" + super().qSupported(client_supported)
+
+def QNonStop(self, val):
+assert val == 1
+return "OK"
+
+def qfThreadInfo(self):
+return "m10,12"
+
+def qsThreadInfo(self):
+return "l"
+
+def vStopped(self):
+return "OK"
+
+def cont(self):
+return ["OK", "%Stop:T02;thread:12"]
+
+def vCtrlC(self):
+return ["OK", "%Stop:T00;thread:10"]

[Lldb-commits] [PATCH] D126655: [lldb] [gdb-remote] Be more explicit about notification reading

2022-05-30 Thread Michał Górny via Phabricator via lldb-commits
mgorny created this revision.
mgorny added reviewers: labath, krytarowski, emaste.
Herald added a subscriber: arichardson.
Herald added a project: All.
mgorny requested review of this revision.

The current GDBRemoteCommunication::ReadPacket() support
for notifications is very limited.  Notably, it can return notifications
when the caller does not expect them and it does not provide an explicit
API to distinguish them from standard packets.  This is not a major
problem right now, as we force serialization when running in non-stop
mode and can predict when we expect notifications to arrive.

Firstly, add an explicit 'allow_notification' parameter to ReadPacket()
and WaitForPacketNoLock().  When it is false (the default),
notifications are pushed onto a queue rather than returned
to the caller.  Effectively, the existing callers can now safely expect
the reading functions to return only standard responses,
and the non-stop logic can explicitly permit notifications.

Secondly, add an explicit PacketResult value for notifications.  This
value can only be returned when allow_notification is true, so it does
not require changes for most of the callers.  For the few that support
notifications, it makes it possible to distinguish standard packets
from notification packets.

Update the non-stop client code to take advantage of the new API,
and therefore be more strict when dealing with responses in non-stop
protocol mode.

Sponsored by: The FreeBSD Foundation


https://reviews.llvm.org/D126655

Files:
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteClientBase.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
  lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h

Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
===
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
+++ lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.h
@@ -12,6 +12,7 @@
 #include "GDBRemoteCommunicationHistory.h"
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -89,17 +90,18 @@
   enum class PacketType { Invalid = 0, Standard, Notify };
 
   enum class PacketResult {
-Success = 0,// Success
-ErrorSendFailed,// Status sending the packet
-ErrorSendAck,   // Didn't get an ack back after sending a packet
-ErrorReplyFailed,   // Status getting the reply
-ErrorReplyTimeout,  // Timed out waiting for reply
-ErrorReplyInvalid,  // Got a reply but it wasn't valid for the packet that
-// was sent
-ErrorReplyAck,  // Sending reply ack failed
-ErrorDisconnected,  // We were disconnected
-ErrorNoSequenceLock // We couldn't get the sequence lock for a multi-packet
-// request
+Success = 0, // Success
+ErrorSendFailed, // Status sending the packet
+ErrorSendAck,// Didn't get an ack back after sending a packet
+ErrorReplyFailed,// Status getting the reply
+ErrorReplyTimeout,   // Timed out waiting for reply
+ErrorReplyInvalid,   // Got a reply but it wasn't valid for the packet that
+ // was sent
+ErrorReplyAck,   // Sending reply ack failed
+ErrorDisconnected,   // We were disconnected
+ErrorNoSequenceLock, // We couldn't get the sequence lock for a multi-packet
+ // request
+Notify,  // Successfully gotten a notification packet
   };
 
   // Class to change the timeout for a given scope and restore it to the
@@ -179,6 +181,7 @@
   bool m_is_platform; // Set to true if this class represents a platform,
   // false if this class represents a debug session for
   // a single process
+  std::deque m_notification_packet_queue;
 
   CompressionType m_compression_type;
 
@@ -190,7 +193,8 @@
bool skip_ack = false);
 
   PacketResult ReadPacket(StringExtractorGDBRemote &response,
-  Timeout timeout, bool sync_on_timeout);
+  Timeout timeout, bool sync_on_timeout,
+  bool allow_notification = false);
 
   PacketResult ReadPacketWithOutputSupport(
   StringExtractorGDBRemote &response, Timeout timeout,
@@ -199,7 +203,8 @@
 
   PacketResult WaitForPacketNoLock(StringExtractorGDBRemote &response,
Timeout timeout,
-   bool sync_on_timeout);
+   bool sync_on_timeout,
+   bool allow_notification = false);
 
   bool CompressionIsEnabled() {
 return m_compression_type != CompressionType::None;
Index: lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
===
--- lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ lldb/s

[Lldb-commits] [PATCH] D126657: [lldb] Fix loading DLL from some ramdisk on Windows

2022-05-30 Thread Alvin Wong via Phabricator via lldb-commits
alvinhochun created this revision.
Herald added a subscriber: mstorsjo.
Herald added a project: All.
alvinhochun requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

The WinAPI `GetFinalPathNameByHandle` is used to retrieve the DLL file
name from the HANDLE provided to `LOAD_DLL_DEBUG_EVENT` in the debug
loop. When this API fails, lldb will simply ignore that module.

Certain ramdisk (e.g. ImDisk) does not work with this API, which means
it is impossible to use lldb to debug a process which loads DLLs located
on this type of ramdisk. In order to make this work, we need to use a
fallback routine which involves creating a file mapping, using
`GetMappedFileName` to get a device path, then substitutes the device
path with its drive letter.

References:

- 
https://developercommunity.visualstudio.com/t/cannot-debug-program-when-compiled-to-ram-drive/43004#T-N109926
- https://github.com/jrfonseca/drmingw/issues/65
- 
https://docs.microsoft.com/en-us/windows/win32/memory/obtaining-a-file-name-from-a-file-handle


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D126657

Files:
  lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp

Index: lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
===
--- lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
+++ lldb/source/Plugins/Process/Windows/Common/DebuggerThread.cpp
@@ -13,6 +13,7 @@
 #include "lldb/Core/ModuleSpec.h"
 #include "lldb/Host/ProcessLaunchInfo.h"
 #include "lldb/Host/ThreadLauncher.h"
+#include "lldb/Host/windows/AutoHandle.h"
 #include "lldb/Host/windows/HostProcessWindows.h"
 #include "lldb/Host/windows/HostThreadWindows.h"
 #include "lldb/Host/windows/ProcessLauncherWindows.h"
@@ -29,6 +30,8 @@
 #include "llvm/Support/Threading.h"
 #include "llvm/Support/raw_ostream.h"
 
+#include 
+
 #ifndef STATUS_WX86_BREAKPOINT
 #define STATUS_WX86_BREAKPOINT 0x401FL // For WOW64
 #endif
@@ -409,6 +412,60 @@
   return DBG_CONTINUE;
 }
 
+static llvm::Optional GetFileNameFromHandleFallback(HANDLE hFile) {
+  // Check that file is not empty as we cannot map a file with zero length.
+  DWORD dwFileSizeHi = 0;
+  DWORD dwFileSizeLo = ::GetFileSize(hFile, &dwFileSizeHi);
+  if (dwFileSizeLo == 0 && dwFileSizeHi == 0)
+return llvm::None;
+
+  AutoHandle filemap(
+  ::CreateFileMappingW(hFile, nullptr, PAGE_READONLY, 0, 1, NULL), nullptr);
+  if (!filemap.IsValid())
+return llvm::None;
+
+  auto view_deleter = [](void *pMem) { ::UnmapViewOfFile(pMem); };
+  std::unique_ptr pMem(
+  ::MapViewOfFile(filemap.get(), FILE_MAP_READ, 0, 0, 1), view_deleter);
+  if (!pMem)
+return llvm::None;
+
+  std::array mapped_filename;
+  if (!::GetMappedFileNameW(::GetCurrentProcess(), pMem.get(),
+mapped_filename.data(), mapped_filename.size()))
+return llvm::None;
+
+  // A series of null-terminated strings, plus an additional null character
+  std::array drive_strings;
+  drive_strings[0] = L'\0';
+  if (!::GetLogicalDriveStringsW(drive_strings.size(), drive_strings.data()))
+return llvm::None;
+
+  std::array drive = {L"_:"};
+  for (auto it = drive_strings.cbegin(); *it != L'\0'; it += wcslen(it) + 1) {
+// Copy the drive letter to the template string
+drive[0] = it[0];
+std::array device_name;
+if (::QueryDosDeviceW(drive.data(), device_name.data(),
+  device_name.size())) {
+  size_t device_name_len = wcslen(device_name.data());
+  if (device_name_len < mapped_filename.size()) {
+bool match = _wcsnicmp(mapped_filename.data(), device_name.data(),
+   device_name_len) == 0;
+if (match && mapped_filename[device_name_len] == L'\\') {
+  // Replace device path with its drive letter
+  std::wstring rebuilt_path(drive.data());
+  rebuilt_path.append(&mapped_filename[device_name_len]);
+  std::string path_utf8;
+  llvm::convertWideToUTF8(rebuilt_path, path_utf8);
+  return path_utf8;
+}
+  }
+}
+  }
+  return llvm::None;
+}
+
 DWORD
 DebuggerThread::HandleLoadDllEvent(const LOAD_DLL_DEBUG_INFO &info,
DWORD thread_id) {
@@ -420,6 +477,17 @@
 return DBG_CONTINUE;
   }
 
+  auto on_load_dll = [&](llvm::StringRef path) {
+FileSpec file_spec(path);
+ModuleSpec module_spec(file_spec);
+lldb::addr_t load_addr = reinterpret_cast(info.lpBaseOfDll);
+
+LLDB_LOG(log, "Inferior {0} - DLL '{1}' loaded at address {2:x}...",
+ m_process.GetProcessId(), path, info.lpBaseOfDll);
+
+m_debug_delegate->OnLoadDll(module_spec, load_addr);
+  };
+
   std::vector buffer(1);
   DWORD required_size =
   GetFinalPathNameByHandleW(info.hFile, &buffer[0], 0, VOLUME_NAME_DOS);
@@ -434,14 +502,10 @@
 if (path_str.startswith("?\\"))
   path += 4;
 
-FileSpec 

[Lldb-commits] [PATCH] D126668: LLDB: Fix resolving nested template parameters

2022-05-30 Thread Levon Ter-Grigoryan via Phabricator via lldb-commits
PatriosTheGreat created this revision.
PatriosTheGreat added a reviewer: teemperor.
Herald added a reviewer: shafik.
Herald added a project: All.
PatriosTheGreat requested review of this revision.
Herald added a project: LLDB.
Herald added a subscriber: lldb-commits.

Right now LLDB ignores nested template type:

echo "
template 
struct A {};
int main() {

  A> s;

}
" > sample.cc

clang++ sample.cc -g -O0
lldb-15 a.out -o "breakpoint set -l 6 -f sample.cc" -o "run" -o "frame variable"

The result:
(A**>) s = {}

This issue was introduced in LLDB 12 due to this CL: 
https://reviews.llvm.org/D92425
Before LLDB 12 this type was resolving correctly:
(A** >) s = {}

I discussed this issue with Raphael in discord:
https://discord.com/channels/636084430946959380/636732809708306432/980825811714191371

Apparently in this case Clang emits A as a forward declaration:
0x05b4:   DW_TAG_base_type

  DW_AT_name  ("int")
  DW_AT_encoding  (DW_ATE_signed)
  DW_AT_byte_size (0x04)

0x05bb:   DW_TAG_structure_type

  DW_AT_calling_convention(DW_CC_pass_by_value)
  DW_AT_name  ("A >")
  DW_AT_byte_size (0x01)
  DW_AT_decl_file ("/home/teemperor/test/args.cpp")
  DW_AT_decl_line (2)

0x05c4: DW_TAG_template_type_parameter

  DW_AT_type(0x05ce "A")
  DW_AT_name("T")

0x05cd: NULL

0x05ce:   DW_TAG_structure_type

  DW_AT_name  ("A")
  DW_AT_declaration   (true)

0x05d3:   NULL

So for LLDB it looks the same as template with empty arguments.
Turning back the old logic is fixing this issue. Other tests from LLVM test 
suite on Linux seems to be green.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D126668

Files:
  lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
  lldb/test/API/lang/cpp/complete-type-check/TestCppIsTypeComplete.py


Index: lldb/test/API/lang/cpp/complete-type-check/TestCppIsTypeComplete.py
===
--- lldb/test/API/lang/cpp/complete-type-check/TestCppIsTypeComplete.py
+++ lldb/test/API/lang/cpp/complete-type-check/TestCppIsTypeComplete.py
@@ -47,7 +47,7 @@
 # Record types without a defining declaration are not complete.
 self.assertPointeeIncomplete("FwdClass *", "fwd_class")
 self.assertPointeeIncomplete("FwdClassTypedef *", "fwd_class_typedef")
-self.assertPointeeIncomplete("FwdTemplateClass<> *", 
"fwd_template_class")
+self.assertPointeeIncomplete("FwdTemplateClass *", 
"fwd_template_class")
 
 # A pointer type is complete even when it points to an incomplete type.
 fwd_class_ptr = self.expect_expr("fwd_class", result_type="FwdClass *")
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2050,6 +2050,8 @@
   break;
 }
   }
+  if (template_param_infos.args.empty() && template_param_infos.names.empty())
+return false;
   return template_param_infos.args.size() == template_param_infos.names.size();
 }
 


Index: lldb/test/API/lang/cpp/complete-type-check/TestCppIsTypeComplete.py
===
--- lldb/test/API/lang/cpp/complete-type-check/TestCppIsTypeComplete.py
+++ lldb/test/API/lang/cpp/complete-type-check/TestCppIsTypeComplete.py
@@ -47,7 +47,7 @@
 # Record types without a defining declaration are not complete.
 self.assertPointeeIncomplete("FwdClass *", "fwd_class")
 self.assertPointeeIncomplete("FwdClassTypedef *", "fwd_class_typedef")
-self.assertPointeeIncomplete("FwdTemplateClass<> *", "fwd_template_class")
+self.assertPointeeIncomplete("FwdTemplateClass *", "fwd_template_class")
 
 # A pointer type is complete even when it points to an incomplete type.
 fwd_class_ptr = self.expect_expr("fwd_class", result_type="FwdClass *")
Index: lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
===
--- lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
+++ lldb/source/Plugins/SymbolFile/DWARF/DWARFASTParserClang.cpp
@@ -2050,6 +2050,8 @@
   break;
 }
   }
+  if (template_param_infos.args.empty() && template_param_infos.names.empty())
+return false;
   return template_param_infos.args.size() == template_param_infos.names.size();
 }
 
___
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits