From scallanan at apple.com Mon Aug 9 13:50:15 2010 From: scallanan at apple.com (Sean Callanan) Date: Mon, 09 Aug 2010 18:50:15 -0000 Subject: [Lldb-commits] [lldb] r110585 - in /lldb/trunk/source: Commands/CommandObjectCommands.cpp Interpreter/CommandInterpreter.cpp Message-ID: <20100809185015.D092E2A6C12C@llvm.org> Author: spyffe Date: Mon Aug 9 13:50:15 2010 New Revision: 110585 URL: http://llvm.org/viewvc/llvm-project?rev=110585&view=rev Log: Updated help text to refer to "commands alias" instead of "alias." Also fixed a bunch of indentation in the help for "commands alias." Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp lldb/trunk/source/Interpreter/CommandInterpreter.cpp Modified: lldb/trunk/source/Commands/CommandObjectCommands.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectCommands.cpp?rev=110585&r1=110584&r2=110585&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectCommands.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectCommands.cpp Mon Aug 9 13:50:15 2010 @@ -140,27 +140,27 @@ CommandObjectCommandsAlias () : CommandObject ("commands alias", "Allows users to define their own debugger command abbreviations.", - "alias []") + "commands alias []") { SetHelpLong( "'alias' allows the user to create a short-cut or abbreviation for long \n\ commands, multi-word commands, and commands that take particular options. \n\ Below are some simple examples of how one might use the 'alias' command: \n\ - \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\ - // command. \n\ - 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\ - // command. Since breakpoint commands are two-word \n\ - // commands, the user will still need to enter the \n\ - // second word after 'bp', e.g. 'bp enable' or \n\ - // 'bp delete'. \n\ - 'command alias bpi breakpoint list' // Creates the abbreviation 'bpi' for the \n\ - // two-word command 'breakpoint list'. \n\ + \n 'command alias sc script' // Creates the abbreviation 'sc' for the 'script' \n\ + // command. \n\ + 'command alias bp breakpoint' // Creates the abbreviation 'bp' for the 'breakpoint' \n\ + // command. Since breakpoint commands are two-word \n\ + // commands, the user will still need to enter the \n\ + // second word after 'bp', e.g. 'bp enable' or \n\ + // 'bp delete'. \n\ + 'command alias bpi breakpoint list' // Creates the abbreviation 'bpi' for the \n\ + // two-word command 'breakpoint list'. \n\ \nAn alias can include some options for the command, with the values either \n\ filled in at the time the alias is created, or specified as positional \n\ arguments, to be filled in when the alias is invoked. The following example \n\ shows how to create aliases with options: \n\ \n\ - 'command alias bfl breakpoint set -f %1 -l %2' \n\ + 'command alias bfl breakpoint set -f %1 -l %2' \n\ \nThis creates the abbreviation 'bfl' (for break-file-line), with the -f and -l \n\ options already part of the alias. So if the user wants to set a breakpoint \n\ by file and line without explicitly having to use the -f and -l options, the \n\ @@ -175,20 +175,20 @@ filled in with the first argument following 'bfl' and the actual line number \n\ value will be filled in with the second argument. The user would use this \n\ alias as follows: \n\ - \n (dbg) alias bfl breakpoint set -f %1 -l %2 \n\ - <... some time later ...> \n\ - (dbg) bfl my-file.c 137 \n\ + \n (dbg) commands alias bfl breakpoint set -f %1 -l %2 \n\ + <... some time later ...> \n\ + (dbg) bfl my-file.c 137 \n\ \nThis would be the same as if the user had entered \n\ 'breakpoint set -f my-file.c -l 137'. \n\ \nAnother example: \n\ - \n (dbg) alias pltty process launch -s -o %1 -e %1 \n\ - (dbg) pltty /dev/tty0 \n\ - // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\ + \n (dbg) commands alias pltty process launch -s -o %1 -e %1 \n\ + (dbg) pltty /dev/tty0 \n\ + // becomes 'process launch -s -o /dev/tty0 -e /dev/tty0' \n\ \nIf the user always wanted to pass the same value to a particular option, the \n\ alias could be defined with that value directly in the alias as a constant, \n\ rather than using a positional placeholder: \n\ - \n alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\ - // 3 of whatever file is indicated. \n"); + \n commands alias bl3 breakpoint set -f %1 -l 3 // Always sets a breakpoint on line \n\ + // 3 of whatever file is indicated. \n"); } Modified: lldb/trunk/source/Interpreter/CommandInterpreter.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/CommandInterpreter.cpp?rev=110585&r1=110584&r2=110585&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/CommandInterpreter.cpp (original) +++ lldb/trunk/source/Interpreter/CommandInterpreter.cpp Mon Aug 9 13:50:15 2010 @@ -533,7 +533,7 @@ if (m_alias_dict.size() > 0) { - result.AppendMessage("The following is a list of your current command abbreviations (see 'alias' for more info):"); + result.AppendMessage("The following is a list of your current command abbreviations (see 'commands alias' for more info):"); result.AppendMessage(""); longest_word = FindLongestCommandWord (m_alias_dict); max_len = strlen (longest_word.c_str()); From johnny.chen at apple.com Mon Aug 9 15:40:52 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 09 Aug 2010 20:40:52 -0000 Subject: [Lldb-commits] [lldb] r110595 - /lldb/trunk/test/dotest.py Message-ID: <20100809204052.5A8C32A6C12C@llvm.org> Author: johnny Date: Mon Aug 9 15:40:52 2010 New Revision: 110595 URL: http://llvm.org/viewvc/llvm-project?rev=110595&view=rev Log: Install the SIGINT (control-c) handler before invoking the text test runner. Modified: lldb/trunk/test/dotest.py Modified: lldb/trunk/test/dotest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=110595&r1=110594&r2=110595&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Mon Aug 9 15:40:52 2010 @@ -180,6 +180,10 @@ if not res.Succeeded(): raise Exception('log enable failed (check your LLDB_LOG env variable...') +# Install the control-c handler. +unittest2.signals.installHandler() + +# Invoke the default TextTestRunner to run the test suite. unittest2.TextTestRunner(verbosity=verbose).run(suite) # Add some delay before calling SBDebugger.Terminate(). From johnny.chen at apple.com Mon Aug 9 17:01:17 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 09 Aug 2010 22:01:17 -0000 Subject: [Lldb-commits] [lldb] r110611 - in /lldb/trunk/test: array_types/TestArrayTypes.py lldbtest.py Message-ID: <20100809220117.A4EC82A6C12C@llvm.org> Author: johnny Date: Mon Aug 9 17:01:17 2010 New Revision: 110611 URL: http://llvm.org/viewvc/llvm-project?rev=110611&view=rev Log: Added some commonly used assert messages to the lldbtest.py module which houses the TestBase. Modified TestArrayTypes.py to use the assert messages. Other files to follow. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/lldbtest.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=110611&r1=110610&r2=110611&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Mon Aug 9 17:01:17 2010 @@ -3,9 +3,9 @@ import os, time import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestArrayTypes(lldbtest.TestBase): +class TestArrayTypes(TestBase): mydir = "array_types" @@ -14,29 +14,31 @@ res = self.res exe = os.path.join(os.getcwd(), "a.out") self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) # Break on line 42 inside main(). self.ci.HandleCommand("breakpoint set -f main.c -l 42", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.c', line = 42, locations = 1")) + "Breakpoint created: 1: file ='main.c', line = 42, locations = 1"), + BREAK_POINT_CREATED) self.ci.HandleCommand("run", res) - time.sleep(0.1) + time.sleep(1) self.assertTrue(res.Succeeded()) # The stop reason of the thread should be breakpoint. self.ci.HandleCommand("thread list", res) - print "thread list ->", res.GetOutput() self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and - res.GetOutput().find('stop reason = breakpoint') > 0) + res.GetOutput().find('stop reason = breakpoint') > 0, + STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find('resolved, hit count = 1') > 0) + self.assertTrue(res.GetOutput().find('resolved, hit count = 1') > 0, + BREAK_POINT_HIT_ONCE) # Issue 'variable list' command on several array-type variables. @@ -51,20 +53,24 @@ output.find('Hello') > 0 and output.find('Hola') > 0 and output.find('Bonjour') > 0 and - output.find('Guten Tag') > 0) + output.find('Guten Tag') > 0, + VARIABLES_DISPLAYED_CORRECTLY) self.ci.HandleCommand("variable list char_16", res); self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().find('(char) char_16[0]') > 0 and - res.GetOutput().find('(char) char_16[15]') > 0) + res.GetOutput().find('(char) char_16[15]') > 0, + VARIABLES_DISPLAYED_CORRECTLY) self.ci.HandleCommand("variable list ushort_matrix", res); self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().startswith('(unsigned short [2][3])')) + self.assertTrue(res.GetOutput().startswith('(unsigned short [2][3])'), + VARIABLES_DISPLAYED_CORRECTLY) self.ci.HandleCommand("variable list long_6", res); self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().startswith('(long [6])')) + self.assertTrue(res.GetOutput().startswith('(long [6])'), + VARIABLES_DISPLAYED_CORRECTLY) self.ci.HandleCommand("continue", res) self.assertTrue(res.Succeeded()) Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=110611&r1=110610&r2=110611&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Mon Aug 9 17:01:17 2010 @@ -31,6 +31,24 @@ import unittest2 import lldb +# +# Some commonly used assert messages. +# + +CURRENT_EXECUTABLE_SET = "Current executable set successfully" + +COMMAND_HANDLED = "Command handled successfully" + +BREAK_POINT_CREATED = "Breakpoint created successfully" + +BREAK_POINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1" + +STOPPED_DUE_TO_BREAKPOINT = "Process state is stopped due to breakpoint" + +STOPPED_DUE_TO_STEP_IN = "Process state is stopped due to step in" + +VARIABLES_DISPLAYED_CORRECTLY = "Show specified variable(s) correctly" + class TestBase(unittest2.TestCase): """This LLDB abstract base class is meant to be subclassed.""" From jingham at apple.com Mon Aug 9 18:31:02 2010 From: jingham at apple.com (Jim Ingham) Date: Mon, 09 Aug 2010 23:31:02 -0000 Subject: [Lldb-commits] [lldb] r110624 - in /lldb/trunk: include/lldb/Core/ include/lldb/Host/ include/lldb/Symbol/ include/lldb/Target/ source/Commands/ source/Core/ source/Host/macosx/ source/Plugins/DynamicLoader/MacOSX-DYLD/ source/Plugins/ObjectContainer/Universal-Mach-O/ source/Plugins/ObjectFile/ELF/ source/Plugins/ObjectFile/Mach-O/ source/Plugins/Process/MacOSX-User/source/ source/Plugins/Process/gdb-remote/ source/Symbol/ source/Target/ Message-ID: <20100809233103.20AAC2A6C12C@llvm.org> Author: jingham Date: Mon Aug 9 18:31:02 2010 New Revision: 110624 URL: http://llvm.org/viewvc/llvm-project?rev=110624&view=rev Log: Change Target & Process so they can really be initialized with an invalid architecture. Arrange that this then gets properly set on attach, or when a "file" is set. Add a completer for "process attach -n". Caveats: there isn't currently a way to handle multiple processes with the same name. That will have to wait on a way to pass annotations along with the completion strings. Modified: lldb/trunk/include/lldb/Core/Module.h lldb/trunk/include/lldb/Host/Host.h lldb/trunk/include/lldb/Symbol/ObjectFile.h lldb/trunk/include/lldb/Target/Process.h lldb/trunk/include/lldb/Target/Target.h lldb/trunk/source/Commands/CommandObjectFile.cpp lldb/trunk/source/Commands/CommandObjectProcess.cpp lldb/trunk/source/Core/Module.cpp lldb/trunk/source/Host/macosx/Host.mm lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h lldb/trunk/source/Symbol/ObjectFile.cpp lldb/trunk/source/Target/Process.cpp lldb/trunk/source/Target/StopInfo.cpp lldb/trunk/source/Target/Target.cpp lldb/trunk/source/Target/TargetList.cpp Modified: lldb/trunk/include/lldb/Core/Module.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Module.h?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/include/lldb/Core/Module.h (original) +++ lldb/trunk/include/lldb/Core/Module.h Mon Aug 9 18:31:02 2010 @@ -13,6 +13,7 @@ #include "lldb/Core/ArchSpec.h" #include "lldb/Core/Section.h" #include "lldb/Core/UUID.h" +#include "lldb/Symbol/ObjectFile.h" #include "lldb/Host/Mutex.h" #include "lldb/Host/TimeValue.h" #include "lldb/Symbol/CompileUnit.h" @@ -46,6 +47,7 @@ { public: friend class ModuleList; + friend bool ObjectFile::SetModulesArchitecture (const ArchSpec &new_arch); enum { @@ -343,6 +345,16 @@ const TimeValue & GetModificationTime () const; + + //------------------------------------------------------------------ + /// Tells whether this module is capable of being the main executable + /// for a process. + /// + /// @return + /// \b true if it is, \b false otherwise. + //------------------------------------------------------------------ + bool + IsExecutable (); //------------------------------------------------------------------ /// Get the number of compile units for this module. @@ -547,7 +559,7 @@ //------------------------------------------------------------------ mutable Mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments. TimeValue m_mod_time; ///< The modification time for this module when it was created. - const ArchSpec m_arch; ///< The architecture for this module. + ArchSpec m_arch; ///< The architecture for this module. UUID m_uuid; ///< Each module is assumed to have a unique identifier to help match it up to debug symbols. FileSpec m_file; ///< The file representation on disk for this module (if there is one). Flags m_flags; ///< Flags for this module to track what has been parsed already. @@ -592,7 +604,9 @@ ResolveSymbolContextForAddress (lldb::addr_t vm_addr, bool vm_addr_is_file_addr, uint32_t resolve_scope, Address& so_addr, SymbolContext& sc); void SymbolIndicesToSymbolContextList (Symtab *symtab, std::vector &symbol_indexes, SymbolContextList &sc_list); - + + bool SetArchitecture (const ArchSpec &new_arch); + private: DISALLOW_COPY_AND_ASSIGN (Module); Modified: lldb/trunk/include/lldb/Host/Host.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/Host.h?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/include/lldb/Host/Host.h (original) +++ lldb/trunk/include/lldb/Host/Host.h Mon Aug 9 18:31:02 2010 @@ -13,6 +13,7 @@ #include "lldb/lldb-private.h" +#include "lldb/Core/StringList.h" namespace lldb_private { @@ -273,6 +274,16 @@ static bool ResolveExecutableInBundle (FileSpec *file); + + static uint32_t + ListProcessesMatchingName (const char *name, StringList &matches, std::vector &pids); + + static ArchSpec + GetArchSpecForExistingProcess (lldb::pid_t pid); + + static ArchSpec + GetArchSpecForExistingProcess (const char *process_name); + }; } // namespace lldb_private Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ObjectFile.h?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/ObjectFile.h (original) +++ lldb/trunk/include/lldb/Symbol/ObjectFile.h Mon Aug 9 18:31:02 2010 @@ -51,6 +51,8 @@ public PluginInterface, public ModuleChild { +friend class lldb_private::Module; + public: //------------------------------------------------------------------ /// Construct with a parent module, offset, and header data. @@ -159,7 +161,17 @@ //------------------------------------------------------------------ virtual uint32_t GetDependentModules (FileSpecList& file_list) = 0; - + + //------------------------------------------------------------------ + /// Tells whether this object file is capable of being the main executable + /// for a process. + /// + /// @return + /// \b true if it is, \b false otherwise. + //------------------------------------------------------------------ + virtual bool + IsExecutable () const = 0; + //------------------------------------------------------------------ /// Returns the offset into a file at which this object resides. /// @@ -290,6 +302,20 @@ lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory lldb::addr_t m_length; ///< The length of this object file if it is known (can be zero if length is unknown or can't be determined). DataExtractor m_data; ///< The data for this object file so things can be parsed lazily. + + //------------------------------------------------------------------ + /// Sets the architecture for a module. At present the architecture + /// can only be set if it is invalid. It is not allowed to switch from + /// one concrete architecture to another. + /// + /// @param[in] new_arch + /// The architecture this module will be set to. + /// + /// @return + /// Returns \b true if the architecture was changed, \b + /// false otherwise. + //------------------------------------------------------------------ + bool SetModulesArchitecture (const ArchSpec &new_arch); private: DISALLOW_COPY_AND_ASSIGN (ObjectFile); Modified: lldb/trunk/include/lldb/Target/Process.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Process.h (original) +++ lldb/trunk/include/lldb/Target/Process.h Mon Aug 9 18:31:02 2010 @@ -20,6 +20,7 @@ #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Error.h" #include "lldb/Core/Event.h" +#include "lldb/Core/StringList.h" #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Core/ThreadSafeSTLMap.h" #include "lldb/Core/PluginInterface.h" @@ -313,6 +314,58 @@ //------------------------------------------------------------------ virtual Error Attach (const char *process_name, bool wait_for_launch); + + //------------------------------------------------------------------ + /// List the processes matching the given partial name. + /// + /// FIXME: Is it too heavyweight to create an entire process object to do this? + /// The problem is for remote processes we're going to have to set up the same transport + /// to get this data as to actually attach. So we need to factor out transport + /// and process before we can do this separately from the process. + /// + /// @param[in] name + /// A partial name to match against the current process list. + /// + /// @param[out] matches + /// The list of process names matching \a name. + /// + /// @param[in] pids + /// A vector filled with the pids that correspond to the names in \a matches. + /// + /// @return + /// Returns the number of matching processes. + //------------------------------------------------------------------ + + virtual uint32_t + ListProcessesMatchingName (const char *name, StringList &matches, std::vector &pids); + + //------------------------------------------------------------------ + /// Find the architecture of a process by pid. + /// + /// FIXME: See comment for ListProcessesMatchingName. + /// + /// @param[in] pid + /// A pid to inspect. + /// + /// @return + /// Returns the architecture of the process or an invalid architecture if the process can't be found. + //------------------------------------------------------------------ + virtual ArchSpec + GetArchSpecForExistingProcess (lldb::pid_t pid); + + //------------------------------------------------------------------ + /// Find the architecture of a process by name. + /// + /// FIXME: See comment for ListProcessesMatchingName. + /// + /// @param[in] process_name + /// The process name to inspect. + /// + /// @return + /// Returns the architecture of the process or an invalid architecture if the process can't be found. + //------------------------------------------------------------------ + virtual ArchSpec + GetArchSpecForExistingProcess (const char *process_name); uint32_t GetAddressByteSize(); Modified: lldb/trunk/include/lldb/Target/Target.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Target.h?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Target.h (original) +++ lldb/trunk/include/lldb/Target/Target.h Mon Aug 9 18:31:02 2010 @@ -253,6 +253,27 @@ ArchSpec GetArchitecture () const; + + //------------------------------------------------------------------ + /// Set the architecture for this target. + /// + /// If the current target has no Images read in, then this just sets the architecture, which will + /// be used to select the architecture of the ExecutableModule when that is set. + /// If the current target has an ExecutableModule, then calling SetArchitecture with a different + /// architecture from the currently selected one will reset the ExecutableModule to that slice + /// of the file backing the ExecutableModule. If the file backing the ExecutableModule does not + /// contain a fork of this architecture, then this code will return false, and the architecture + /// won't be changed. + /// If the input arch_spec is the same as the already set architecture, this is a no-op. + /// + /// @param[in] arch_spec + /// The new architecture. + /// + /// @return + /// \b true if the architecture was successfully set, \bfalse otherwise. + //------------------------------------------------------------------ + bool + SetArchitecture (const ArchSpec &arch_spec); Debugger & GetDebugger () @@ -300,6 +321,7 @@ // Member variables. //------------------------------------------------------------------ Debugger & m_debugger; + ArchSpec m_arch_spec; ModuleList m_images; ///< The list of images for this process (shared libraries and anything dynamically loaded). BreakpointList m_breakpoint_list; BreakpointList m_internal_breakpoint_list; Modified: lldb/trunk/source/Commands/CommandObjectFile.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectFile.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectFile.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectFile.cpp Mon Aug 9 18:31:02 2010 @@ -126,31 +126,14 @@ TargetSP target_sp; - ArchSpec arch; - if (m_options.m_arch.IsValid()) - arch = m_options.m_arch; - else - { - arch = lldb_private::GetDefaultArchitecture (); - if (!arch.IsValid()) - arch = LLDB_ARCH_DEFAULT; - } + ArchSpec arch = m_options.m_arch; Debugger &debugger = interpreter.GetDebugger(); - Error error = debugger.GetTargetList().CreateTarget (debugger, file_spec, arch, NULL, true, target_sp); - - if (error.Fail() && !m_options.m_arch.IsValid()) - { - if (arch == LLDB_ARCH_DEFAULT_32BIT) - arch = LLDB_ARCH_DEFAULT_64BIT; - else - arch = LLDB_ARCH_DEFAULT_32BIT; - error = debugger.GetTargetList().CreateTarget (debugger, file_spec, arch, NULL, true, target_sp); - } + Error error = debugger.GetTargetList().CreateTarget (debugger, file_spec, m_options.m_arch, NULL, true, target_sp); if (target_sp) { debugger.GetTargetList().SetCurrentTarget(target_sp.get()); - result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, arch.AsCString()); + result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().AsCString()); result.SetStatus (eReturnStatusSuccessFinishNoResult); } else Modified: lldb/trunk/source/Commands/CommandObjectProcess.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectProcess.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectProcess.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectProcess.cpp Mon Aug 9 18:31:02 2010 @@ -279,110 +279,6 @@ { public: - CommandObjectProcessAttach () : - CommandObject ("process attach", - "Attaches to a process.", - "process attach ") - { - SetHelpLong("Currently, you must set the executable file before you can attach " - "to a process.\n"); - } - - ~CommandObjectProcessAttach () - { - } - - bool - Execute (CommandInterpreter &interpreter, - Args& command, - CommandReturnObject &result) - { - Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); - if (target == NULL) - { - result.AppendError ("invalid target, set executable file using 'file' command"); - result.SetStatus (eReturnStatusFailed); - return false; - } - - // If our listener is NULL, users aren't allows to launch - - Process *process = interpreter.GetDebugger().GetExecutionContext().process; - if (process) - { - if (process->IsAlive()) - { - result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", process->GetID()); - result.SetStatus (eReturnStatusFailed); - return false; - } - } - - if (command.GetArgumentCount()) - { - result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); - result.SetStatus (eReturnStatusFailed); - } - else - { - const char *plugin_name = NULL; - - if (!m_options.plugin_name.empty()) - plugin_name = m_options.plugin_name.c_str(); - - process = target->CreateProcess (interpreter.GetDebugger().GetListener(), plugin_name).get(); - - if (process) - { - Error error; - int attach_pid = m_options.pid; - - if (attach_pid != LLDB_INVALID_PROCESS_ID) - { - error = process->Attach (attach_pid); - if (error.Success()) - { - result.SetStatus (eReturnStatusSuccessContinuingNoResult); - } - else - { - result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", - attach_pid, - error.AsCString()); - result.SetStatus (eReturnStatusFailed); - } - } - else if (!m_options.name.empty()) - { - error = process->Attach (m_options.name.c_str(), m_options.waitfor); - if (error.Success()) - { - result.SetStatus (eReturnStatusSuccessContinuingNoResult); - } - else - { - if (m_options.waitfor) - result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", - m_options.name.c_str(), - error.AsCString()); - else - result.AppendErrorWithFormat ("Failed to a process named '%s': %s\n", - m_options.name.c_str(), - error.AsCString()); - result.SetStatus (eReturnStatusFailed); - } - } - } - } - return result.Succeeded(); - } - - Options * - GetOptions () - { - return &m_options; - } - class CommandOptions : public Options { public: @@ -448,6 +344,68 @@ return g_option_table; } + virtual bool + HandleOptionArgumentCompletion (CommandInterpreter &interpreter, + Args &input, + int cursor_index, + int char_pos, + OptionElementVector &opt_element_vector, + int opt_element_index, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) + { + int opt_arg_pos = opt_element_vector[opt_element_index].opt_arg_pos; + int opt_defs_index = opt_element_vector[opt_element_index].opt_defs_index; + + // We are only completing the name option for now... + + const lldb::OptionDefinition *opt_defs = GetDefinitions(); + if (opt_defs[opt_defs_index].short_option == 'n') + { + // Are we in the name? + + // Look to see if there is a -P argument provided, and if so use that plugin, otherwise + // use the default plugin. + Process *process = interpreter.GetDebugger().GetExecutionContext().process; + bool need_to_delete_process = false; + + const char *partial_name = NULL; + partial_name = input.GetArgumentAtIndex(opt_arg_pos); + + if (process && process->IsAlive()) + return true; + + Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + if (target == NULL) + { + // No target has been set yet, for now do host completion. Otherwise I don't know how we would + // figure out what the right target to use is... + std::vector pids; + Host::ListProcessesMatchingName (partial_name, matches, pids); + return true; + } + if (!process) + { + process = target->CreateProcess (interpreter.GetDebugger().GetListener(), partial_name).get(); + need_to_delete_process = true; + } + + if (process) + { + matches.Clear(); + std::vector pids; + process->ListProcessesMatchingName (NULL, matches, pids); + if (need_to_delete_process) + target->DeleteCurrentProcess(); + return true; + } + } + + return false; + } + // Options table: Required for subclasses of Options. static lldb::OptionDefinition g_option_table[]; @@ -460,6 +418,211 @@ bool waitfor; }; + CommandObjectProcessAttach () : + CommandObject ("process attach", + "Attaches to a process.", + "process attach ") + { + SetHelpLong("Currently, you must set the executable file before you can attach " + "to a process.\n"); + } + + ~CommandObjectProcessAttach () + { + } + + bool + Execute (CommandInterpreter &interpreter, + Args& command, + CommandReturnObject &result) + { + Target *target = interpreter.GetDebugger().GetCurrentTarget().get(); + + Process *process = interpreter.GetDebugger().GetExecutionContext().process; + if (process) + { + if (process->IsAlive()) + { + result.AppendErrorWithFormat ("Process %u is currently being debugged, kill the process before attaching.\n", + process->GetID()); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + + if (target == NULL) + { + // If there isn't a current target create one. + TargetSP new_target_sp; + FileSpec emptyFileSpec; + ArchSpec emptyArchSpec; + Error error; + + error = interpreter.GetDebugger().GetTargetList().CreateTarget(interpreter.GetDebugger(), + emptyFileSpec, + emptyArchSpec, + NULL, + false, + new_target_sp); + target = new_target_sp.get(); + if (target == NULL || error.Fail()) + { + result.AppendError(error.AsCString("Error creating empty target")); + return false; + } + interpreter.GetDebugger().GetTargetList().SetCurrentTarget(target); + } + + // Record the old executable module, we want to issue a warning if the process of attaching changed the + // current executable (like somebody said "file foo" then attached to a PID whose executable was bar.) + + ModuleSP old_exec_module_sp = target->GetExecutableModule(); + ArchSpec old_arch_spec = target->GetArchitecture(); + + if (command.GetArgumentCount()) + { + result.AppendErrorWithFormat("Invalid arguments for '%s'.\nUsage: \n", m_cmd_name.c_str(), m_cmd_syntax.c_str()); + result.SetStatus (eReturnStatusFailed); + } + else + { + const char *plugin_name = NULL; + + if (!m_options.plugin_name.empty()) + plugin_name = m_options.plugin_name.c_str(); + + process = target->CreateProcess (interpreter.GetDebugger().GetListener(), plugin_name).get(); + + if (process) + { + Error error; + int attach_pid = m_options.pid; + + // If we are waiting for a process with this name to show up, do that first. + if (m_options.waitfor) + { + if (m_options.name.empty()) + { + result.AppendError("Invalid arguments: must supply a process name with the waitfor option.\n"); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + error = process->Attach (m_options.name.c_str(), m_options.waitfor); + if (error.Success()) + { + result.SetStatus (eReturnStatusSuccessContinuingNoResult); + } + else + { + result.AppendErrorWithFormat ("Waiting for a process to launch named '%s': %s\n", + m_options.name.c_str(), + error.AsCString()); + result.SetStatus (eReturnStatusFailed); + return false; + } + } + } + else + { + // If the process was specified by name look it up, so we can warn if there are multiple + // processes with this pid. + + if (attach_pid == LLDB_INVALID_PROCESS_ID && !m_options.name.empty()) + { + std::vector pids; + StringList matches; + + process->ListProcessesMatchingName(m_options.name.c_str(), matches, pids); + if (matches.GetSize() > 1) + { + result.AppendErrorWithFormat("More than one process named %s\n", m_options.name.c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } + else if (matches.GetSize() == 0) + { + result.AppendErrorWithFormat("Could not find a process named %s\n", m_options.name.c_str()); + result.SetStatus (eReturnStatusFailed); + return false; + } + else + { + attach_pid = pids[0]; + } + + } + + if (attach_pid != LLDB_INVALID_PROCESS_ID) + { + error = process->Attach (attach_pid); + if (error.Success()) + { + result.SetStatus (eReturnStatusSuccessContinuingNoResult); + } + else + { + result.AppendErrorWithFormat ("Attaching to process %i failed: %s.\n", + attach_pid, + error.AsCString()); + result.SetStatus (eReturnStatusFailed); + } + } + else + { + result.AppendErrorWithFormat ("No PID specified for attach\n", + attach_pid, + error.AsCString()); + result.SetStatus (eReturnStatusFailed); + + } + } + } + } + + if (result.Succeeded()) + { + // Okay, we're done. Last step is to warn if the executable module has changed: + if (!old_exec_module_sp) + { + char new_path[PATH_MAX + 1]; + target->GetExecutableModule()->GetFileSpec().GetPath(new_path, PATH_MAX); + + result.AppendMessageWithFormat("Executable module set to \"%s\".\n", + new_path); + } + else if (old_exec_module_sp->GetFileSpec() != target->GetExecutableModule()->GetFileSpec()) + { + char old_path[PATH_MAX + 1]; + char new_path[PATH_MAX + 1]; + + old_exec_module_sp->GetFileSpec().GetPath(old_path, PATH_MAX); + target->GetExecutableModule()->GetFileSpec().GetPath (new_path, PATH_MAX); + + result.AppendWarningWithFormat("Executable module changed from \"%s\" to \"%s\".\n", + old_path, new_path); + } + + if (!old_arch_spec.IsValid()) + { + result.AppendMessageWithFormat ("Architecture set to: %s.\n", target->GetArchitecture().AsCString()); + } + else if (old_arch_spec != target->GetArchitecture()) + { + result.AppendWarningWithFormat("Architecture changed from %s to %s.\n", + old_arch_spec.AsCString(), target->GetArchitecture().AsCString()); + } + } + return result.Succeeded(); + } + + Options * + GetOptions () + { + return &m_options; + } + protected: CommandOptions m_options; Modified: lldb/trunk/source/Core/Module.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Module.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Core/Module.cpp (original) +++ lldb/trunk/source/Core/Module.cpp Mon Aug 9 18:31:02 2010 @@ -43,7 +43,6 @@ m_object_name.IsEmpty() ? "" : "(", m_object_name.IsEmpty() ? "" : m_object_name.AsCString(""), m_object_name.IsEmpty() ? "" : ")"); - } Module::~Module() @@ -516,3 +515,30 @@ { return m_mod_time; } + +bool +Module::IsExecutable () +{ + if (GetObjectFile() == NULL) + return false; + else + return GetObjectFile()->IsExecutable(); +} + +bool +Module::SetArchitecture (const ArchSpec &new_arch) +{ + if (m_arch == new_arch) + return true; + else if (!m_arch.IsValid()) + { + m_arch = new_arch; + return true; + } + else + { + return false; + } + +} + Modified: lldb/trunk/source/Host/macosx/Host.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Host/macosx/Host.mm (original) +++ lldb/trunk/source/Host/macosx/Host.mm Mon Aug 9 18:31:02 2010 @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include @@ -802,3 +804,86 @@ } } +uint32_t +Host::ListProcessesMatchingName (const char *name, StringList &matches, std::vector &pids) +{ + + int num_pids; + int size_of_pids; + int *pid_list; + uint32_t num_matches = 0; + + size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0); + if (size_of_pids == -1) + return 0; + + num_pids = size_of_pids/sizeof(int); + pid_list = (int *) malloc(size_of_pids); + size_of_pids = proc_listpids(PROC_ALL_PIDS, 0, pid_list, size_of_pids); + if (size_of_pids == -1) + return 0; + + pid_t our_pid = getpid(); + + for (int i = 0; i < num_pids; i++) + { + struct proc_bsdinfo bsd_info; + int error = proc_pidinfo (pid_list[i], PROC_PIDTBSDINFO, (uint64_t) 0, &bsd_info, PROC_PIDTBSDINFO_SIZE); + if (error == 0) + continue; + + // Don't offer to attach to zombie processes, already traced or exiting + // processes, and of course, ourselves... It looks like passing the second arg of + // 0 to proc_listpids will exclude zombies anyway, but that's not documented so... + if ((bsd_info.pbi_flags & (PROC_FLAG_TRACED | PROC_FLAG_INEXIT) != 0) + || (bsd_info.pbi_status == SZOMB) + || (bsd_info.pbi_pid == our_pid)) + continue; + char pid_name[MAXCOMLEN * 2 + 1]; + int name_len; + name_len = proc_name(bsd_info.pbi_pid, pid_name, MAXCOMLEN * 2); + if (name_len == 0) + continue; + + if (strstr(pid_name, name) != pid_name) + continue; + matches.AppendString (pid_name); + pids.push_back (bsd_info.pbi_pid); + num_matches++; + } + + return num_matches; +} + +ArchSpec +Host::GetArchSpecForExistingProcess (lldb::pid_t pid) +{ + ArchSpec return_spec; + + struct proc_bsdinfo bsd_info; + int error = proc_pidinfo (pid, PROC_PIDTBSDINFO, (uint64_t) 0, &bsd_info, PROC_PIDTBSDINFO_SIZE); + if (error == 0) + return return_spec; + if (bsd_info.pbi_flags & PROC_FLAG_LP64) + return_spec.SetArch(LLDB_ARCH_DEFAULT_64BIT); + else + return_spec.SetArch(LLDB_ARCH_DEFAULT_32BIT); + + return return_spec; +} + +ArchSpec +Host::GetArchSpecForExistingProcess (const char *process_name) +{ + ArchSpec returnSpec; + StringList matches; + std::vector pids; + if (ListProcessesMatchingName(process_name, matches, pids)) + { + if (matches.GetSize() == 1) + { + return GetArchSpecForExistingProcess(pids[0]); + } + } + return returnSpec; +} Modified: lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original) +++ lldb/trunk/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Mon Aug 9 18:31:02 2010 @@ -1016,8 +1016,7 @@ return m_break_id != LLDB_INVALID_BREAK_ID; } -//----------------------------------------------------------------------Target.h - +//---------------------------------------------------------------------- // Member function that gets called when the process state changes. //---------------------------------------------------------------------- void Modified: lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp (original) +++ lldb/trunk/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp Mon Aug 9 18:31:02 2010 @@ -199,7 +199,18 @@ ObjectContainerUniversalMachO::GetObjectFile (const FileSpec *file) { uint32_t arch_idx = 0; - const ArchSpec arch = m_module->GetArchitecture(); + ArchSpec arch; + // If the module hasn't specified an architecture yet, set it to the default + // architecture: + if (!m_module->GetArchitecture().IsValid()) + { + arch = lldb_private::GetDefaultArchitecture (); + if (!arch.IsValid()) + arch = LLDB_ARCH_DEFAULT; + } + else + arch = m_module->GetArchitecture(); + ArchSpec curr_arch; for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx) { Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original) +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Mon Aug 9 18:31:02 2010 @@ -145,6 +145,13 @@ { } +bool +ObjectFileELF::IsExecutable() const +{ + // FIXME: How is this marked in ELF? + return false; +} + ByteOrder ObjectFileELF::GetByteOrder() const { Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h (original) +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h Mon Aug 9 18:31:02 2010 @@ -86,6 +86,9 @@ virtual lldb::ByteOrder GetByteOrder() const; + virtual bool + IsExecutable () const; + virtual size_t GetAddressByteSize() const; Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original) +++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Mon Aug 9 18:31:02 2010 @@ -161,7 +161,8 @@ m_data.GetU32(&offset, &m_header.cputype, 6); ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype); - if (mach_arch == m_module->GetArchitecture()) + + if (SetModulesArchitecture (mach_arch)) { // Read in all only the load command data DataBufferSP data_sp(m_file.ReadFileContents(m_offset, m_header.sizeofcmds + MachHeaderSizeFromMagic(m_header.magic))); @@ -184,6 +185,11 @@ return m_data.GetByteOrder (); } +bool +ObjectFileMachO::IsExecutable() const +{ + return m_header.filetype == HeaderFileTypeExecutable; +} size_t ObjectFileMachO::GetAddressByteSize () const Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original) +++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Mon Aug 9 18:31:02 2010 @@ -66,6 +66,9 @@ virtual lldb::ByteOrder GetByteOrder () const; + + virtual bool + IsExecutable () const; virtual size_t GetAddressByteSize () const; Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.cpp Mon Aug 9 18:31:02 2010 @@ -2208,5 +2208,10 @@ } } +uint32_t +ProcessMacOSX::ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector &pids) +{ + return Host::ListProcessesMatchingName (name, matches, pids); +} Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ProcessMacOSX.h Mon Aug 9 18:31:02 2010 @@ -18,6 +18,7 @@ // Other libraries and framework includes #include "lldb/Core/ArchSpec.h" #include "lldb/Core/ThreadSafeValue.h" +#include "lldb/Core/StringList.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" @@ -110,6 +111,9 @@ virtual void DidAttach (); + + virtual uint32_t + ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector &pids); //------------------------------------------------------------------ // PluginInterface protocol Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Mon Aug 9 18:31:02 2010 @@ -93,7 +93,8 @@ ModuleSP exe_module_sp(target.GetExecutableModule()); if (exe_module_sp.get()) return exe_module_sp->GetFileSpec().Exists(); - return false; + // However, if there is no executable module, we return true since we might be preparing to attach. + return true; } //---------------------------------------------------------------------- @@ -106,7 +107,6 @@ m_stdio_communication ("gdb-remote.stdio"), m_stdio_mutex (Mutex::eMutexTypeRecursive), m_stdout_data (), - m_arch_spec (), m_byte_order (eByteOrderHost), m_gdb_comm(), m_debugserver_pid (LLDB_INVALID_PROCESS_ID), @@ -124,7 +124,8 @@ m_max_memory_size (512), m_libunwind_target_type (UNW_TARGET_UNSPECIFIED), m_libunwind_addr_space (NULL), - m_waiting_for_attach (false) + m_waiting_for_attach (false), + m_local_debugserver (true) { } @@ -563,11 +564,9 @@ { m_dispatch_queue_offsets_addr = LLDB_INVALID_ADDRESS; - Module * exe_module = GetTarget().GetExecutableModule ().get(); + Module * exe_module = GetTarget().GetExecutableModule ().get(); assert(exe_module); - m_arch_spec = exe_module->GetArchitecture(); - ObjectFile *exe_objfile = exe_module->GetObjectFile(); assert(exe_objfile); @@ -580,8 +579,9 @@ // See if the GDB server supports the qHostInfo information const char *vendor = m_gdb_comm.GetVendorString().AsCString(); const char *os_type = m_gdb_comm.GetOSString().AsCString(); + ArchSpec arch_spec = GetTarget().GetArchitecture(); - if (m_arch_spec.IsValid() && m_arch_spec == ArchSpec ("arm")) + if (arch_spec.IsValid() && arch_spec == ArchSpec ("arm")) { // For ARM we can't trust the arch of the process as it could // have an armv6 object file, but be running on armv7 kernel. @@ -589,7 +589,7 @@ } if (!inferior_arch.IsValid()) - inferior_arch = m_arch_spec; + inferior_arch = arch_spec; if (vendor == NULL) vendor = Host::GetVendorString().AsCString("apple"); @@ -622,11 +622,11 @@ Error error; // Clear out and clean up from any current state Clear(); - // HACK: require arch be set correctly at the target level until we can - // figure out a good way to determine the arch of what we are attaching to - m_arch_spec = m_target.GetArchitecture(); - + ArchSpec arch_spec = GetTarget().GetArchitecture(); + //Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS); + + if (attach_pid != LLDB_INVALID_PROCESS_ID) { SetPrivateState (eStateAttaching); @@ -638,7 +638,7 @@ NULL, LLDB_INVALID_PROCESS_ID, NULL, false, - m_arch_spec); + arch_spec); if (error.Fail()) { @@ -724,7 +724,6 @@ Clear(); // HACK: require arch be set correctly at the target level until we can // figure out a good way to determine the arch of what we are attaching to - m_arch_spec = m_target.GetArchitecture(); //Log *log = ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS); if (process_name && process_name[0]) @@ -732,6 +731,7 @@ SetPrivateState (eStateAttaching); char host_port[128]; + ArchSpec arch_spec = GetTarget().GetArchitecture(); snprintf (host_port, sizeof(host_port), "localhost:%u", get_random_port ()); error = StartDebugserverProcess (host_port, NULL, @@ -739,7 +739,7 @@ NULL, LLDB_INVALID_PROCESS_ID, NULL, false, - m_arch_spec); + arch_spec); if (error.Fail()) { const char *error_string = error.AsCString(); @@ -840,9 +840,26 @@ void ProcessGDBRemote::DidAttach () { - DidLaunchOrAttach (); + // If we haven't got an executable module yet, then we should make a dynamic loader, and + // see if it can find the executable module for us. If we do have an executable module, + // make sure it matches the process we've just attached to. + + ModuleSP exe_module_sp = GetTarget().GetExecutableModule(); + if (!m_dynamic_loader_ap.get()) + { + m_dynamic_loader_ap.reset(DynamicLoader::FindPlugin(this, "dynamic-loader.macosx-dyld")); + } + if (m_dynamic_loader_ap.get()) m_dynamic_loader_ap->DidAttach(); + + Module * new_exe_module = GetTarget().GetExecutableModule().get(); + if (new_exe_module == NULL) + { + + } + + DidLaunchOrAttach (); } Error @@ -876,7 +893,7 @@ static const uint8_t g_ppc_breakpoint_opcode[] = { 0x7F, 0xC0, 0x00, 0x08 }; static const uint8_t g_i386_breakpoint_opcode[] = { 0xCC }; - ArchSpec::CPU arch_cpu = m_arch_spec.GetGenericCPUType(); + ArchSpec::CPU arch_cpu = GetTarget().GetArchitecture().GetGenericCPUType(); switch (arch_cpu) { case ArchSpec::eCPU_i386: @@ -1060,13 +1077,16 @@ void ProcessGDBRemote::RefreshStateAfterStop () { + // FIXME - add a variable to tell that we're in the middle of attaching if we + // need to know that. // We must be attaching if we don't already have a valid architecture - if (!m_arch_spec.IsValid()) - { - Module *exe_module = GetTarget().GetExecutableModule().get(); - if (exe_module) - m_arch_spec = exe_module->GetArchitecture(); - } +// if (!GetTarget().GetArchitecture().IsValid()) +// { +// Module *exe_module = GetTarget().GetExecutableModule().get(); +// if (exe_module) +// m_arch_spec = exe_module->GetArchitecture(); +// } + // Let all threads recover from stopping and do any clean up based // on the previous thread state (if any). m_thread_list.RefreshStateAfterStop(); @@ -2251,3 +2271,19 @@ return dispatch_queue_name.c_str(); } +uint32_t +ProcessGDBRemote::ListProcessesMatchingName (const char *name, StringList &matches, std::vector &pids) +{ + // If we are planning to launch the debugserver remotely, then we need to fire up a debugserver + // process and ask it for the list of processes. But if we are local, we can let the Host do it. + if (m_local_debugserver) + { + return Host::ListProcessesMatchingName (name, matches, pids); + } + else + { + // FIXME: Implement talking to the remote debugserver. + return 0; + } + +} Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Mon Aug 9 18:31:02 2010 @@ -21,6 +21,7 @@ #include "lldb/Core/Error.h" #include "lldb/Core/InputReader.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/StringList.h" #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Target/Process.h" #include "lldb/Target/Thread.h" @@ -67,6 +68,9 @@ virtual bool CanDebug (lldb_private::Target &target); + virtual uint32_t + ListProcessesMatchingName (const char *name, lldb_private::StringList &matches, std::vector &pids); + //------------------------------------------------------------------ // Creating a new process, or attaching to an existing one //------------------------------------------------------------------ @@ -262,17 +266,6 @@ void AppendSTDOUT (const char* s, size_t len); - lldb_private::ArchSpec& - GetArchSpec() - { - return m_arch_spec; - } - const lldb_private::ArchSpec& - GetArchSpec() const - { - return m_arch_spec; - } - void Clear ( ); @@ -328,7 +321,6 @@ lldb_private::Communication m_stdio_communication; lldb_private::Mutex m_stdio_mutex; // Multithreaded protection for stdio std::string m_stdout_data; - lldb_private::ArchSpec m_arch_spec; lldb::ByteOrder m_byte_order; GDBRemoteCommunication m_gdb_comm; lldb::pid_t m_debugserver_pid; @@ -349,6 +341,7 @@ lldb_private::unw_targettype_t m_libunwind_target_type; lldb_private::unw_addr_space_t m_libunwind_addr_space; // libunwind address space object for this process. bool m_waiting_for_attach; + bool m_local_debugserver; // Is the debugserver process we are talking to local or on another machine. void ResetGDBRemoteState (); Modified: lldb/trunk/source/Symbol/ObjectFile.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ObjectFile.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Symbol/ObjectFile.cpp (original) +++ lldb/trunk/source/Symbol/ObjectFile.cpp Mon Aug 9 18:31:02 2010 @@ -90,3 +90,10 @@ } return NULL; } + +bool +ObjectFile::SetModulesArchitecture (const ArchSpec &new_arch) +{ + return m_module->SetArchitecture (new_arch); +} + Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Mon Aug 9 18:31:02 2010 @@ -1048,6 +1048,24 @@ if (state == eStateStopped || state == eStateCrashed) { DidAttach (); + // Figure out which one is the executable, and set that in our target: + ModuleList &modules = GetTarget().GetImages(); + + size_t num_modules = modules.GetSize(); + for (int i = 0; i < num_modules; i++) + { + ModuleSP module_sp = modules.GetModuleAtIndex(i); + if (module_sp->IsExecutable()) + { + ModuleSP exec_module = GetTarget().GetExecutableModule(); + if (!exec_module || exec_module != module_sp) + { + + GetTarget().SetExecutableModule (module_sp, false); + } + break; + } + } // This delays passing the stopped event to listeners till DidLaunch gets // a chance to complete... @@ -1073,6 +1091,16 @@ m_target_triple.Clear(); m_abi_sp.reset(); + // Find the process and its architecture. Make sure it matches the architecture + // of the current Target, and if not adjust it. + + ArchSpec attach_spec = GetArchSpecForExistingProcess (attach_pid); + if (attach_spec != GetTarget().GetArchitecture()) + { + // Set the architecture on the target. + GetTarget().SetArchitecture(attach_spec); + } + Error error (WillAttachToProcessWithID(attach_pid)); if (error.Success()) { @@ -1102,6 +1130,16 @@ { m_target_triple.Clear(); m_abi_sp.reset(); + + // Find the process and its architecture. Make sure it matches the architecture + // of the current Target, and if not adjust it. + + ArchSpec attach_spec = GetArchSpecForExistingProcess (process_name); + if (attach_spec != GetTarget().GetArchitecture()) + { + // Set the architecture on the target. + GetTarget().SetArchitecture(attach_spec); + } Error error (WillAttachToProcessWithName(process_name, wait_for_launch)); if (error.Success()) @@ -1863,3 +1901,22 @@ return m_objc_object_printer; } +uint32_t +Process::ListProcessesMatchingName (const char *name, StringList &matches, std::vector &pids) +{ + return 0; +} + +ArchSpec +Process::GetArchSpecForExistingProcess (lldb::pid_t pid) +{ + return Host::GetArchSpecForExistingProcess (pid); +} + +ArchSpec +Process::GetArchSpecForExistingProcess (const char *process_name) +{ + return Host::GetArchSpecForExistingProcess (process_name); +} + + Modified: lldb/trunk/source/Target/StopInfo.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Target/StopInfo.cpp (original) +++ lldb/trunk/source/Target/StopInfo.cpp Mon Aug 9 18:31:02 2010 @@ -79,7 +79,7 @@ &m_thread.GetProcess(), &m_thread, m_thread.GetStackFrameAtIndex(0).get(), - false); + true); m_should_stop = bp_site_sp->ShouldStop (&context); } Modified: lldb/trunk/source/Target/Target.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Target.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Target/Target.cpp (original) +++ lldb/trunk/source/Target/Target.cpp Mon Aug 9 18:31:02 2010 @@ -373,6 +373,10 @@ m_images.Append(executable_sp); // The first image is our exectuable file ArchSpec exe_arch = executable_sp->GetArchitecture(); + // If we haven't set an architecture yet, reset our architecture based on what we found in the executable module. + if (!m_arch_spec.IsValid()) + m_arch_spec = exe_arch; + FileSpecList dependent_files; ObjectFile * executable_objfile = executable_sp->GetObjectFile(); if (executable_objfile == NULL) @@ -426,18 +430,63 @@ ArchSpec Target::GetArchitecture () const { - ArchSpec arch; - if (m_images.GetSize() > 0) + return m_arch_spec; +} + +bool +Target::SetArchitecture (const ArchSpec &arch_spec) +{ + if (m_arch_spec == arch_spec) { - Module *exe_module = m_images.GetModulePointerAtIndex(0); - if (exe_module) - arch = exe_module->GetArchitecture(); + // If we're setting the architecture to our current architecture, we + // don't need to do anything. + return true; + } + else if (!m_arch_spec.IsValid()) + { + // If we haven't got a valid arch spec, then we just need to set it. + m_arch_spec = arch_spec; + return true; + } + else + { + // If we have an executable file, try to reset the executable to the desired architecture + m_arch_spec = arch_spec; + ModuleSP executable_sp = GetExecutableModule (); + m_images.Clear(); + m_scratch_ast_context_ap.reset(); + m_triple.Clear(); + // Need to do something about unsetting breakpoints. + + if (executable_sp) + { + FileSpec exec_file_spec = executable_sp->GetFileSpec(); + Error error = ModuleList::GetSharedModule(exec_file_spec, + arch_spec, + NULL, + NULL, + 0, + executable_sp, + NULL, + NULL); + + if (!error.Fail() && executable_sp) + { + SetExecutableModule (executable_sp, true); + return true; + } + else + { + return false; + } + } + else + { + return false; + } } - return arch; } - - bool Target::GetTargetTriple(ConstString &triple) { Modified: lldb/trunk/source/Target/TargetList.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/TargetList.cpp?rev=110624&r1=110623&r2=110624&view=diff ============================================================================== --- lldb/trunk/source/Target/TargetList.cpp (original) +++ lldb/trunk/source/Target/TargetList.cpp Mon Aug 9 18:31:02 2010 @@ -60,30 +60,50 @@ file.GetFilename().AsCString(), arch.AsCString(), uuid_ptr); - ModuleSP exe_module_sp; - FileSpec resolved_file(file); - if (!Host::ResolveExecutableInBundle (&resolved_file)) - resolved_file = file; - - Error error = ModuleList::GetSharedModule(resolved_file, - arch, - uuid_ptr, - NULL, - 0, - exe_module_sp, - NULL, - NULL); - if (exe_module_sp) + Error error; + + if (!file) { target_sp.reset(new Target(debugger)); - target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); - - if (target_sp.get()) + target_sp->SetArchitecture(arch); + } + else + { + ModuleSP exe_module_sp; + FileSpec resolved_file(file); + if (!Host::ResolveExecutableInBundle (&resolved_file)) + resolved_file = file; + + error = ModuleList::GetSharedModule(resolved_file, + arch, + uuid_ptr, + NULL, + 0, + exe_module_sp, + NULL, + NULL); + if (exe_module_sp) { - Mutex::Locker locker(m_target_list_mutex); - m_current_target_idx = m_target_list.size(); - m_target_list.push_back(target_sp); + if (exe_module_sp->GetObjectFile() == NULL) + { + error.SetErrorStringWithFormat("%s%s%s: doesn't contain architecture %s", + file.GetDirectory().AsCString(), + file.GetDirectory() ? "/" : "", + file.GetFilename().AsCString(), + arch.AsCString()); + return error; + } + target_sp.reset(new Target(debugger)); + target_sp->SetExecutableModule (exe_module_sp, get_dependent_files); } + } + + if (target_sp.get()) + { + Mutex::Locker locker(m_target_list_mutex); + m_current_target_idx = m_target_list.size(); + m_target_list.push_back(target_sp); + } // target_sp.reset(new Target); // // Let the target resolve any funky bundle paths before we try and get @@ -107,7 +127,6 @@ // m_target_list.push_back(target_sp); // } // } - } else { target_sp.reset(); From johnny.chen at apple.com Mon Aug 9 18:44:24 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Mon, 09 Aug 2010 23:44:24 -0000 Subject: [Lldb-commits] [lldb] r110625 - in /lldb/trunk/test: array_types/TestArrayTypes.py class_types/TestClassTypes.py command_source/TestCommandSource.py dead-strip/TestDeadStrip.py function_types/TestFunctionTypes.py global_variables/TestGlobalVariables.py help/TestHelp.py lldbtest.py load_unload/TestLoadUnload.py order/TestOrderFile.py set_values/TestSetValues.py stl/TestSTL.py struct_types/TestStructTypes.py unsigned_types/TestUnsignedTypes.py Message-ID: <20100809234424.987182A6C12C@llvm.org> Author: johnny Date: Mon Aug 9 18:44:24 2010 New Revision: 110625 URL: http://llvm.org/viewvc/llvm-project?rev=110625&view=rev Log: Modified the remaining test cases to display more meaningful assert messages. Added a generic message generator to the lldbtest.py base module. Modified: lldb/trunk/test/array_types/TestArrayTypes.py lldb/trunk/test/class_types/TestClassTypes.py lldb/trunk/test/command_source/TestCommandSource.py lldb/trunk/test/dead-strip/TestDeadStrip.py lldb/trunk/test/function_types/TestFunctionTypes.py lldb/trunk/test/global_variables/TestGlobalVariables.py lldb/trunk/test/help/TestHelp.py lldb/trunk/test/lldbtest.py lldb/trunk/test/load_unload/TestLoadUnload.py lldb/trunk/test/order/TestOrderFile.py lldb/trunk/test/set_values/TestSetValues.py lldb/trunk/test/stl/TestSTL.py lldb/trunk/test/struct_types/TestStructTypes.py lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Modified: lldb/trunk/test/array_types/TestArrayTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/array_types/TestArrayTypes.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/array_types/TestArrayTypes.py (original) +++ lldb/trunk/test/array_types/TestArrayTypes.py Mon Aug 9 18:44:24 2010 @@ -21,14 +21,15 @@ self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: file ='main.c', line = 42, locations = 1"), - BREAK_POINT_CREATED) + BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - time.sleep(1) - self.assertTrue(res.Succeeded()) + #time.sleep(0.1) + self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint. self.ci.HandleCommand("thread list", res) + #print "thread list ->", res.GetOutput() self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and res.GetOutput().find('stop reason = breakpoint') > 0, @@ -38,7 +39,7 @@ self.ci.HandleCommand("breakpoint list", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().find('resolved, hit count = 1') > 0, - BREAK_POINT_HIT_ONCE) + BREAKPOINT_HIT_ONCE) # Issue 'variable list' command on several array-type variables. Modified: lldb/trunk/test/class_types/TestClassTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/class_types/TestClassTypes.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/class_types/TestClassTypes.py (original) +++ lldb/trunk/test/class_types/TestClassTypes.py Mon Aug 9 18:44:24 2010 @@ -3,9 +3,9 @@ import os, time import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestClassTypes(lldbtest.TestBase): +class TestClassTypes(TestBase): mydir = "class_types" @@ -14,34 +14,38 @@ res = self.res exe = os.path.join(os.getcwd(), "a.out") self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) # Break on the ctor function of class C. self.ci.HandleCommand("breakpoint set -f main.cpp -l 73", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.cpp', line = 73, locations = 1")) + "Breakpoint created: 1: file ='main.cpp', line = 73, locations = 1"), + BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - time.sleep(0.1) - self.assertTrue(res.Succeeded()) + #time.sleep(0.1) + self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint. self.ci.HandleCommand("thread list", res) - print "thread list ->", res.GetOutput() - self.assertTrue(res.Succeeded()) + #print "thread list ->", res.GetOutput() + self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and - res.GetOutput().find('stop reason = breakpoint') > 0) + res.GetOutput().find('stop reason = breakpoint') > 0, + STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, + BREAKPOINT_HIT_ONCE) # We should be stopped on the ctor function of class C. self.ci.HandleCommand("variable list this", res); self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().startswith('(class C *const) this = ')) + self.assertTrue(res.GetOutput().startswith('(class C *const) this = '), + VARIABLES_DISPLAYED_CORRECTLY) self.ci.HandleCommand("continue", res) self.assertTrue(res.Succeeded()) Modified: lldb/trunk/test/command_source/TestCommandSource.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/command_source/TestCommandSource.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/command_source/TestCommandSource.py (original) +++ lldb/trunk/test/command_source/TestCommandSource.py Mon Aug 9 18:44:24 2010 @@ -7,9 +7,9 @@ import os, time import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestCommandSource(lldbtest.TestBase): +class TestCommandSource(TestBase): mydir = "command_source" @@ -20,13 +20,13 @@ # Sourcing .lldb in the current working directory, which in turn imports # the "my" package that defines the date() function. self.ci.HandleCommand("command source .lldb", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('command source .lldb')) # Python should evaluate "my.date()" successfully. self.ci.HandleCommand("script my.date()", res) if (not res.Succeeded()): print res.GetError() - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('script my.date()')) if __name__ == '__main__': Modified: lldb/trunk/test/dead-strip/TestDeadStrip.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dead-strip/TestDeadStrip.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/dead-strip/TestDeadStrip.py (original) +++ lldb/trunk/test/dead-strip/TestDeadStrip.py Mon Aug 9 18:44:24 2010 @@ -5,9 +5,9 @@ import os, time import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestDeadStrip(lldbtest.TestBase): +class TestDeadStrip(TestBase): mydir = "dead-strip" @@ -16,32 +16,35 @@ res = self.res exe = os.path.join(os.getcwd(), "a.out") self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) # Break by function name f1 (live code). self.ci.HandleCommand("breakpoint set -s a.out -n f1", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: name = 'f1', module = a.out, locations = 1" - )) + ), + BREAKPOINT_CREATED) # Break by function name f2 (dead code). self.ci.HandleCommand("breakpoint set -s a.out -n f2", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 2: name = 'f2', module = a.out, locations = 0 " - "(pending)")) + "(pending)"), + BREAKPOINT_CREATED) # Break by function name f3 (live code). self.ci.HandleCommand("breakpoint set -s a.out -n f3", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 3: name = 'f3', module = a.out, locations = 1" - )) + ), + BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - time.sleep(0.1) - self.assertTrue(res.Succeeded()) + #time.sleep(0.1) + self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint (breakpoint #1). self.ci.HandleCommand("thread list", res) @@ -50,12 +53,14 @@ self.assertTrue(output.find('state is Stopped') > 0 and output.find('main.c:20') > 0 and output.find('where = a.out`f1') > 0 and - output.find('stop reason = breakpoint') > 0) + output.find('stop reason = breakpoint') > 0, + STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list 1", res) self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, + BREAKPOINT_HIT_ONCE) self.ci.HandleCommand("continue", res) self.assertTrue(res.Succeeded()) @@ -67,12 +72,14 @@ self.assertTrue(output.find('state is Stopped') > 0 and output.find('main.c:40') > 0 and output.find('where = a.out`f3') > 0 and - output.find('stop reason = breakpoint') > 0) + output.find('stop reason = breakpoint') > 0, + STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list 3", res) self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, + BREAKPOINT_HIT_ONCE) self.ci.HandleCommand("continue", res) self.assertTrue(res.Succeeded()) Modified: lldb/trunk/test/function_types/TestFunctionTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/function_types/TestFunctionTypes.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/function_types/TestFunctionTypes.py (original) +++ lldb/trunk/test/function_types/TestFunctionTypes.py Mon Aug 9 18:44:24 2010 @@ -3,9 +3,9 @@ import os, time import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestFunctionTypes(lldbtest.TestBase): +class TestFunctionTypes(TestBase): mydir = "function_types" @@ -14,39 +14,43 @@ res = self.res exe = os.path.join(os.getcwd(), "a.out") self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) # Break inside the main. self.ci.HandleCommand("breakpoint set -f main.c -l 21", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.c', line = 21, locations = 1")) + "Breakpoint created: 1: file ='main.c', line = 21, locations = 1"), + BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - time.sleep(0.1) - self.assertTrue(res.Succeeded()) + #time.sleep(0.1) + self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint. self.ci.HandleCommand("thread list", res) - print "thread list ->", res.GetOutput() - self.assertTrue(res.Succeeded()) + #print "thread list ->", res.GetOutput() + self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and - res.GetOutput().find('stop reason = breakpoint') > 0) + res.GetOutput().find('stop reason = breakpoint') > 0, + STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, + BREAKPOINT_HIT_ONCE) # Check that the 'callback' variable display properly. self.ci.HandleCommand("variable list callback", res); self.assertTrue(res.Succeeded()) output = res.GetOutput() - self.assertTrue(output.startswith('(int (*)(char const *)) callback =')) + self.assertTrue(output.startswith('(int (*)(char const *)) callback ='), + VARIABLES_DISPLAYED_CORRECTLY) # And that we can break on the callback function. self.ci.HandleCommand("breakpoint set -n string_not_empty", res); - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), BREAKPOINT_CREATED) self.ci.HandleCommand("continue", res) self.assertTrue(res.Succeeded()) @@ -57,7 +61,8 @@ #print "process status =", output self.assertTrue(output.find('where = a.out`string_not_empty') > 0 and output.find('main.c:12') > 0 and - output.find('stop reason = breakpoint') > 0) + output.find('stop reason = breakpoint') > 0, + STOPPED_DUE_TO_BREAKPOINT) self.ci.HandleCommand("continue", res) self.assertTrue(res.Succeeded()) Modified: lldb/trunk/test/global_variables/TestGlobalVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/global_variables/TestGlobalVariables.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/global_variables/TestGlobalVariables.py (original) +++ lldb/trunk/test/global_variables/TestGlobalVariables.py Mon Aug 9 18:44:24 2010 @@ -3,9 +3,9 @@ import os, time import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestGlobalVariables(lldbtest.TestBase): +class TestGlobalVariables(TestBase): mydir = "global_variables" @@ -14,29 +14,32 @@ res = self.res exe = os.path.join(os.getcwd(), "a.out") self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) # Break inside the main. self.ci.HandleCommand("breakpoint set -f main.c -l 20", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.c', line = 20, locations = 1")) + "Breakpoint created: 1: file ='main.c', line = 20, locations = 1"), + BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - time.sleep(0.1) - self.assertTrue(res.Succeeded()) + #time.sleep(0.1) + self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint. self.ci.HandleCommand("thread list", res) - print "thread list ->", res.GetOutput() - self.assertTrue(res.Succeeded()) + #print "thread list ->", res.GetOutput() + self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and - res.GetOutput().find('stop reason = breakpoint') > 0) + res.GetOutput().find('stop reason = breakpoint') > 0, + STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, + BREAKPOINT_HIT_ONCE) # Check that GLOBAL scopes are indicated for the variables. self.ci.HandleCommand("variable list -s -a", res); @@ -47,7 +50,8 @@ output.find('GLOBAL: g_file_global_int') > 0 and output.find('(int) 42') > 0 and output.find('GLOBAL: g_file_global_cstr') > 0 and - output.find('g_file_global_cstr') > 0) + output.find('g_file_global_cstr') > 0, + VARIABLES_DISPLAYED_CORRECTLY) self.ci.HandleCommand("continue", res) self.assertTrue(res.Succeeded()) Modified: lldb/trunk/test/help/TestHelp.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/help/TestHelp.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/help/TestHelp.py (original) +++ lldb/trunk/test/help/TestHelp.py Mon Aug 9 18:44:24 2010 @@ -7,9 +7,9 @@ import os, time import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestHelpCommand(lldbtest.TestBase): +class TestHelpCommand(TestBase): mydir = "help" @@ -17,22 +17,24 @@ """A simple test of 'help' command and its output.""" res = lldb.SBCommandReturnObject() self.ci.HandleCommand("help", res) - time.sleep(0.1) + #time.sleep(0.1) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - 'The following is a list of built-in, permanent debugger commands')) + 'The following is a list of built-in, permanent debugger commands'), + CMD_MSG('help')) def test_help_should_not_hang_emacsshell(self): """Command 'set term-width 0' should not hang the help command.""" res = lldb.SBCommandReturnObject() self.ci.HandleCommand("set term-width 0", res) - time.sleep(0.1) - self.assertTrue(res.Succeeded()) + #time.sleep(0.1) + self.assertTrue(res.Succeeded(), CMD_MSG('set term-width 0')) self.ci.HandleCommand("help", res) - time.sleep(0.1) + #time.sleep(0.1) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - 'The following is a list of built-in, permanent debugger commands')) + 'The following is a list of built-in, permanent debugger commands'), + CMD_MSG('help')) if __name__ == '__main__': Modified: lldb/trunk/test/lldbtest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/lldbtest.py (original) +++ lldb/trunk/test/lldbtest.py Mon Aug 9 18:44:24 2010 @@ -37,11 +37,13 @@ CURRENT_EXECUTABLE_SET = "Current executable set successfully" -COMMAND_HANDLED = "Command handled successfully" +RUN_STOPPED = "Process is stopped successfully" -BREAK_POINT_CREATED = "Breakpoint created successfully" +RUN_COMPLETED = "Process exited successfully" -BREAK_POINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1" +BREAKPOINT_CREATED = "Breakpoint created successfully" + +BREAKPOINT_HIT_ONCE = "Breakpoint resolved with hit cout = 1" STOPPED_DUE_TO_BREAKPOINT = "Process state is stopped due to breakpoint" @@ -49,6 +51,13 @@ VARIABLES_DISPLAYED_CORRECTLY = "Show specified variable(s) correctly" +# +# And a generic "Command '%s' returns successfully" message generator. +# +def CMD_MSG(command): + return "Command '%s' returns successfully" % (command) + + class TestBase(unittest2.TestCase): """This LLDB abstract base class is meant to be subclassed.""" Modified: lldb/trunk/test/load_unload/TestLoadUnload.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/load_unload/TestLoadUnload.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/load_unload/TestLoadUnload.py (original) +++ lldb/trunk/test/load_unload/TestLoadUnload.py Mon Aug 9 18:44:24 2010 @@ -5,9 +5,9 @@ import os, time import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestLoadUnload(lldbtest.TestBase): +class TestLoadUnload(TestBase): mydir = "load_unload" @@ -16,7 +16,7 @@ res = self.res exe = os.path.join(os.getcwd(), "a.out") self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) # Break by function name a_function (not yet loaded). self.ci.HandleCommand("breakpoint set -n a_function", res) @@ -24,25 +24,28 @@ self.assertTrue(res.GetOutput().startswith( "Breakpoint created: 1: name = 'a_function', locations = 0 " "(pending)" - )) + ), + BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - time.sleep(0.1) - self.assertTrue(res.Succeeded()) + #time.sleep(0.1) + self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint and at a_function. self.ci.HandleCommand("thread list", res) output = res.GetOutput() - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) self.assertTrue(output.find('state is Stopped') > 0 and output.find('a_function') > 0 and output.find('a.c:14') > 0 and - output.find('stop reason = breakpoint') > 0) + output.find('stop reason = breakpoint') > 0, + STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, + BREAKPOINT_HIT_ONCE) self.ci.HandleCommand("continue", res) self.assertTrue(res.Succeeded()) Modified: lldb/trunk/test/order/TestOrderFile.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/order/TestOrderFile.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/order/TestOrderFile.py (original) +++ lldb/trunk/test/order/TestOrderFile.py Mon Aug 9 18:44:24 2010 @@ -6,9 +6,9 @@ import re import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestOrderFile(lldbtest.TestBase): +class TestOrderFile(TestBase): mydir = "order" @@ -17,7 +17,7 @@ res = self.res exe = os.path.join(os.getcwd(), "a.out") self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) # Test that the debug symbols have Function f3 before Function f1. self.ci.HandleCommand("image dump symtab a.out", res) @@ -27,10 +27,11 @@ mo_f1 = re.search("Function +.+f1", output) # Match objects for f3 and f1 must exist and f3 must come before f1. - self.assertTrue(mo_f3 and mo_f1 and mo_f3.start() < mo_f1.start()) + self.assertTrue(mo_f3 and mo_f1 and mo_f3.start() < mo_f1.start(), + "Symbols have correct order by the order file") self.ci.HandleCommand("run", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), RUN_COMPLETED) if __name__ == '__main__': Modified: lldb/trunk/test/set_values/TestSetValues.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/set_values/TestSetValues.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/set_values/TestSetValues.py (original) +++ lldb/trunk/test/set_values/TestSetValues.py Mon Aug 9 18:44:24 2010 @@ -3,9 +3,9 @@ import os, time import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestSetValues(lldbtest.TestBase): +class TestSetValues(TestBase): mydir = "set_values" @@ -14,51 +14,59 @@ res = self.res exe = os.path.join(os.getcwd(), "a.out") self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) # Set breakpoints on several places to set program variables. self.ci.HandleCommand("breakpoint set -f main.c -l 15", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.c', line = 15, locations = 1")) + "Breakpoint created: 1: file ='main.c', line = 15, locations = 1"), + BREAKPOINT_CREATED) self.ci.HandleCommand("breakpoint set -f main.c -l 36", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 2: file ='main.c', line = 36, locations = 1")) + "Breakpoint created: 2: file ='main.c', line = 36, locations = 1"), + BREAKPOINT_CREATED) self.ci.HandleCommand("breakpoint set -f main.c -l 57", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 3: file ='main.c', line = 57, locations = 1")) + "Breakpoint created: 3: file ='main.c', line = 57, locations = 1"), + BREAKPOINT_CREATED) self.ci.HandleCommand("breakpoint set -f main.c -l 78", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 4: file ='main.c', line = 78, locations = 1")) + "Breakpoint created: 4: file ='main.c', line = 78, locations = 1"), + BREAKPOINT_CREATED) self.ci.HandleCommand("breakpoint set -f main.c -l 85", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 5: file ='main.c', line = 85, locations = 1")) + "Breakpoint created: 5: file ='main.c', line = 85, locations = 1"), + BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - time.sleep(0.1) - self.assertTrue(res.Succeeded()) + #time.sleep(0.1) + self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint. self.ci.HandleCommand("thread list", res) - print "thread list ->", res.GetOutput() - self.assertTrue(res.Succeeded()) + #print "thread list ->", res.GetOutput() + self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and - res.GetOutput().find('stop reason = breakpoint') > 0) + res.GetOutput().find('stop reason = breakpoint') > 0, + STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, + BREAKPOINT_HIT_ONCE) # main.c:15 # Check that 'variable list' displays the correct data type and value. self.ci.HandleCommand("variable list", res); self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().startswith("i = (char) 'a'")) + self.assertTrue(res.GetOutput().startswith("i = (char) 'a'"), + VARIABLES_DISPLAYED_CORRECTLY) # TODO: # Now set variable 'i' and check that it is correctly displayed. @@ -70,7 +78,8 @@ self.ci.HandleCommand("variable list", res); self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "i = (short unsigned int) 0x0021")) + "i = (short unsigned int) 0x0021"), + VARIABLES_DISPLAYED_CORRECTLY) # TODO: # Now set variable 'i' and check that it is correctly displayed. @@ -81,7 +90,8 @@ # Check that 'variable list' displays the correct data type and value. self.ci.HandleCommand("variable list", res); self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().startswith("i = (long int) 33")) + self.assertTrue(res.GetOutput().startswith("i = (long int) 33"), + VARIABLES_DISPLAYED_CORRECTLY) # TODO: # Now set variable 'i' and check that it is correctly displayed. @@ -92,7 +102,8 @@ # Check that 'variable list' displays the correct data type and value. self.ci.HandleCommand("variable list", res); self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().startswith("i = (double) 3.14159")) + self.assertTrue(res.GetOutput().startswith("i = (double) 3.14159"), + VARIABLES_DISPLAYED_CORRECTLY) # TODO: # Now set variable 'i' and check that it is correctly displayed. @@ -103,7 +114,8 @@ # Check that 'variable list' displays the correct data type and value. self.ci.HandleCommand("variable list", res); self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().startswith("i = (long double) ")) + self.assertTrue(res.GetOutput().startswith("i = (long double) "), + VARIABLES_DISPLAYED_CORRECTLY) # TODO: # Now set variable 'i' and check that it is correctly displayed. Modified: lldb/trunk/test/stl/TestSTL.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/stl/TestSTL.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/stl/TestSTL.py (original) +++ lldb/trunk/test/stl/TestSTL.py Mon Aug 9 18:44:24 2010 @@ -5,9 +5,9 @@ import os, time import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestSTL(lldbtest.TestBase): +class TestSTL(TestBase): mydir = "stl" @@ -20,42 +20,44 @@ #self.ci.HandleCommand("log enable -f /tmp/lldb.log lldb default", res) #self.assertTrue(res.Succeeded()) self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) # Break on line 13 of main.cpp. self.ci.HandleCommand("breakpoint set -f main.cpp -l 13", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.cpp', line = 13, locations = 1") - ) + "Breakpoint created: 1: file ='main.cpp', line = 13, locations = 1" + ), + BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - time.sleep(0.1) - self.assertTrue(res.Succeeded()) + #time.sleep(0.1) + self.assertTrue(res.Succeeded(), RUN_STOPPED) # Stop at 'std::string hello_world ("Hello World!");'. self.ci.HandleCommand("thread list", res) - print "thread list ->", res.GetOutput() + #print "thread list ->", res.GetOutput() self.assertTrue(res.Succeeded()) output = res.GetOutput() self.assertTrue(output.find('main.cpp:13') > 0 and - output.find('stop reason = breakpoint') > 0) + output.find('stop reason = breakpoint') > 0, + STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, + BREAKPOINT_HIT_ONCE) # Now do 'thread step-in', we should stop on the basic_string template. self.ci.HandleCommand("thread step-in", res) - print "thread step-in:", res.GetOutput() + #print "thread step-in:", res.GetOutput() # # This assertion currently always fails. # This might be related: rdar://problem/8247112. # - self.assertTrue(res.Succeeded(), - 'Command "thread step-in" returns successfully') + self.assertTrue(res.Succeeded(), CMD_MSG("thread step-in")) #self.ci.HandleCommand("process status", res) #print "process status:", res.GetOutput() @@ -66,7 +68,7 @@ self.assertTrue(output.find('[inlined]') > 0 and output.find('basic_string.h') and output.find('stop reason = step in,') > 0, - 'Command "thread backtrace" shows we stepped in STL') + "Command 'thread backtrace' shows we stepped in STL") self.ci.HandleCommand("continue", res) self.assertTrue(res.Succeeded()) Modified: lldb/trunk/test/struct_types/TestStructTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/struct_types/TestStructTypes.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/struct_types/TestStructTypes.py (original) +++ lldb/trunk/test/struct_types/TestStructTypes.py Mon Aug 9 18:44:24 2010 @@ -7,9 +7,9 @@ import os, time import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestStructTypes(lldbtest.TestBase): +class TestStructTypes(TestBase): mydir = "struct_types" @@ -18,31 +18,34 @@ res = self.res exe = os.path.join(os.getcwd(), "a.out") self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) # Break on the ctor function of class C. self.ci.HandleCommand("breakpoint set -f main.c -l 14", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.c', line = 14, locations = 1")) + "Breakpoint created: 1: file ='main.c', line = 14, locations = 1"), + BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - time.sleep(0.1) - self.assertTrue(res.Succeeded()) + #time.sleep(0.1) + self.assertTrue(res.Succeeded(), RUN_STOPPED) # We should be stopped on the first executable statement within the # function where the original breakpoint was attempted. self.ci.HandleCommand("thread backtrace", res) - print "thread backtrace ->", res.GetOutput() + #print "thread backtrace ->", res.GetOutput() self.assertTrue(res.Succeeded()) output = res.GetOutput() self.assertTrue(output.find('main.c:20') > 0 and - output.find('stop reason = breakpoint') > 0) + output.find('stop reason = breakpoint') > 0, + STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, + BREAKPOINT_HIT_ONCE) self.ci.HandleCommand("continue", res) self.assertTrue(res.Succeeded()) Modified: lldb/trunk/test/unsigned_types/TestUnsignedTypes.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/unsigned_types/TestUnsignedTypes.py?rev=110625&r1=110624&r2=110625&view=diff ============================================================================== --- lldb/trunk/test/unsigned_types/TestUnsignedTypes.py (original) +++ lldb/trunk/test/unsigned_types/TestUnsignedTypes.py Mon Aug 9 18:44:24 2010 @@ -6,9 +6,9 @@ import re import unittest2 import lldb -import lldbtest +from lldbtest import * -class TestUnsignedTypes(lldbtest.TestBase): +class TestUnsignedTypes(TestBase): mydir = "unsigned_types" @@ -17,33 +17,36 @@ res = self.res exe = os.path.join(os.getcwd(), "a.out") self.ci.HandleCommand("file " + exe, res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) # Break on line 19 in main() aftre the variables are assigned values. self.ci.HandleCommand("breakpoint set -f main.cpp -l 19", res) self.assertTrue(res.Succeeded()) self.assertTrue(res.GetOutput().startswith( - "Breakpoint created: 1: file ='main.cpp', line = 19, locations = 1") - ) + "Breakpoint created: 1: file ='main.cpp', line = 19, locations = 1" + ), + BREAKPOINT_CREATED) self.ci.HandleCommand("run", res) - time.sleep(0.1) - self.assertTrue(res.Succeeded()) + #time.sleep(0.1) + self.assertTrue(res.Succeeded(), RUN_STOPPED) # The stop reason of the thread should be breakpoint. self.ci.HandleCommand("thread list", res) - self.assertTrue(res.Succeeded()) + self.assertTrue(res.Succeeded(), CMD_MSG('thread list')) self.assertTrue(res.GetOutput().find('state is Stopped') > 0 and - res.GetOutput().find('stop reason = breakpoint') > 0) + res.GetOutput().find('stop reason = breakpoint') > 0, + STOPPED_DUE_TO_BREAKPOINT) # The breakpoint should have a hit count of 1. self.ci.HandleCommand("breakpoint list", res) self.assertTrue(res.Succeeded()) - self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0) + self.assertTrue(res.GetOutput().find(' resolved, hit count = 1') > 0, + BREAKPOINT_HIT_ONCE) # Test that unsigned types display correctly. self.ci.HandleCommand("variable list -a", res) - print "variable list -a ->", res.GetOutput() + #print "variable list -a ->", res.GetOutput() self.assertTrue(res.Succeeded()) output = res.GetOutput() self.assertTrue( @@ -59,7 +62,9 @@ output.find("the_unsigned_long_long = (long long unsigned int)" " 0x0000000000000063") > 0 and - output.find("the_uint32 = (uint32_t) 0x00000063") + output.find("the_uint32 = (uint32_t) 0x00000063"), + + VARIABLES_DISPLAYED_CORRECTLY ) self.ci.HandleCommand("continue", res) From jmolenda at apple.com Mon Aug 9 18:56:27 2010 From: jmolenda at apple.com (Jason Molenda) Date: Mon, 09 Aug 2010 23:56:27 -0000 Subject: [Lldb-commits] [lldb] r110626 - in /lldb/trunk/source/Plugins/Process/Utility/libunwind/src: AddressSpace.hpp ArchDefaultUnwinder.hpp DwarfInstructions.hpp Registers.hpp RemoteDebuggerDummyUnwinder.hpp RemoteProcInfo.hpp UnwindCursor.hpp Message-ID: <20100809235627.D091E2A6C12C@llvm.org> Author: jmolenda Date: Mon Aug 9 18:56:27 2010 New Revision: 110626 URL: http://llvm.org/viewvc/llvm-project?rev=110626&view=rev Log: Remove unused powerpc unwind support. Modified: lldb/trunk/source/Plugins/Process/Utility/libunwind/src/AddressSpace.hpp lldb/trunk/source/Plugins/Process/Utility/libunwind/src/ArchDefaultUnwinder.hpp lldb/trunk/source/Plugins/Process/Utility/libunwind/src/DwarfInstructions.hpp lldb/trunk/source/Plugins/Process/Utility/libunwind/src/Registers.hpp lldb/trunk/source/Plugins/Process/Utility/libunwind/src/RemoteDebuggerDummyUnwinder.hpp lldb/trunk/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp lldb/trunk/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp Modified: lldb/trunk/source/Plugins/Process/Utility/libunwind/src/AddressSpace.hpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/libunwind/src/AddressSpace.hpp?rev=110626&r1=110625&r2=110626&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/libunwind/src/AddressSpace.hpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/libunwind/src/AddressSpace.hpp Mon Aug 9 18:56:27 2010 @@ -24,7 +24,6 @@ #if !defined (SUPPORT_REMOTE_UNWINDING) #include #endif -#include #include #include Modified: lldb/trunk/source/Plugins/Process/Utility/libunwind/src/ArchDefaultUnwinder.hpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/libunwind/src/ArchDefaultUnwinder.hpp?rev=110626&r1=110625&r2=110626&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/libunwind/src/ArchDefaultUnwinder.hpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/libunwind/src/ArchDefaultUnwinder.hpp Mon Aug 9 18:56:27 2010 @@ -102,13 +102,6 @@ return stepByArchitectureDefault_x86 (addressSpace, registers, pc, 4); } -template -int stepByArchitectureDefault (A& addressSpace, Registers_ppc& registers, - uint64_t pc) { - ABORT("Remote unwinding not supported for ppc."); - return UNW_EUNSPEC; -} - }; // namespace lldb_private #endif // SUPPORT_REMOTE_UNWINDING Modified: lldb/trunk/source/Plugins/Process/Utility/libunwind/src/DwarfInstructions.hpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/libunwind/src/DwarfInstructions.hpp?rev=110626&r1=110625&r2=110626&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/libunwind/src/DwarfInstructions.hpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/libunwind/src/DwarfInstructions.hpp Mon Aug 9 18:56:27 2010 @@ -129,15 +129,6 @@ static compact_unwind_encoding_t createCompactEncodingFromProlog(A& addressSpace, pint_t funcAddr, const Registers_x86_64&, const typename CFI_Parser::PrologInfo& prolog, char warningBuffer[1024]); - - // ppc specific variants - static int lastRestoreReg(const Registers_ppc&); - static bool isReturnAddressRegister(int regNum, const Registers_ppc&); - static pint_t getCFA(A& addressSpace, const typename CFI_Parser::PrologInfo& prolog, const Registers_ppc&); - static compact_unwind_encoding_t encodeToUseDwarf(const Registers_ppc&); - static compact_unwind_encoding_t createCompactEncodingFromProlog(A& addressSpace, pint_t funcAddr, - const Registers_ppc&, const typename CFI_Parser::PrologInfo& prolog, - char warningBuffer[1024]); }; @@ -1626,56 +1617,6 @@ - - -// -// ppc specific functions -// -template -int DwarfInstructions::lastRestoreReg(const Registers_ppc&) -{ - COMPILE_TIME_ASSERT( (int)CFI_Parser::kMaxRegisterNumber > (int)UNW_PPC_SPEFSCR ); - return UNW_PPC_SPEFSCR; -} - -template -bool DwarfInstructions::isReturnAddressRegister(int regNum, const Registers_ppc&) -{ - return (regNum == UNW_PPC_LR); -} - -template -typename A::pint_t DwarfInstructions::getCFA(A& addressSpace, const typename CFI_Parser::PrologInfo& prolog, - const Registers_ppc& registers) -{ - if ( prolog.cfaRegister != 0 ) - return registers.getRegister(prolog.cfaRegister) + prolog.cfaRegisterOffset; - else if ( prolog.cfaExpression != 0 ) - return evaluateExpression(prolog.cfaExpression, addressSpace, registers, 0); - else - ABORT("getCFA(): unknown location for ppc cfa"); -} - - -template -compact_unwind_encoding_t DwarfInstructions::encodeToUseDwarf(const Registers_ppc&) -{ - return UNWIND_X86_MODE_DWARF; -} - - -template -compact_unwind_encoding_t DwarfInstructions::createCompactEncodingFromProlog(A& addressSpace, pint_t funcAddr, - const Registers_ppc& r, const typename CFI_Parser::PrologInfo& prolog, - char warningBuffer[1024]) -{ - warningBuffer[0] = '\0'; - return UNWIND_X86_MODE_DWARF; -} - - - - } // namespace lldb_private Modified: lldb/trunk/source/Plugins/Process/Utility/libunwind/src/Registers.hpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/libunwind/src/Registers.hpp?rev=110626&r1=110625&r2=110626&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/libunwind/src/Registers.hpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/libunwind/src/Registers.hpp Mon Aug 9 18:56:27 2010 @@ -21,7 +21,6 @@ #include #include #include -#include #include #include "libunwind.h" @@ -446,534 +445,6 @@ } -/// -/// Registers_ppc holds the register state of a thread in a 32-bit PowerPC process. -/// -class Registers_ppc -{ -public: - Registers_ppc(); - Registers_ppc(const void* registers); - - bool validRegister(int num) const; - uint32_t getRegister(int num) const; - void setRegister(int num, uint32_t value); - bool validFloatRegister(int num) const; - double getFloatRegister(int num) const; - void setFloatRegister(int num, double value); - bool validVectorRegister(int num) const; - v128 getVectorRegister(int num) const; - void setVectorRegister(int num, v128 value); - void jumpto() {} - const char* getRegisterName(int num); - uint64_t getSP() const { return fRegisters.__r1; } - void setSP(uint64_t value) { fRegisters.__r1 = value; } - uint64_t getIP() const { return fRegisters.__srr0; } - void setIP(uint64_t value) { fRegisters.__srr0 = value; } -private: - ppc_thread_state_t fRegisters; - ppc_float_state_t fFloatRegisters; - v128 fVectorRegisters[32]; // offset 424 -}; - - - -inline Registers_ppc::Registers_ppc(const void* registers) -{ - COMPILE_TIME_ASSERT( sizeof(Registers_ppc) < sizeof(unw_context_t) ); - fRegisters = *((ppc_thread_state_t*)registers); - fFloatRegisters = *((ppc_float_state_t*)((char*)registers+160)); - memcpy(fVectorRegisters, ((char*)registers+424), sizeof(fVectorRegisters)); -} - -inline Registers_ppc::Registers_ppc() -{ - bzero(&fRegisters, sizeof(fRegisters)); - bzero(&fFloatRegisters, sizeof(fFloatRegisters)); - bzero(&fVectorRegisters, sizeof(fVectorRegisters)); -} - - -inline bool Registers_ppc::validRegister(int regNum) const -{ - if ( regNum == UNW_REG_IP ) - return true; - if ( regNum == UNW_REG_SP ) - return true; - if ( regNum == UNW_PPC_VRSAVE ) - return true; - if ( regNum < 0 ) - return false; - if ( regNum <= UNW_PPC_R31 ) - return true; - if ( regNum == UNW_PPC_MQ ) - return true; - if ( regNum == UNW_PPC_LR ) - return true; - if ( regNum == UNW_PPC_CTR ) - return true; - if ( (UNW_PPC_CR0 <= regNum) && (regNum <= UNW_PPC_CR7) ) - return true; - return false; -} - - -inline uint32_t Registers_ppc::getRegister(int regNum) const -{ - switch ( regNum ) { - case UNW_REG_IP: - return fRegisters.__srr0; - case UNW_REG_SP: - return fRegisters.__r1; - case UNW_PPC_R0: - return fRegisters.__r0; - case UNW_PPC_R1: - return fRegisters.__r1; - case UNW_PPC_R2: - return fRegisters.__r2; - case UNW_PPC_R3: - return fRegisters.__r3; - case UNW_PPC_R4: - return fRegisters.__r4; - case UNW_PPC_R5: - return fRegisters.__r5; - case UNW_PPC_R6: - return fRegisters.__r6; - case UNW_PPC_R7: - return fRegisters.__r7; - case UNW_PPC_R8: - return fRegisters.__r8; - case UNW_PPC_R9: - return fRegisters.__r9; - case UNW_PPC_R10: - return fRegisters.__r10; - case UNW_PPC_R11: - return fRegisters.__r11; - case UNW_PPC_R12: - return fRegisters.__r12; - case UNW_PPC_R13: - return fRegisters.__r13; - case UNW_PPC_R14: - return fRegisters.__r14; - case UNW_PPC_R15: - return fRegisters.__r15; - case UNW_PPC_R16: - return fRegisters.__r16; - case UNW_PPC_R17: - return fRegisters.__r17; - case UNW_PPC_R18: - return fRegisters.__r18; - case UNW_PPC_R19: - return fRegisters.__r19; - case UNW_PPC_R20: - return fRegisters.__r20; - case UNW_PPC_R21: - return fRegisters.__r21; - case UNW_PPC_R22: - return fRegisters.__r22; - case UNW_PPC_R23: - return fRegisters.__r23; - case UNW_PPC_R24: - return fRegisters.__r24; - case UNW_PPC_R25: - return fRegisters.__r25; - case UNW_PPC_R26: - return fRegisters.__r26; - case UNW_PPC_R27: - return fRegisters.__r27; - case UNW_PPC_R28: - return fRegisters.__r28; - case UNW_PPC_R29: - return fRegisters.__r29; - case UNW_PPC_R30: - return fRegisters.__r30; - case UNW_PPC_R31: - return fRegisters.__r31; - case UNW_PPC_LR: - return fRegisters.__lr; - case UNW_PPC_CR0: - return (fRegisters.__cr & 0xF0000000); - case UNW_PPC_CR1: - return (fRegisters.__cr & 0x0F000000); - case UNW_PPC_CR2: - return (fRegisters.__cr & 0x00F00000); - case UNW_PPC_CR3: - return (fRegisters.__cr & 0x000F0000); - case UNW_PPC_CR4: - return (fRegisters.__cr & 0x0000F000); - case UNW_PPC_CR5: - return (fRegisters.__cr & 0x00000F00); - case UNW_PPC_CR6: - return (fRegisters.__cr & 0x000000F0); - case UNW_PPC_CR7: - return (fRegisters.__cr & 0x0000000F); - case UNW_PPC_VRSAVE: - return fRegisters.__vrsave; - } - ABORT("unsupported ppc register"); -} - - -inline void Registers_ppc::setRegister(int regNum, uint32_t value) -{ - //fprintf(stderr, "Registers_ppc::setRegister(%d, 0x%08X)\n", regNum, value); - switch ( regNum ) { - case UNW_REG_IP: - fRegisters.__srr0 = value; - return; - case UNW_REG_SP: - fRegisters.__r1 = value; - return; - case UNW_PPC_R0: - fRegisters.__r0 = value; - return; - case UNW_PPC_R1: - fRegisters.__r1 = value; - return; - case UNW_PPC_R2: - fRegisters.__r2 = value; - return; - case UNW_PPC_R3: - fRegisters.__r3 = value; - return; - case UNW_PPC_R4: - fRegisters.__r4 = value; - return; - case UNW_PPC_R5: - fRegisters.__r5 = value; - return; - case UNW_PPC_R6: - fRegisters.__r6 = value; - return; - case UNW_PPC_R7: - fRegisters.__r7 = value; - return; - case UNW_PPC_R8: - fRegisters.__r8 = value; - return; - case UNW_PPC_R9: - fRegisters.__r9 = value; - return; - case UNW_PPC_R10: - fRegisters.__r10 = value; - return; - case UNW_PPC_R11: - fRegisters.__r11 = value; - return; - case UNW_PPC_R12: - fRegisters.__r12 = value; - return; - case UNW_PPC_R13: - fRegisters.__r13 = value; - return; - case UNW_PPC_R14: - fRegisters.__r14 = value; - return; - case UNW_PPC_R15: - fRegisters.__r15 = value; - return; - case UNW_PPC_R16: - fRegisters.__r16 = value; - return; - case UNW_PPC_R17: - fRegisters.__r17 = value; - return; - case UNW_PPC_R18: - fRegisters.__r18 = value; - return; - case UNW_PPC_R19: - fRegisters.__r19 = value; - return; - case UNW_PPC_R20: - fRegisters.__r20 = value; - return; - case UNW_PPC_R21: - fRegisters.__r21 = value; - return; - case UNW_PPC_R22: - fRegisters.__r22 = value; - return; - case UNW_PPC_R23: - fRegisters.__r23 = value; - return; - case UNW_PPC_R24: - fRegisters.__r24 = value; - return; - case UNW_PPC_R25: - fRegisters.__r25 = value; - return; - case UNW_PPC_R26: - fRegisters.__r26 = value; - return; - case UNW_PPC_R27: - fRegisters.__r27 = value; - return; - case UNW_PPC_R28: - fRegisters.__r28 = value; - return; - case UNW_PPC_R29: - fRegisters.__r29 = value; - return; - case UNW_PPC_R30: - fRegisters.__r30 = value; - return; - case UNW_PPC_R31: - fRegisters.__r31 = value; - return; - case UNW_PPC_MQ: - fRegisters.__mq = value; - return; - case UNW_PPC_LR: - fRegisters.__lr = value; - return; - case UNW_PPC_CTR: - fRegisters.__ctr = value; - return; - case UNW_PPC_CR0: - fRegisters.__cr &= 0x0FFFFFFF; - fRegisters.__cr |= (value & 0xF0000000); - return; - case UNW_PPC_CR1: - fRegisters.__cr &= 0xF0FFFFFF; - fRegisters.__cr |= (value & 0x0F000000); - return; - case UNW_PPC_CR2: - fRegisters.__cr &= 0xFF0FFFFF; - fRegisters.__cr |= (value & 0x00F00000); - return; - case UNW_PPC_CR3: - fRegisters.__cr &= 0xFFF0FFFF; - fRegisters.__cr |= (value & 0x000F0000); - return; - case UNW_PPC_CR4: - fRegisters.__cr &= 0xFFFF0FFF; - fRegisters.__cr |= (value & 0x0000F000); - return; - case UNW_PPC_CR5: - fRegisters.__cr &= 0xFFFFF0FF; - fRegisters.__cr |= (value & 0x00000F00); - return; - case UNW_PPC_CR6: - fRegisters.__cr &= 0xFFFFFF0F; - fRegisters.__cr |= (value & 0x000000F0); - return; - case UNW_PPC_CR7: - fRegisters.__cr &= 0xFFFFFFF0; - fRegisters.__cr |= (value & 0x0000000F); - return; - case UNW_PPC_VRSAVE: - fRegisters.__vrsave = value; - return; - // not saved - return; - case UNW_PPC_XER: - fRegisters.__xer = value; - return; - case UNW_PPC_AP: - case UNW_PPC_VSCR: - case UNW_PPC_SPEFSCR: - // not saved - return; - } - ABORT("unsupported ppc register"); -} - -inline bool Registers_ppc::validFloatRegister(int regNum) const -{ - if ( regNum < UNW_PPC_F0 ) - return false; - if ( regNum > UNW_PPC_F31 ) - return false; - return true; -} - -inline double Registers_ppc::getFloatRegister(int regNum) const -{ - assert(validFloatRegister(regNum)); - return fFloatRegisters.__fpregs[regNum-UNW_PPC_F0]; -} - -inline void Registers_ppc::setFloatRegister(int regNum, double value) -{ - //fprintf(stderr, "Registers_ppc::setFloatRegister(%d, %g))\n", regNum, value); - assert(validFloatRegister(regNum)); - fFloatRegisters.__fpregs[regNum-UNW_PPC_F0] = value; -} - - -inline bool Registers_ppc::validVectorRegister(int regNum) const -{ - if ( regNum < UNW_PPC_V0 ) - return false; - if ( regNum > UNW_PPC_V31 ) - return false; - return true; -} - -v128 Registers_ppc::getVectorRegister(int regNum) const -{ - assert(validVectorRegister(regNum)); - v128 result = fVectorRegisters[regNum-UNW_PPC_V0]; - //fprintf(stderr, "Registers_ppc::getVectorRegister(this=%p, %d) => <0x%08X, 0x%08X, 0x%08X, 0x%08X> \n", - // this, regNum, result.vec[0], result.vec[1], result.vec[2], result.vec[3]); - return result; -} - -void Registers_ppc::setVectorRegister(int regNum, v128 value) -{ - assert(validVectorRegister(regNum)); - //fprintf(stderr, "Registers_ppc::setVectorRegister(this=%p, %d) <0x%08X, 0x%08X, 0x%08X, 0x%08X> => <0x%08X, 0x%08X, 0x%08X, 0x%08X> \n", - // this, regNum, fVectorRegisters[regNum-UNW_PPC_V0].vec[0], fVectorRegisters[regNum-UNW_PPC_V0].vec[1], fVectorRegisters[regNum-UNW_PPC_V0].vec[2], - // fVectorRegisters[regNum-UNW_PPC_V0].vec[3], value.vec[0], value.vec[1], value.vec[2], value.vec[3]); - fVectorRegisters[regNum-UNW_PPC_V0] = value; -} - - -inline const char* Registers_ppc::getRegisterName(int regNum) -{ - switch ( regNum ) { - case UNW_REG_IP: - return "ip"; - case UNW_REG_SP: - return "sp"; - case UNW_PPC_R0: - return "r0"; - case UNW_PPC_R1: - return "r1"; - case UNW_PPC_R2: - return "r2"; - case UNW_PPC_R3: - return "r3"; - case UNW_PPC_R4: - return "r4"; - case UNW_PPC_R5: - return "r5"; - case UNW_PPC_R6: - return "r6"; - case UNW_PPC_R7: - return "r7"; - case UNW_PPC_R8: - return "r8"; - case UNW_PPC_R9: - return "r9"; - case UNW_PPC_R10: - return "r10"; - case UNW_PPC_R11: - return "r11"; - case UNW_PPC_R12: - return "r12"; - case UNW_PPC_R13: - return "r13"; - case UNW_PPC_R14: - return "r14"; - case UNW_PPC_R15: - return "r15"; - case UNW_PPC_R16: - return "r16"; - case UNW_PPC_R17: - return "r17"; - case UNW_PPC_R18: - return "r18"; - case UNW_PPC_R19: - return "r19"; - case UNW_PPC_R20: - return "r20"; - case UNW_PPC_R21: - return "r21"; - case UNW_PPC_R22: - return "r22"; - case UNW_PPC_R23: - return "r23"; - case UNW_PPC_R24: - return "r24"; - case UNW_PPC_R25: - return "r25"; - case UNW_PPC_R26: - return "r26"; - case UNW_PPC_R27: - return "r27"; - case UNW_PPC_R28: - return "r28"; - case UNW_PPC_R29: - return "r29"; - case UNW_PPC_R30: - return "r30"; - case UNW_PPC_R31: - return "r31"; - case UNW_PPC_F0: - return "fp0"; - case UNW_PPC_F1: - return "fp1"; - case UNW_PPC_F2: - return "fp2"; - case UNW_PPC_F3: - return "fp3"; - case UNW_PPC_F4: - return "fp4"; - case UNW_PPC_F5: - return "fp5"; - case UNW_PPC_F6: - return "fp6"; - case UNW_PPC_F7: - return "fp7"; - case UNW_PPC_F8: - return "fp8"; - case UNW_PPC_F9: - return "fp9"; - case UNW_PPC_F10: - return "fp10"; - case UNW_PPC_F11: - return "fp11"; - case UNW_PPC_F12: - return "fp12"; - case UNW_PPC_F13: - return "fp13"; - case UNW_PPC_F14: - return "fp14"; - case UNW_PPC_F15: - return "fp15"; - case UNW_PPC_F16: - return "fp16"; - case UNW_PPC_F17: - return "fp17"; - case UNW_PPC_F18: - return "fp18"; - case UNW_PPC_F19: - return "fp19"; - case UNW_PPC_F20: - return "fp20"; - case UNW_PPC_F21: - return "fp21"; - case UNW_PPC_F22: - return "fp22"; - case UNW_PPC_F23: - return "fp23"; - case UNW_PPC_F24: - return "fp24"; - case UNW_PPC_F25: - return "fp25"; - case UNW_PPC_F26: - return "fp26"; - case UNW_PPC_F27: - return "fp27"; - case UNW_PPC_F28: - return "fp28"; - case UNW_PPC_F29: - return "fp29"; - case UNW_PPC_F30: - return "fp30"; - case UNW_PPC_F31: - return "fp31"; - case UNW_PPC_LR: - return "lr"; - default: - return "unknown register"; - } - - -} - - } // namespace lldb_private Modified: lldb/trunk/source/Plugins/Process/Utility/libunwind/src/RemoteDebuggerDummyUnwinder.hpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/libunwind/src/RemoteDebuggerDummyUnwinder.hpp?rev=110626&r1=110625&r2=110626&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/libunwind/src/RemoteDebuggerDummyUnwinder.hpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/libunwind/src/RemoteDebuggerDummyUnwinder.hpp Mon Aug 9 18:56:27 2010 @@ -72,14 +72,6 @@ return UNW_STEP_SUCCESS; } -template -int stepOutOfDebuggerDummyFrame (A& addressSpace, Registers_ppc& registers, - uint64_t ip, uint64_t sp) -{ - ABORT ("stepping out of a debugger dummy frame not supported on ppc"); - return UNW_EUNSPEC; -} - }; // namespace lldb_private #endif // SUPPORT_REMOTE_UNWINDING Modified: lldb/trunk/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp?rev=110626&r1=110625&r2=110626&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/libunwind/src/RemoteProcInfo.hpp Mon Aug 9 18:56:27 2010 @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -977,11 +976,6 @@ #undef FILLREG } - -void getRemoteContext (RemoteProcInfo* procinfo, Registers_ppc& r, void *arg) { - ABORT("ppc get remote context not implemented."); -} - }; // namespace lldb_private Modified: lldb/trunk/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp?rev=110626&r1=110625&r2=110626&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp (original) +++ lldb/trunk/source/Plugins/Process/Utility/libunwind/src/UnwindCursor.hpp Mon Aug 9 18:56:27 2010 @@ -337,8 +337,6 @@ { return CompactUnwinder_x86_64::stepWithCompactEncoding(fInfo.format, fInfo.start_ip, fAddressSpace, fRegisters); } int stepWithCompactEncoding(Registers_x86&) { return CompactUnwinder_x86::stepWithCompactEncoding(fInfo.format, fInfo.start_ip, fAddressSpace, fRegisters); } - int stepWithCompactEncoding(Registers_ppc&) - { return UNW_EINVAL; } #if FOR_DYLD #if __ppc__ @@ -381,13 +379,10 @@ #endif return false; } - virtual bool dwarfWithOffset(Registers_ppc&, uint32_t& offset) const { return true; } - virtual compact_unwind_encoding_t dwarfEncoding() const { R dummy; return dwarfEncoding(dummy); } virtual compact_unwind_encoding_t dwarfEncoding(Registers_x86_64&) const { return UNWIND_X86_64_MODE_DWARF; } virtual compact_unwind_encoding_t dwarfEncoding(Registers_x86&) const { return UNWIND_X86_MODE_DWARF; } - virtual compact_unwind_encoding_t dwarfEncoding(Registers_ppc&) const { return 0; } unw_proc_info_t fInfo; R fRegisters; From jingham at apple.com Mon Aug 9 19:59:59 2010 From: jingham at apple.com (Jim Ingham) Date: Tue, 10 Aug 2010 00:59:59 -0000 Subject: [Lldb-commits] [lldb] r110637 - in /lldb/trunk: include/lldb/Target/StopInfo.h source/Target/Process.cpp source/Target/StopInfo.cpp Message-ID: <20100810005959.55BEC2A6C12C@llvm.org> Author: jingham Date: Mon Aug 9 19:59:59 2010 New Revision: 110637 URL: http://llvm.org/viewvc/llvm-project?rev=110637&view=rev Log: Make breakpoint commands work again. Added a PerformAction to the stop info - actions are run when the stop event is pulled from the event queue. Then made the StopInfoBreakpoint's PerformAction do the breakpoint command. Also fixed the StopInfoBreakpoint's GetDescription so it gets the breakpoint location info, not the breakpoint site info. Modified: lldb/trunk/include/lldb/Target/StopInfo.h lldb/trunk/source/Target/Process.cpp lldb/trunk/source/Target/StopInfo.cpp Modified: lldb/trunk/include/lldb/Target/StopInfo.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/StopInfo.h?rev=110637&r1=110636&r2=110637&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/StopInfo.h (original) +++ lldb/trunk/include/lldb/Target/StopInfo.h Mon Aug 9 19:59:59 2010 @@ -54,6 +54,13 @@ virtual lldb::StopReason GetStopReason () const = 0; + + // Perform any action that is associated with this stop. This is done as the + // Event is removed from the event queue. + virtual void + PerformAction (Event *event_ptr) + { + } // Stop the thread by default. Subclasses can override this to allow // the thread to continue if desired. Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=110637&r1=110636&r2=110637&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Mon Aug 9 19:59:59 2010 @@ -1746,8 +1746,6 @@ int num_threads = m_process_sp->GetThreadList().GetSize(); int idx; - int32_t should_stop_count = -1; - int32_t should_run_count = -1; for (idx = 0; idx < num_threads; ++idx) { lldb::ThreadSP thread_sp = m_process_sp->GetThreadList().GetThreadAtIndex(idx); @@ -1755,25 +1753,14 @@ StopInfo *stop_info = thread_sp->GetStopInfo (); if (stop_info) { - if (stop_info->ShouldStop(event_ptr)) - { - if (should_stop_count < 0) - should_stop_count = 1; - else - should_stop_count++; - } - else - { - if (should_run_count < 0) - should_run_count = 1; - else - should_run_count++; - } + stop_info->PerformAction(event_ptr); } } - // Are we secretly watching the private state here? Should we look at the - // should_run_count or the "should_stop_count" and the "should_run_count"??? + // The stop action might restart the target. If it does, then we want to mark that in the + // event so that whoever is receiving it will know to wait for the running event and reflect + // that state appropriately. + if (m_process_sp->GetPrivateState() == eStateRunning) SetRestarted(true); } Modified: lldb/trunk/source/Target/StopInfo.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/StopInfo.cpp?rev=110637&r1=110636&r2=110637&view=diff ============================================================================== --- lldb/trunk/source/Target/StopInfo.cpp (original) +++ lldb/trunk/source/Target/StopInfo.cpp Mon Aug 9 19:59:59 2010 @@ -96,6 +96,35 @@ } return m_should_stop; } + + virtual void + PerformAction (Event *event_ptr) + { + BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value)); + if (bp_site_sp) + { + size_t num_owners = bp_site_sp->GetNumberOfOwners(); + for (size_t j = 0; j < num_owners; j++) + { + // The breakpoint action is an asynchronous breakpoint callback. If we ever need to have both + // callbacks and actions on the same breakpoint, we'll have to split this into two. + lldb::BreakpointLocationSP bp_loc_sp = bp_site_sp->GetOwnerAtIndex(j); + StoppointCallbackContext context (event_ptr, + &m_thread.GetProcess(), + &m_thread, + m_thread.GetStackFrameAtIndex(0).get(), + false); + bp_loc_sp->InvokeCallback (&context); + } + } + else + { + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS); + + if (log) + log->Printf ("Process::%s could not find breakpoint site id: %lld...", __FUNCTION__, m_value); + } + } virtual bool ShouldNotify (Event *event_ptr) @@ -123,9 +152,20 @@ { if (m_description.empty()) { - StreamString strm; - strm.Printf("breakpoint %lli", m_value); - m_description.swap (strm.GetString()); + BreakpointSiteSP bp_site_sp (m_thread.GetProcess().GetBreakpointSiteList().FindByID (m_value)); + if (bp_site_sp) + { + StreamString strm; + strm.Printf("breakpoint "); + bp_site_sp->GetDescription(&strm, eDescriptionLevelBrief); + m_description.swap (strm.GetString()); + } + else + { + StreamString strm; + strm.Printf("breakpoint site %lli", m_value); + m_description.swap (strm.GetString()); + } } return m_description.c_str(); } From jingham at apple.com Mon Aug 9 20:36:46 2010 From: jingham at apple.com (Jim Ingham) Date: Tue, 10 Aug 2010 01:36:46 -0000 Subject: [Lldb-commits] [lldb] r110641 - /lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Message-ID: <20100810013646.472C22A6C12C@llvm.org> Author: jingham Date: Mon Aug 9 20:36:46 2010 New Revision: 110641 URL: http://llvm.org/viewvc/llvm-project?rev=110641&view=rev Log: Looks like this is how you identify executables in ELF. Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=110641&r1=110640&r2=110641&view=diff ============================================================================== --- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original) +++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Mon Aug 9 20:36:46 2010 @@ -148,8 +148,7 @@ bool ObjectFileELF::IsExecutable() const { - // FIXME: How is this marked in ELF? - return false; + return m_header.e_type == ET_EXEC; } ByteOrder From benny.kra at googlemail.com Tue Aug 10 08:22:03 2010 From: benny.kra at googlemail.com (Benjamin Kramer) Date: Tue, 10 Aug 2010 13:22:03 -0000 Subject: [Lldb-commits] [lldb] r110676 - /lldb/trunk/source/Host/macosx/Host.mm Message-ID: <20100810132203.831CE2A6C12C@llvm.org> Author: d0k Date: Tue Aug 10 08:22:03 2010 New Revision: 110676 URL: http://llvm.org/viewvc/llvm-project?rev=110676&view=rev Log: Fix clang warnings. Modified: lldb/trunk/source/Host/macosx/Host.mm Modified: lldb/trunk/source/Host/macosx/Host.mm URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/macosx/Host.mm?rev=110676&r1=110675&r2=110676&view=diff ============================================================================== --- lldb/trunk/source/Host/macosx/Host.mm (original) +++ lldb/trunk/source/Host/macosx/Host.mm Tue Aug 10 08:22:03 2010 @@ -823,7 +823,7 @@ if (size_of_pids == -1) return 0; - pid_t our_pid = getpid(); + lldb::pid_t our_pid = getpid(); for (int i = 0; i < num_pids; i++) { @@ -835,7 +835,7 @@ // Don't offer to attach to zombie processes, already traced or exiting // processes, and of course, ourselves... It looks like passing the second arg of // 0 to proc_listpids will exclude zombies anyway, but that's not documented so... - if ((bsd_info.pbi_flags & (PROC_FLAG_TRACED | PROC_FLAG_INEXIT) != 0) + if (((bsd_info.pbi_flags & (PROC_FLAG_TRACED | PROC_FLAG_INEXIT)) != 0) || (bsd_info.pbi_status == SZOMB) || (bsd_info.pbi_pid == our_pid)) continue; From johnny.chen at apple.com Tue Aug 10 15:23:56 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 10 Aug 2010 20:23:56 -0000 Subject: [Lldb-commits] [lldb] r110719 - /lldb/trunk/test/dotest.py Message-ID: <20100810202356.257DF2A6C12C@llvm.org> Author: johnny Date: Tue Aug 10 15:23:55 2010 New Revision: 110719 URL: http://llvm.org/viewvc/llvm-project?rev=110719&view=rev Log: Call lldb.SBDebugger.Terminate() at the end of test suite run through the atexit handler similar to what's happening for the individual test case run. Modified: lldb/trunk/test/dotest.py Modified: lldb/trunk/test/dotest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=110719&r1=110718&r2=110719&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Tue Aug 10 15:23:55 2010 @@ -164,8 +164,9 @@ # For the time being, let's bracket the test runner within the # lldb.SBDebugger.Initialize()/Terminate() pair. -import lldb +import lldb, atexit lldb.SBDebugger.Initialize() +atexit.register(lambda: lldb.SBDebugger.Terminate()) # Create a singleton SBDebugger in the lldb namespace. lldb.DBG = lldb.SBDebugger.Create() @@ -184,8 +185,7 @@ unittest2.signals.installHandler() # Invoke the default TextTestRunner to run the test suite. -unittest2.TextTestRunner(verbosity=verbose).run(suite) +result = unittest2.TextTestRunner(verbosity=verbose).run(suite) -# Add some delay before calling SBDebugger.Terminate(). -time.sleep(1) -lldb.SBDebugger.Terminate() +# Exiting. +sys.exit(not result.wasSuccessful) From johnny.chen at apple.com Tue Aug 10 16:26:55 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Tue, 10 Aug 2010 21:26:55 -0000 Subject: [Lldb-commits] [lldb] r110731 - /lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Message-ID: <20100810212655.EF9C82A6C12C@llvm.org> Author: johnny Date: Tue Aug 10 16:26:55 2010 New Revision: 110731 URL: http://llvm.org/viewvc/llvm-project?rev=110731&view=rev Log: There is no need to restore (sys.stdin, sys.stdout) of the python script interpreter right before calling Py_Finalize(). This also fixed the crash as reported in rdar://problem/8252903. Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Modified: lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp?rev=110731&r1=110730&r2=110731&view=diff ============================================================================== --- lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp (original) +++ lldb/trunk/source/Interpreter/ScriptInterpreterPython.cpp Tue Aug 10 16:26:55 2010 @@ -211,15 +211,12 @@ PyRun_SimpleString ("from embedded_interpreter import run_python_interpreter"); PyRun_SimpleString ("import sys"); PyRun_SimpleString ("from termios import *"); - PyRun_SimpleString ("old_stdin = sys.stdin"); StreamString run_string; run_string.Printf ("new_stdin = open('%s', 'r')", pty_slave_name); PyRun_SimpleString (run_string.GetData()); PyRun_SimpleString ("sys.stdin = new_stdin"); - PyRun_SimpleString ("old_stdout = sys.stdout"); - if (out_fh != NULL) { PyObject *new_sysout = PyFile_FromFile (out_fh, (char *) "", (char *) "w", @@ -253,8 +250,6 @@ ScriptInterpreterPython::~ScriptInterpreterPython () { - PyRun_SimpleString ("sys.stdin = old_stdin"); - PyRun_SimpleString ("sys.stdout = old_stdout"); Py_Finalize (); } From scallanan at apple.com Tue Aug 10 22:57:18 2010 From: scallanan at apple.com (Sean Callanan) Date: Wed, 11 Aug 2010 03:57:18 -0000 Subject: [Lldb-commits] [lldb] r110777 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h include/lldb/Expression/ClangPersistentVariables.h include/lldb/Expression/IRForTarget.h include/lldb/Symbol/TaggedASTType.h include/lldb/Target/Process.h lldb.xcodeproj/project.pbxproj source/Commands/CommandObjectExpression.cpp source/Expression/ClangExpression.cpp source/Expression/ClangExpressionDeclMap.cpp source/Expression/ClangPersistentVariables.cpp source/Expression/IRForTarget.cpp source/Target/Process.cpp Message-ID: <20100811035718.D07C62A6C12C@llvm.org> Author: spyffe Date: Tue Aug 10 22:57:18 2010 New Revision: 110777 URL: http://llvm.org/viewvc/llvm-project?rev=110777&view=rev Log: Added support for persistent variables to the expression parser. It is now possible to type: (lldb) expr int $i = 5; $i + 1 (int) 6 (lldb) expr $i + 2 (int) 7 The skeleton for automatic result variables is also implemented. The changes affect: - the process, which now contains a ClangPersistentVariables object that holds persistent variables associated with it - the expression parser, which now uses the persistent variables during variable lookup - TaggedASTType, where I loaded some commonly used tags into a header so that they are interchangeable between different clients of the class Added: lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h lldb/trunk/source/Expression/ClangPersistentVariables.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h lldb/trunk/include/lldb/Expression/IRForTarget.h lldb/trunk/include/lldb/Symbol/TaggedASTType.h lldb/trunk/include/lldb/Target/Process.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Commands/CommandObjectExpression.cpp lldb/trunk/source/Expression/ClangExpression.cpp lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Expression/IRForTarget.cpp lldb/trunk/source/Target/Process.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=110777&r1=110776&r2=110777&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Tue Aug 10 22:57:18 2010 @@ -30,6 +30,7 @@ namespace lldb_private { +class ClangPersistentVariable; class ClangPersistentVariables; class Error; class Function; @@ -39,8 +40,7 @@ class ClangExpressionDeclMap { public: - ClangExpressionDeclMap(ExecutionContext *exe_ctx, - ClangPersistentVariables &persistent_vars); + ClangExpressionDeclMap(ExecutionContext *exe_ctx); ~ClangExpressionDeclMap(); // Interface for ClangStmtVisitor @@ -48,6 +48,7 @@ const clang::Decl *decl); // Interface for IRForTarget + bool AddPersistentVariable (const clang::NamedDecl *decl); bool AddValueToStruct (llvm::Value *value, const clang::NamedDecl *decl, std::string &name, @@ -67,7 +68,6 @@ bool GetFunctionInfo (const clang::NamedDecl *decl, llvm::Value**& value, uint64_t &ptr); - bool GetFunctionAddress (const char *name, uint64_t &ptr); @@ -90,9 +90,6 @@ // Interface for ClangASTSource void GetDecls (NameSearchContext &context, const char *name); - - typedef TaggedASTType<0> TypeFromParser; - typedef TaggedASTType<1> TypeFromUser; private: struct Tuple { @@ -124,7 +121,7 @@ StructMemberVector m_members; ExecutionContext *m_exe_ctx; SymbolContext *m_sym_ctx; /* owned by ClangExpressionDeclMap */ - ClangPersistentVariables &m_persistent_vars; + ClangPersistentVariables *m_persistent_vars; off_t m_struct_alignment; size_t m_struct_size; bool m_struct_laid_out; @@ -142,6 +139,7 @@ TypeFromParser *parser_type = NULL); void AddOneVariable(NameSearchContext &context, Variable *var); + void AddOneVariable(NameSearchContext &context, ClangPersistentVariable *pvar); void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym); void AddOneType(NameSearchContext &context, Type *type); @@ -150,6 +148,12 @@ lldb_private::Value *result_value, /* must be non-NULL if D is set */ Error &err); + bool DoMaterializeOnePersistentVariable(bool dematerialize, + ExecutionContext &exe_ctx, + const char *name, + lldb::addr_t addr, + Error &err); + bool DoMaterializeOneVariable(bool dematerialize, ExecutionContext &exe_ctx, const SymbolContext &sym_ctx, @@ -159,11 +163,6 @@ Error &err); }; -class ClangPersistentVariables -{ - -}; - } // namespace lldb_private #endif // liblldb_ClangExpressionDeclMap_h_ Added: lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h?rev=110777&view=auto ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h (added) +++ lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h Tue Aug 10 22:57:18 2010 @@ -0,0 +1,89 @@ +//===-- ClangPersistentVariables.h ------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ClangPersistentVariables_h_ +#define liblldb_ClangPersistentVariables_h_ + +#include "lldb-forward-rtti.h" +#include "lldb/Core/ConstString.h" +#include "lldb/Core/DataBufferHeap.h" +#include "lldb/Symbol/TaggedASTType.h" + +#include +#include + +namespace lldb_private +{ + +class ClangPersistentVariable +{ + friend class ClangPersistentVariables; +public: + ClangPersistentVariable () : + m_user_type(), + m_data() + { + } + + ClangPersistentVariable (const ClangPersistentVariable &pv) : + m_user_type(pv.m_user_type), + m_data(pv.m_data) + { + } + + ClangPersistentVariable &operator=(const ClangPersistentVariable &pv) + { + m_user_type = pv.m_user_type; + m_data = pv.m_data; + return *this; + } + + size_t Size () + { + return (m_user_type.GetClangTypeBitWidth () + 7) / 8; + } + + uint8_t *Data () + { + return m_data->GetBytes(); + } + + TypeFromUser Type () + { + return m_user_type; + } +private: + ClangPersistentVariable (TypeFromUser user_type) + { + m_user_type = user_type; + m_data = lldb::DataBufferSP(new DataBufferHeap(Size(), 0)); + } + TypeFromUser m_user_type; + lldb::DataBufferSP m_data; +}; + +class ClangPersistentVariables +{ +public: + ClangPersistentVariable *CreateVariable (ConstString name, TypeFromUser user_type); + ClangPersistentVariable *CreateResultVariable (TypeFromUser user_type); + ClangPersistentVariable *GetVariable (ConstString name); + + ClangPersistentVariables (); +private: + typedef std::map PVarMap; + typedef PVarMap::iterator PVarIterator; + + PVarMap m_variables; + uint64_t m_result_counter; +}; + +} + +#endif \ No newline at end of file Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=110777&r1=110776&r2=110777&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRForTarget.h (original) +++ lldb/trunk/include/lldb/Expression/IRForTarget.h Tue Aug 10 22:57:18 2010 @@ -46,6 +46,13 @@ bool rewriteObjCSelectors(llvm::Module &M, llvm::BasicBlock &BB); + // pass to find declarations of, and references to, persistent variables and + // register them for (de)materialization + bool RewritePersistentAlloc(llvm::Instruction *persistent_alloc, + llvm::Module &M); + bool rewritePersistentAllocs(llvm::Module &M, + llvm::BasicBlock &BB); + // pass to register referenced variables and redirect functions at their // targets in the debugged process bool MaybeHandleVariable(llvm::Module &M, Modified: lldb/trunk/include/lldb/Symbol/TaggedASTType.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/TaggedASTType.h?rev=110777&r1=110776&r2=110777&view=diff ============================================================================== --- lldb/trunk/include/lldb/Symbol/TaggedASTType.h (original) +++ lldb/trunk/include/lldb/Symbol/TaggedASTType.h Tue Aug 10 22:57:18 2010 @@ -38,6 +38,10 @@ } }; +// Commonly-used tagged types, so code using them is interoperable +typedef TaggedASTType<0> TypeFromParser; +typedef TaggedASTType<1> TypeFromUser; + } #endif Modified: lldb/trunk/include/lldb/Target/Process.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Process.h?rev=110777&r1=110776&r2=110777&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Process.h (original) +++ lldb/trunk/include/lldb/Target/Process.h Tue Aug 10 22:57:18 2010 @@ -25,6 +25,7 @@ #include "lldb/Core/ThreadSafeSTLMap.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Breakpoint/BreakpointSiteList.h" +#include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/ObjCObjectPrinter.h" #include "lldb/Target/ThreadList.h" @@ -1366,6 +1367,9 @@ lldb::ProcessSP GetSP (); + ClangPersistentVariables & + GetPersistentVariables(); + ObjCObjectPrinter & GetObjCObjectPrinter(); @@ -1392,6 +1396,7 @@ Listener &m_listener; BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend ///< to insert in the target. + ClangPersistentVariables m_persistent_vars; ///< These are the persistent variables associated with this process for the expression parser. UnixSignals m_unix_signals; /// This is the current signal set for this process. ConstString m_target_triple; lldb::ABISP m_abi_sp; Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=110777&r1=110776&r2=110777&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue Aug 10 22:57:18 2010 @@ -337,6 +337,8 @@ 49A8A3A011D568A300AD3B68 /* ClangResultSynthesizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */; }; 49A8A3A411D568BF00AD3B68 /* ClangResultSynthesizer.h in Headers */ = {isa = PBXBuildFile; fileRef = 49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */; }; 49BB309611F79450001A4197 /* TaggedASTType.h in Headers */ = {isa = PBXBuildFile; fileRef = 49BB309511F79450001A4197 /* TaggedASTType.h */; }; + 49D4FE831210B5FB00CDB854 /* ClangPersistentVariables.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */; }; + 49D4FE891210B61C00CDB854 /* ClangPersistentVariables.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */; }; 49D7072711B5AD03001AD875 /* ClangASTSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 49D7072611B5AD03001AD875 /* ClangASTSource.h */; }; 49D7072911B5AD11001AD875 /* ClangASTSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */; settings = {COMPILER_FLAGS = "-fno-rtti"; }; }; 49DA743011DE6A5A006AEF7E /* IRToDWARF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49DA742F11DE6A5A006AEF7E /* IRToDWARF.cpp */; }; @@ -920,6 +922,8 @@ 49BB309511F79450001A4197 /* TaggedASTType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TaggedASTType.h; path = include/lldb/Symbol/TaggedASTType.h; sourceTree = ""; }; 49BF48DC11ADF356008863BD /* ObjCObjectPrinter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ObjCObjectPrinter.cpp; path = source/Target/ObjCObjectPrinter.cpp; sourceTree = ""; }; 49BF48E011ADF37D008863BD /* ObjCObjectPrinter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ObjCObjectPrinter.h; path = include/lldb/Target/ObjCObjectPrinter.h; sourceTree = ""; }; + 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangPersistentVariables.h; path = include/lldb/Expression/ClangPersistentVariables.h; sourceTree = ""; }; + 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangPersistentVariables.cpp; path = source/Expression/ClangPersistentVariables.cpp; sourceTree = ""; }; 49D7072611B5AD03001AD875 /* ClangASTSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangASTSource.h; path = include/lldb/Expression/ClangASTSource.h; sourceTree = ""; }; 49D7072811B5AD11001AD875 /* ClangASTSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangASTSource.cpp; path = source/Expression/ClangASTSource.cpp; sourceTree = ""; }; 49DA742F11DE6A5A006AEF7E /* IRToDWARF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = IRToDWARF.cpp; path = source/Expression/IRToDWARF.cpp; sourceTree = ""; }; @@ -1851,6 +1855,8 @@ 49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */, 26BC7DC110F1B79500F91463 /* ClangExpressionVariable.h */, 26BC7ED610F1B86700F91463 /* ClangExpressionVariable.cpp */, + 49D4FE821210B5FB00CDB854 /* ClangPersistentVariables.h */, + 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */, 49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */, 49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */, 26BC7DC210F1B79500F91463 /* ClangStmtVisitor.h */, @@ -2224,6 +2230,7 @@ 264723A611FA076E00DE380C /* CleanUp.h in Headers */, 2615DB851208A9C90021781D /* StopInfo.h in Headers */, 2615DBCB1208B5FC0021781D /* StopInfoMachException.h in Headers */, + 49D4FE831210B5FB00CDB854 /* ClangPersistentVariables.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -2680,6 +2687,7 @@ 49E45FAF11F660FE008F7B28 /* ClangASTType.cpp in Sources */, 2615DB871208A9E40021781D /* StopInfo.cpp in Sources */, 2615DBCA1208B5FC0021781D /* StopInfoMachException.cpp in Sources */, + 49D4FE891210B61C00CDB854 /* ClangPersistentVariables.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=110777&r1=110776&r2=110777&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Tue Aug 10 22:57:18 2010 @@ -19,6 +19,7 @@ #include "lldb/Expression/ClangExpression.h" #include "lldb/Expression/ClangExpressionDeclMap.h" #include "lldb/Expression/ClangExpressionVariable.h" +#include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Expression/ClangFunction.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Host/Host.h" @@ -217,8 +218,7 @@ return false; } - ClangPersistentVariables persistent_vars; /* TODO store this somewhere sensible */ - ClangExpressionDeclMap expr_decl_map (&m_exe_ctx, persistent_vars); + ClangExpressionDeclMap expr_decl_map (&m_exe_ctx); ClangExpression clang_expr (target_triple.AsCString (), &expr_decl_map); ////////////////////////// Modified: lldb/trunk/source/Expression/ClangExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpression.cpp?rev=110777&r1=110776&r2=110777&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangExpression.cpp Tue Aug 10 22:57:18 2010 @@ -239,6 +239,7 @@ m_clang_ap->getLangOpts().ObjC1 = true; m_clang_ap->getLangOpts().ThreadsafeStatics = false; m_clang_ap->getLangOpts().AccessControl = false; // Debuggers get universal access + m_clang_ap->getLangOpts().DollarIdents = true; // $ indicates a persistent variable name // Set CodeGen options m_clang_ap->getCodeGenOpts().EmitDeclMetadata = true; Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=110777&r1=110776&r2=110777&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Tue Aug 10 22:57:18 2010 @@ -19,6 +19,7 @@ #include "lldb/Core/Log.h" #include "lldb/Core/Module.h" #include "lldb/Expression/ClangASTSource.h" +#include "lldb/Expression/ClangPersistentVariables.h" #include "lldb/Symbol/ClangASTContext.h" #include "lldb/Symbol/CompileUnit.h" #include "lldb/Symbol/Function.h" @@ -36,17 +37,17 @@ using namespace lldb_private; using namespace clang; -ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx, - ClangPersistentVariables &persistent_vars) : - m_exe_ctx(exe_ctx), - m_persistent_vars(persistent_vars), - m_struct_laid_out(false), +ClangExpressionDeclMap::ClangExpressionDeclMap(ExecutionContext *exe_ctx) : + m_exe_ctx(exe_ctx), m_struct_laid_out(false), m_materialized_location(0) { if (exe_ctx && exe_ctx->frame) m_sym_ctx = new SymbolContext(exe_ctx->frame->GetSymbolContext(lldb::eSymbolContextEverything)); else m_sym_ctx = NULL; + + if (exe_ctx && exe_ctx->process) + m_persistent_vars = &exe_ctx->process->GetPersistentVariables(); } ClangExpressionDeclMap::~ClangExpressionDeclMap() @@ -83,6 +84,31 @@ // Interface for IRForTarget bool +ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl) +{ + clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext()); + + const clang::VarDecl *var(dyn_cast(decl)); + + if (!var) + return false; + + TypeFromUser user_type(ClangASTContext::CopyType(context, + &var->getASTContext(), + var->getType().getAsOpaquePtr()), + context); + + ConstString const_name(decl->getName().str().c_str()); + + ClangPersistentVariable *pvar = m_persistent_vars->CreateVariable(const_name, user_type); + + if (!pvar) + return false; + + return true; +} + +bool ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value, const clang::NamedDecl *decl, std::string &name, @@ -400,33 +426,40 @@ if (!GetIndexForDecl(tuple_index, iter->m_decl)) { - if (iter->m_name.find("___clang_expr_result") == std::string::npos) + if (iter->m_name[0] == '$') { - err.SetErrorStringWithFormat("Unexpected variable %s", iter->m_name.c_str()); - return false; + if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, iter->m_name.c_str(), m_materialized_location + iter->m_offset, err)) + return false; } - - if (log) - log->Printf("Found special result variable %s", iter->m_name.c_str()); - - if (dematerialize) + else if (iter->m_name.find("___clang_expr_result") != std::string::npos) { - clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext()); + if (log) + log->Printf("Found special result variable %s", iter->m_name.c_str()); - if (!context) + if (dematerialize) { - err.SetErrorString("Couldn't find a scratch AST context to put the result type into"); + clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext()); + + if (!context) + { + err.SetErrorString("Couldn't find a scratch AST context to put the result type into"); + } + + TypeFromUser copied_type(ClangASTContext::CopyType(context, + iter->m_parser_type.GetASTContext(), + iter->m_parser_type.GetOpaqueQualType()), + context); + + result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetOpaqueQualType()); + + result_value->SetValueType(Value::eValueTypeLoadAddress); + result_value->GetScalar() = (uintptr_t)m_materialized_location + iter->m_offset; } - - TypeFromUser copied_type(ClangASTContext::CopyType(context, - iter->m_parser_type.GetASTContext(), - iter->m_parser_type.GetOpaqueQualType()), - context); - - result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetOpaqueQualType()); - - result_value->SetValueType(Value::eValueTypeLoadAddress); - result_value->GetScalar() = (uintptr_t)m_materialized_location + iter->m_offset; + } + else + { + err.SetErrorStringWithFormat("Unexpected variable %s", iter->m_name.c_str()); + return false; } continue; @@ -441,6 +474,50 @@ return true; } +bool +ClangExpressionDeclMap::DoMaterializeOnePersistentVariable(bool dematerialize, + ExecutionContext &exe_ctx, + const char *name, + lldb::addr_t addr, + Error &err) +{ + Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + if (log) + log->Printf("Found persistent variable %s", name); + + ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name))); + + if (!pvar) + { + err.SetErrorStringWithFormat("Undefined persistent variable %s", name); + return LLDB_INVALID_ADDRESS; + } + + size_t pvar_size = pvar->Size(); + uint8_t *pvar_data = pvar->Data(); + Error error; + + if (dematerialize) + { + if (exe_ctx.process->ReadMemory (addr, pvar_data, pvar_size, error) != pvar_size) + { + err.SetErrorStringWithFormat ("Couldn't read a composite type from the target: %s", error.AsCString()); + return false; + } + } + else + { + if (exe_ctx.process->WriteMemory (addr, pvar_data, pvar_size, error) != pvar_size) + { + err.SetErrorStringWithFormat ("Couldn't write a composite type to the target: %s", error.AsCString()); + return false; + } + } + + return true; +} + bool ClangExpressionDeclMap::DoMaterializeOneVariable(bool dematerialize, ExecutionContext &exe_ctx, @@ -682,6 +759,11 @@ if (var) AddOneVariable(context, var); + ClangPersistentVariable *pvar(m_persistent_vars->GetVariable(ConstString(name))); + + if (pvar) + AddOneVariable(context, pvar); + /* Commented out pending resolution of a loop when the TagType is imported lldb::TypeSP type = m_sym_ctx->FindTypeByName(name_cs); @@ -824,6 +906,20 @@ } void +ClangExpressionDeclMap::AddOneVariable(NameSearchContext &context, + ClangPersistentVariable *pvar) +{ + TypeFromUser user_type = pvar->Type(); + + TypeFromParser parser_type(ClangASTContext::CopyType(context.GetASTContext(), + user_type.GetASTContext(), + user_type.GetOpaqueQualType()), + context.GetASTContext()); + + (void)context.AddVarDecl(parser_type.GetOpaqueQualType()); +} + +void ClangExpressionDeclMap::AddOneFunction(NameSearchContext &context, Function* fun, Symbol* symbol) Added: lldb/trunk/source/Expression/ClangPersistentVariables.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangPersistentVariables.cpp?rev=110777&view=auto ============================================================================== --- lldb/trunk/source/Expression/ClangPersistentVariables.cpp (added) +++ lldb/trunk/source/Expression/ClangPersistentVariables.cpp Tue Aug 10 22:57:18 2010 @@ -0,0 +1,59 @@ +//===-- ClangPersistentVariables.cpp ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "ClangPersistentVariables.h" +#include "lldb/Core/Log.h" +#include "lldb/Core/StreamString.h" + +using namespace lldb_private; +using namespace clang; + +ClangPersistentVariables::ClangPersistentVariables () : + m_variables(), + m_result_counter(0) +{ +} + +ClangPersistentVariable * +ClangPersistentVariables::CreateVariable (ConstString name, + TypeFromUser user_type) +{ + ClangPersistentVariable new_var(user_type); + + if (m_variables.find(name) != m_variables.end()) + return NULL; + + m_variables[name] = new_var; + + return &m_variables[name]; +} + +ClangPersistentVariable * +ClangPersistentVariables::CreateResultVariable (TypeFromUser user_type) +{ + StreamString s; + s.Printf("$%llu", m_result_counter); + ConstString name(s.GetString().c_str()); + + ClangPersistentVariable *ret = CreateVariable (name, user_type); + + if (ret != NULL) + ++m_result_counter; + + return ret; +} + +ClangPersistentVariable * +ClangPersistentVariables::GetVariable (ConstString name) +{ + if (m_variables.find(name) == m_variables.end()) + return NULL; + + return &m_variables[name]; +} Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=110777&r1=110776&r2=110777&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Tue Aug 10 22:57:18 2010 @@ -37,6 +37,20 @@ { } +/* A handy utility function used at several places in the code */ + +static std::string +PrintValue(Value *V, bool truncate = false) +{ + std::string s; + raw_string_ostream rso(s); + V->print(rso); + rso.flush(); + if (truncate) + s.resize(s.length() - 1); + return s; +} + IRForTarget::~IRForTarget() { } @@ -200,6 +214,97 @@ return true; } +bool +IRForTarget::RewritePersistentAlloc(llvm::Instruction *persistent_alloc, + llvm::Module &M) +{ + AllocaInst *alloc = dyn_cast(persistent_alloc); + + MDNode *alloc_md = alloc->getMetadata("clang.decl.ptr"); + + if (!alloc_md || !alloc_md->getNumOperands()) + return false; + + ConstantInt *constant_int = dyn_cast(alloc_md->getOperand(0)); + + if (!constant_int) + return false; + + // We attempt to register this as a new persistent variable with the DeclMap. + + uintptr_t ptr = constant_int->getZExtValue(); + + clang::NamedDecl *decl = reinterpret_cast(ptr); + + if (!m_decl_map->AddPersistentVariable(decl)) + return false; + + GlobalVariable *persistent_global = new GlobalVariable(M, + alloc->getType()->getElementType(), + false, /* not constant */ + GlobalValue::ExternalLinkage, + NULL, /* no initializer */ + alloc->getName().str().c_str()); + + // What we're going to do here is make believe this was a regular old external + // variable. That means we need to make the metadata valid. + + NamedMDNode *named_metadata = M.getNamedMetadata("clang.global.decl.ptrs"); + + llvm::Value* values[2]; + values[0] = persistent_global; + values[1] = constant_int; + + MDNode *persistent_global_md = MDNode::get(M.getContext(), values, 2); + named_metadata->addOperand(persistent_global_md); + + alloc->replaceAllUsesWith(persistent_global); + alloc->eraseFromParent(); + + return true; +} + +bool +IRForTarget::rewritePersistentAllocs(llvm::Module &M, + llvm::BasicBlock &BB) +{ + lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + BasicBlock::iterator ii; + + typedef SmallVector InstrList; + typedef InstrList::iterator InstrIterator; + + InstrList pvar_allocs; + + for (ii = BB.begin(); + ii != BB.end(); + ++ii) + { + Instruction &inst = *ii; + + if (AllocaInst *alloc = dyn_cast(&inst)) + if (alloc->getName().startswith("$")) + pvar_allocs.push_back(alloc); + } + + InstrIterator iter; + + for (iter = pvar_allocs.begin(); + iter != pvar_allocs.end(); + ++iter) + { + if (!RewritePersistentAlloc(*iter, M)) + { + if(log) + log->PutCString("Couldn't rewrite the creation of a persistent variable"); + return false; + } + } + + return true; +} + static clang::NamedDecl * DeclForGlobalValue(Module &module, GlobalValue *global_value) @@ -222,7 +327,7 @@ return NULL; if (metadata_node->getNumOperands() != 2) - return NULL; + continue; if (metadata_node->getOperand(0) != global_value) continue; @@ -400,18 +505,6 @@ return true; } -static std::string -PrintValue(Value *V, bool truncate = false) -{ - std::string s; - raw_string_ostream rso(s); - V->print(rso); - rso.flush(); - if (truncate) - s.resize(s.length() - 1); - return s; -} - static bool isGuardVariableRef(Value *V) { ConstantExpr *C = dyn_cast(V); @@ -518,12 +611,21 @@ Value::use_iterator ui; + SmallVector users; + + // We do this because the use list might change, invalidating our iterator. + // Much better to keep a work list ourselves. for (ui = C->use_begin(); ui != C->use_end(); ++ui) - { - User *user = *ui; + users.push_back(*ui); + for (int i = 0; + i < users.size(); + ++i) + { + User *user = users[i]; + if (Constant *constant = dyn_cast(user)) { // synthesize a new non-constant equivalent of the constant @@ -703,9 +805,12 @@ bbi != function->end(); ++bbi) { - if (!rewriteObjCSelectors(M, *bbi)) + if (!rewritePersistentAllocs(M, *bbi)) return false; + if (!rewriteObjCSelectors(M, *bbi)) + return false; + if (!resolveExternals(M, *bbi)) return false; @@ -713,13 +818,6 @@ return false; } - /////////////////////////////// - // Run function-level passes - // - - if (!replaceVariables(M, *function)) - return false; - if (log) { std::string s; @@ -732,6 +830,13 @@ log->Printf("Module after preparing for execution: \n%s", s.c_str()); } + /////////////////////////////// + // Run function-level passes + // + + if (!replaceVariables(M, *function)) + return false; + return true; } Modified: lldb/trunk/source/Target/Process.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Process.cpp?rev=110777&r1=110776&r2=110777&view=diff ============================================================================== --- lldb/trunk/source/Target/Process.cpp (original) +++ lldb/trunk/source/Target/Process.cpp Tue Aug 10 22:57:18 2010 @@ -80,7 +80,8 @@ m_notifications (), m_listener(listener), m_unix_signals (), - m_objc_object_printer(*this) + m_objc_object_printer(*this), + m_persistent_vars() { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT); if (log) @@ -1882,6 +1883,12 @@ return GetTarget().GetProcessSP(); } +ClangPersistentVariables & +Process::GetPersistentVariables() +{ + return m_persistent_vars; +} + ObjCObjectPrinter & Process::GetObjCObjectPrinter() { From jingham at apple.com Wed Aug 11 20:20:14 2010 From: jingham at apple.com (Jim Ingham) Date: Thu, 12 Aug 2010 01:20:14 -0000 Subject: [Lldb-commits] [lldb] r110892 - in /lldb/trunk: source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp test/inlines/ test/inlines/Makefile test/inlines/inlines.c Message-ID: <20100812012014.A133C2A6C12C@llvm.org> Author: jingham Date: Wed Aug 11 20:20:14 2010 New Revision: 110892 URL: http://llvm.org/viewvc/llvm-project?rev=110892&view=rev Log: Few little fixes to reading in inlined functions. Also added a test case with some inlining. Added: lldb/trunk/test/inlines/ lldb/trunk/test/inlines/Makefile lldb/trunk/test/inlines/inlines.c Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=110892&r1=110891&r2=110892&view=diff ============================================================================== --- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original) +++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Wed Aug 11 20:20:14 2010 @@ -1144,8 +1144,8 @@ switch (tag) { - case DW_TAG_subprogram: case DW_TAG_inlined_subroutine: + case DW_TAG_subprogram: case DW_TAG_lexical_block: { DWARFDebugRanges::RangeList ranges; @@ -1160,25 +1160,44 @@ int call_file = 0; int call_line = 0; int call_column = 0; - if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges, decl_file, decl_line, decl_column, call_file, call_line, call_column)) + if (die->GetDIENamesAndRanges(this, dwarf_cu, name, mangled_name, ranges, + decl_file, decl_line, decl_column, + call_file, call_line, call_column)) { if (tag == DW_TAG_subprogram) { assert (subprogram_low_pc == LLDB_INVALID_ADDRESS); subprogram_low_pc = ranges.LowestAddress(0); } - + else if (tag == DW_TAG_inlined_subroutine) + { + // We get called here for inlined subroutines in two ways. + // The first time is when we are making the Function object + // for this inlined concrete instance. Since we're creating a top level block at + // here, the subprogram_low_pc will be LLDB_INVALID_ADDRESS. So we need to + // adjust the containing address. + // The second time is when we are parsing the blocks inside the function that contains + // the inlined concrete instance. Since these will be blocks inside the containing "real" + // function the offset will be for that function. + if (subprogram_low_pc == LLDB_INVALID_ADDRESS) + { + subprogram_low_pc = ranges.LowestAddress(0); + } + } + AddRangesToBlock (blocks, blockID, ranges, subprogram_low_pc); if (tag != DW_TAG_subprogram && (name != NULL || mangled_name != NULL)) { std::auto_ptr decl_ap; if (decl_file != 0 || decl_line != 0 || decl_column != 0) - decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), decl_line, decl_column)); + decl_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(decl_file), + decl_line, decl_column)); std::auto_ptr call_ap; if (call_file != 0 || call_line != 0 || call_column != 0) - call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), call_line, call_column)); + call_ap.reset(new Declaration(sc.comp_unit->GetSupportFiles().GetFileSpecAtIndex(call_file), + call_line, call_column)); blocks.SetInlinedFunctionInfo(blockID, name, mangled_name, decl_ap.get(), call_ap.get()); } @@ -1187,7 +1206,8 @@ if (parse_children && die->HasChildren()) { - blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(), subprogram_low_pc, true, true); + blocks_added += ParseFunctionBlocks(sc, blockID, dwarf_cu, die->GetFirstChild(), + subprogram_low_pc, true, true); } } } @@ -2854,6 +2874,7 @@ } break; + case DW_TAG_inlined_subroutine: case DW_TAG_subprogram: case DW_TAG_subroutine_type: { Added: lldb/trunk/test/inlines/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/inlines/Makefile?rev=110892&view=auto ============================================================================== --- lldb/trunk/test/inlines/Makefile (added) +++ lldb/trunk/test/inlines/Makefile Wed Aug 11 20:20:14 2010 @@ -0,0 +1,125 @@ +#---------------------------------------------------------------------- +# Fill in the source files to build +#---------------------------------------------------------------------- +C_SOURCES := inlines.c +CXX_SOURCES := +OBJC_SOURCES := +OBJCXX_SOURCES := + +# Uncomment line below for debugging shell commands +# SHELL = /bin/sh -x + +#---------------------------------------------------------------------- +# Change any build/tool options needed +#---------------------------------------------------------------------- +DS := /usr/bin/dsymutil +DSFLAGS = +CFLAGS ?=-arch x86_64 -gdwarf-2 -O0 +CPLUSPLUSFLAGS +=$(CFLAGS) +CPPFLAGS +=$(CFLAGS) +LD = gcc +LDFLAGS = $(CFLAGS) +OBJECTS = +EXE=a.out +DSYM=$(EXE).dSYM + +#---------------------------------------------------------------------- +# Check if we have any C source files +#---------------------------------------------------------------------- +ifneq "$(strip $(C_SOURCES))" "" + OBJECTS +=$(strip $(C_SOURCES:.c=.o)) +endif + +#---------------------------------------------------------------------- +# Check if we have any C++ source files +#---------------------------------------------------------------------- +ifneq "$(strip $(CXX_SOURCES))" "" + OBJECTS +=$(strip $(CXX_SOURCES:.cpp=.o)) + LD = g++ +endif + +#---------------------------------------------------------------------- +# Check if we have any ObjC source files +#---------------------------------------------------------------------- +ifneq "$(strip $(OBJC_SOURCES))" "" + OBJECTS +=$(strip $(OBJC_SOURCES:.m=.o)) + LDFLAGS +=-lobjc +endif + +#---------------------------------------------------------------------- +# Check if we have any ObjC++ source files +#---------------------------------------------------------------------- +ifneq "$(strip $(OBJCXX_SOURCES))" "" + OBJECTS +=$(strip $(OBJCXX_SOURCES:.mm=.o)) + LD = g++ + ifeq $(findstring lobjc,$(LDFLAGS)) "" + LDFLAGS +=-lobjc + endif +endif + + +#---------------------------------------------------------------------- +# Make the dSYM file from the executable +#---------------------------------------------------------------------- +$(DSYM) : $(EXE) + $(DS) $(DSFLAGS) -o "$(DSYM)" "$(EXE)" + +#---------------------------------------------------------------------- +# Compile the executable from all the objects (default rule) with no +# dsym file. +#---------------------------------------------------------------------- +$(EXE) : $(OBJECTS) + $(LD) $(LDFLAGS) $(OBJECTS) -o "$(EXE)" + + +#---------------------------------------------------------------------- +# Automatic variables based on items already entered. Below we create +# an objects lists from the list of sources by replacing all entries +# that end with .c with .o, and we also create a list of prerequisite +# files by replacing all .c files with .d. +#---------------------------------------------------------------------- +PREREQS := $(OBJECTS:.o=.d) + +#---------------------------------------------------------------------- +# Rule for Generating Prerequisites Automatically using .d files and +# the compiler -MM option. The -M option will list all system headers, +# and the -MM option will list all non-system dependencies. +#---------------------------------------------------------------------- +%.d: %.c + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +%.d: %.cpp + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +%.d: %.m + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +%.d: %.mm + @set -e; rm -f $@; \ + $(CC) -M $(CPPFLAGS) $< > $@.$$$$; \ + sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \ + rm -f $@.$$$$ + +#---------------------------------------------------------------------- +# Include all of the makefiles for each source file so we don't have +# to manually track all of the prerequisites for each source file. +#---------------------------------------------------------------------- +sinclude $(PREREQS) + +.PHONY: clean +dsym: $(DSYM) +all: $(EXE) $(DSYM) +clean: + rm -rf "$(EXE)" "$(DSYM)" $(OBJECTS) $(PREREQS) *~ + + + Added: lldb/trunk/test/inlines/inlines.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/inlines/inlines.c?rev=110892&view=auto ============================================================================== --- lldb/trunk/test/inlines/inlines.c (added) +++ lldb/trunk/test/inlines/inlines.c Wed Aug 11 20:20:14 2010 @@ -0,0 +1,38 @@ +#include + +#define INLINE_ME __inline__ __attribute__((always_inline)) + +INLINE_ME int +inner_inline (int inner_input, int mod_value) +{ + int inner_result; + inner_result = inner_input % mod_value; + printf ("Returning: %d.\n", inner_result); + return inner_result; +} + +INLINE_ME int +outer_inline (int outer_input) +{ + int outer_result; + + outer_result = inner_inline (outer_input, outer_input % 3); + return outer_result; +} + +int +main (int argc, char **argv) +{ + printf ("Starting...\n"); + + int (*func_ptr) (int); + func_ptr = outer_inline; + + outer_inline (argc); + + func_ptr (argc); + + return 0; +} + + From jingham at apple.com Wed Aug 11 20:21:40 2010 From: jingham at apple.com (Jim Ingham) Date: Thu, 12 Aug 2010 01:21:40 -0000 Subject: [Lldb-commits] [lldb] r110893 - in /lldb/trunk/test/macosx: ./ universal/ universal/Makefile universal/main.c Message-ID: <20100812012140.8C9482A6C12C@llvm.org> Author: jingham Date: Wed Aug 11 20:21:40 2010 New Revision: 110893 URL: http://llvm.org/viewvc/llvm-project?rev=110893&view=rev Log: Test files (but no test cases yet) for handling Universal files. Added: lldb/trunk/test/macosx/ lldb/trunk/test/macosx/universal/ lldb/trunk/test/macosx/universal/Makefile lldb/trunk/test/macosx/universal/main.c Added: lldb/trunk/test/macosx/universal/Makefile URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/macosx/universal/Makefile?rev=110893&view=auto ============================================================================== --- lldb/trunk/test/macosx/universal/Makefile (added) +++ lldb/trunk/test/macosx/universal/Makefile Wed Aug 11 20:21:40 2010 @@ -0,0 +1,17 @@ +testit: testit.i386 testit.x86_64 + lipo -create -o testit testit.i386 testit.x86_64 + +testit.i386: testit.i386.o + gcc -arch i386 -o testit.i386 testit.i386.o + +testit.x86_64: testit.x86_64.o + gcc -arch x86_64 -o testit.x86_64 testit.x86_64.o + +testit.i386.o: main.c + gcc -g -O0 -arch i386 -c -o testit.i386.o main.c + +testit.x86_64.o: main.c + gcc -g -O0 -arch x86_64 -c -o testit.x86_64.o main.c + +clean: + rm -rf testit* *~ Added: lldb/trunk/test/macosx/universal/main.c URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/macosx/universal/main.c?rev=110893&view=auto ============================================================================== --- lldb/trunk/test/macosx/universal/main.c (added) +++ lldb/trunk/test/macosx/universal/main.c Wed Aug 11 20:21:40 2010 @@ -0,0 +1,7 @@ +#include +int +main (int argc, char **argv) +{ + printf ("Hello there!\n"); + return 0; +} From scallanan at apple.com Wed Aug 11 20:56:52 2010 From: scallanan at apple.com (Sean Callanan) Date: Thu, 12 Aug 2010 01:56:52 -0000 Subject: [Lldb-commits] [lldb] r110896 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h include/lldb/Expression/ClangPersistentVariables.h include/lldb/Expression/IRForTarget.h source/Commands/CommandObjectExpression.cpp source/Expression/ClangExpressionDeclMap.cpp source/Expression/ClangPersistentVariables.cpp source/Expression/IRForTarget.cpp Message-ID: <20100812015652.9AB1D2A6C12C@llvm.org> Author: spyffe Date: Wed Aug 11 20:56:52 2010 New Revision: 110896 URL: http://llvm.org/viewvc/llvm-project?rev=110896&view=rev Log: Added automatically generated result variables for each expression. It is now possible to do things like this: (lldb) expr int $i = 5; $i + 1 $0 = (int) 6 (lldb) expr $i + 3 $1 = (int) 8 (lldb) expr $1 + $0 $2 = (int) 14 As a bonus, this allowed us to move printing of expression results into the ClangPersistentVariable class. This code needs a bit of refactoring -- in particular, ClangExpressionDeclMap has eaten one too many bacteria and needs to undergo mitosis -- but the infrastructure appears to be holding up nicely. Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h lldb/trunk/include/lldb/Expression/IRForTarget.h lldb/trunk/source/Commands/CommandObjectExpression.cpp lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Expression/ClangPersistentVariables.cpp lldb/trunk/source/Expression/IRForTarget.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=110896&r1=110895&r2=110896&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Wed Aug 11 20:56:52 2010 @@ -48,7 +48,8 @@ const clang::Decl *decl); // Interface for IRForTarget - bool AddPersistentVariable (const clang::NamedDecl *decl); + void GetPersistentResultName (std::string &name); + bool AddPersistentVariable (const char *name, TypeFromParser type); bool AddValueToStruct (llvm::Value *value, const clang::NamedDecl *decl, std::string &name, @@ -84,7 +85,7 @@ Error &error); bool Dematerialize(ExecutionContext *exe_ctx, - lldb_private::Value &result_value, + ClangPersistentVariable *&result, Error &error); // Interface for ClangASTSource @@ -127,6 +128,7 @@ bool m_struct_laid_out; lldb::addr_t m_allocated_area; lldb::addr_t m_materialized_location; + std::string m_result_name; Variable *FindVariableInScope(const SymbolContext &sym_ctx, const char *name, @@ -145,7 +147,7 @@ bool DoMaterialize (bool dematerialize, ExecutionContext *exe_ctx, - lldb_private::Value *result_value, /* must be non-NULL if D is set */ + ClangPersistentVariable **result, /* must be non-NULL if D is set */ Error &err); bool DoMaterializeOnePersistentVariable(bool dematerialize, Modified: lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h?rev=110896&r1=110895&r2=110896&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h (original) +++ lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h Wed Aug 11 20:56:52 2010 @@ -26,12 +26,14 @@ friend class ClangPersistentVariables; public: ClangPersistentVariable () : + m_name(), m_user_type(), m_data() { } ClangPersistentVariable (const ClangPersistentVariable &pv) : + m_name(pv.m_name), m_user_type(pv.m_user_type), m_data(pv.m_data) { @@ -39,6 +41,7 @@ ClangPersistentVariable &operator=(const ClangPersistentVariable &pv) { + m_name = pv.m_name; m_user_type = pv.m_user_type; m_data = pv.m_data; return *this; @@ -58,12 +61,21 @@ { return m_user_type; } + + Error Print(Stream &output_stream, + ExecutionContext &exe_ctx, + lldb::Format format, + bool show_types, + bool show_summary, + bool verbose); private: - ClangPersistentVariable (TypeFromUser user_type) + ClangPersistentVariable (ConstString name, TypeFromUser user_type) { + m_name = name; m_user_type = user_type; m_data = lldb::DataBufferSP(new DataBufferHeap(Size(), 0)); } + ConstString m_name; TypeFromUser m_user_type; lldb::DataBufferSP m_data; }; @@ -72,9 +84,10 @@ { public: ClangPersistentVariable *CreateVariable (ConstString name, TypeFromUser user_type); - ClangPersistentVariable *CreateResultVariable (TypeFromUser user_type); ClangPersistentVariable *GetVariable (ConstString name); + void GetNextResultName(std::string &name); + ClangPersistentVariables (); private: typedef std::map PVarMap; Modified: lldb/trunk/include/lldb/Expression/IRForTarget.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/IRForTarget.h?rev=110896&r1=110895&r2=110896&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/IRForTarget.h (original) +++ lldb/trunk/include/lldb/Expression/IRForTarget.h Wed Aug 11 20:56:52 2010 @@ -39,6 +39,12 @@ llvm::PassManagerType T = llvm::PMT_ModulePassManager); llvm::PassManagerType getPotentialPassManagerType() const; private: + // pass to find the result variable created in the result synthesizer and + // make a result variable out of it (or a void variable if there is no + // result) + bool createResultVariable(llvm::Module &M, + llvm::Function &F); + // pass to rewrite Objective-C method calls to use the runtime function // sel_registerName bool RewriteObjCSelector(llvm::Instruction* selector_load, Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=110896&r1=110895&r2=110896&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Wed Aug 11 20:56:52 2010 @@ -252,7 +252,7 @@ bool canInterpret = false; clang::ASTContext *ast_context = clang_expr.GetASTContext (); - Value expr_result; + ClangPersistentVariable *expr_result = 0; Error expr_error; canInterpret = clang_expr.ConvertIRToDWARF (expr_local_vars, dwarf_opcodes); @@ -373,79 +373,32 @@ if (!expr_decl_map.Dematerialize(&m_exe_ctx, expr_result, expr_error)) { - error_stream.Printf ("Couldn't dematerialize struct: %s\n", expr_error.AsCString("unknown error")); + error_stream.Printf ("Couldn't dematerialize struct : %s\n", expr_error.AsCString("unknown error")); return false; } } - - /////////////////////////////////////// - // Interpret the result and print it - // - - lldb::Format format = m_options.format; - - // Resolve any values that are possible - expr_result.ResolveValue (&m_exe_ctx, ast_context); - if (expr_result.GetContextType () == Value::eContextTypeInvalid && - expr_result.GetValueType () == Value::eValueTypeScalar && - format == eFormatDefault) + if (expr_result) { - // The expression result is just a scalar with no special formatting - expr_result.GetScalar ().GetValue (&output_stream, m_options.show_types); - output_stream.EOL (); - return true; - } - - // The expression result is more complext and requires special handling - DataExtractor data; - expr_error = expr_result.GetValueAsData (&m_exe_ctx, ast_context, data, 0); - - if (!expr_error.Success ()) - { - error_stream.Printf ("error: couldn't resolve result value: %s\n", expr_error.AsCString ()); - return false; - } - - if (format == eFormatDefault) - format = expr_result.GetValueDefaultFormat (); - - void *clang_type = expr_result.GetValueOpaqueClangQualType (); - - if (clang_type) - { - if (m_options.show_types) - output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString()); + StreamString ss; - ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to - clang_type, // The opaque clang type we want to dump that value of - &m_exe_ctx, // The execution context for memory and variable access - &output_stream, // Stream to dump to - format, // Format to use when dumping - data, // A buffer containing the bytes for the clang type - 0, // Byte offset within "data" where value is - data.GetByteSize (), // Size in bytes of the value we are dumping - 0, // Bitfield bit size - 0, // Bitfield bit offset - m_options.show_types, // Show types? - m_options.show_summary, // Show summary? - m_options.debug, // Debug logging output? - UINT32_MAX); // Depth to dump in case this is an aggregate type + Error err = expr_result->Print (ss, + m_exe_ctx, + m_options.format, + m_options.show_types, + m_options.show_summary, + m_options.debug); + + if (err.Success()) + output_stream.PutCString(ss.GetString().c_str()); + else + error_stream.Printf ("Couldn't print result : %s\n", err.AsCString("unknown error")); } else { - data.Dump (&output_stream, // Stream to dump to - 0, // Byte offset within "data" - format, // Format to use when dumping - data.GetByteSize (), // Size in bytes of each item we are dumping - 1, // Number of items to dump - UINT32_MAX, // Number of items per line - LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context - 0, // Bitfield bit size - 0); // Bitfield bit offset + error_stream.Printf ("Expression produced no result\n"); } - output_stream.EOL(); - + return true; } Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=110896&r1=110895&r2=110896&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Wed Aug 11 20:56:52 2010 @@ -83,22 +83,25 @@ // Interface for IRForTarget +void +ClangExpressionDeclMap::GetPersistentResultName (std::string &name) +{ + m_persistent_vars->GetNextResultName(m_result_name); + + name = m_result_name; +} + bool -ClangExpressionDeclMap::AddPersistentVariable (const clang::NamedDecl *decl) +ClangExpressionDeclMap::AddPersistentVariable (const char *name, TypeFromParser parser_type) { clang::ASTContext *context(m_exe_ctx->target->GetScratchClangASTContext()->getASTContext()); - const clang::VarDecl *var(dyn_cast(decl)); - - if (!var) - return false; - TypeFromUser user_type(ClangASTContext::CopyType(context, - &var->getASTContext(), - var->getType().getAsOpaquePtr()), + parser_type.GetASTContext(), + parser_type.GetOpaqueQualType()), context); - ConstString const_name(decl->getName().str().c_str()); + ConstString const_name(name); ClangPersistentVariable *pvar = m_persistent_vars->CreateVariable(const_name, user_type); @@ -292,10 +295,10 @@ bool ClangExpressionDeclMap::Dematerialize (ExecutionContext *exe_ctx, - lldb_private::Value &result_value, + ClangPersistentVariable *&result, Error &err) { - return DoMaterialize(true, exe_ctx, &result_value, err); + return DoMaterialize(true, exe_ctx, &result, err); } bool @@ -366,11 +369,11 @@ bool ClangExpressionDeclMap::DoMaterialize (bool dematerialize, ExecutionContext *exe_ctx, - lldb_private::Value *result_value, + ClangPersistentVariable **result, Error &err) { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - + if (!m_struct_laid_out) { err.SetErrorString("Structure hasn't been laid out yet"); @@ -426,35 +429,53 @@ if (!GetIndexForDecl(tuple_index, iter->m_decl)) { - if (iter->m_name[0] == '$') - { - if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, iter->m_name.c_str(), m_materialized_location + iter->m_offset, err)) - return false; - } - else if (iter->m_name.find("___clang_expr_result") != std::string::npos) + if (iter->m_name.find("___clang_expr_result") != std::string::npos) { - if (log) - log->Printf("Found special result variable %s", iter->m_name.c_str()); - if (dematerialize) { - clang::ASTContext *context(exe_ctx->target->GetScratchClangASTContext()->getASTContext()); + // Here we pick up the odd anomaly produced by + // IRForTarget::createResultVariable (and described in a comment + // there). + // + // We rename the variable to the name of the result PVar and + // incidentally drop the address of the PVar into *result + // (if it's non-NULL, of course). We then let this case fall + // through to the persistent variable handler. - if (!context) - { - err.SetErrorString("Couldn't find a scratch AST context to put the result type into"); - } + if (log) + log->PutCString("Found result member in the struct"); - TypeFromUser copied_type(ClangASTContext::CopyType(context, - iter->m_parser_type.GetASTContext(), - iter->m_parser_type.GetOpaqueQualType()), - context); + iter->m_name = m_result_name; - result_value->SetContext(Value::eContextTypeOpaqueClangQualType, copied_type.GetOpaqueQualType()); - - result_value->SetValueType(Value::eValueTypeLoadAddress); - result_value->GetScalar() = (uintptr_t)m_materialized_location + iter->m_offset; + if (result) + { + if (log) + log->PutCString("Returning result PVar"); + + *result = m_persistent_vars->GetVariable(ConstString(m_result_name.c_str())); + + if (!*result) + { + err.SetErrorStringWithFormat("Couldn't find persistent variable for result %s", m_result_name.c_str()); + } + } + else + { + if (log) + log->PutCString("Didn't return result PVar; pointer was NULL"); + } } + else + { + // The result variable doesn't need to be materialized, ever. + continue; + } + } + + if (iter->m_name[0] == '$') + { + if (!DoMaterializeOnePersistentVariable(dematerialize, *exe_ctx, iter->m_name.c_str(), m_materialized_location + iter->m_offset, err)) + return false; } else { Modified: lldb/trunk/source/Expression/ClangPersistentVariables.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangPersistentVariables.cpp?rev=110896&r1=110895&r2=110896&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangPersistentVariables.cpp (original) +++ lldb/trunk/source/Expression/ClangPersistentVariables.cpp Wed Aug 11 20:56:52 2010 @@ -8,11 +8,98 @@ //===----------------------------------------------------------------------===// #include "ClangPersistentVariables.h" +#include "lldb/Core/DataExtractor.h" #include "lldb/Core/Log.h" #include "lldb/Core/StreamString.h" +#include "lldb/Core/Value.h" using namespace lldb_private; -using namespace clang; + +Error +ClangPersistentVariable::Print (Stream &output_stream, + ExecutionContext &exe_ctx, + lldb::Format format, + bool show_types, + bool show_summary, + bool verbose) +{ + Error err; + + Value val; + + clang::ASTContext *ast_context = m_user_type.GetASTContext(); + + val.SetContext (Value::eContextTypeOpaqueClangQualType, m_user_type.GetOpaqueQualType ()); + val.SetValueType (Value::eValueTypeHostAddress); + val.GetScalar() = (uint64_t)Data (); + + val.ResolveValue (&exe_ctx, ast_context); + + if (val.GetContextType () == Value::eContextTypeInvalid && + val.GetValueType () == Value::eValueTypeScalar && + format == lldb::eFormatDefault) + { + // The expression result is just a scalar with no special formatting + val.GetScalar ().GetValue (&output_stream, show_types); + output_stream.EOL (); + return err; + } + + // The expression result is more complext and requires special handling + DataExtractor data; + Error expr_error = val.GetValueAsData (&exe_ctx, ast_context, data, 0); + + if (!expr_error.Success ()) + { + err.SetErrorToGenericError (); + err.SetErrorStringWithFormat ("Couldn't resolve result value: %s", expr_error.AsCString ()); + return err; + } + + if (format == lldb::eFormatDefault) + format = val.GetValueDefaultFormat (); + + void *clang_type = val.GetValueOpaqueClangQualType (); + + output_stream.Printf("%s = ", m_name.AsCString("")); + + if (clang_type) + { + if (show_types) + output_stream.Printf("(%s) ", ClangASTType::GetClangTypeName (clang_type).GetCString()); + + ClangASTType::DumpValue (ast_context, // The ASTContext that the clang type belongs to + clang_type, // The opaque clang type we want to dump that value of + &exe_ctx, // The execution context for memory and variable access + &output_stream, // Stream to dump to + format, // Format to use when dumping + data, // A buffer containing the bytes for the clang type + 0, // Byte offset within "data" where value is + data.GetByteSize (), // Size in bytes of the value we are dumping + 0, // Bitfield bit size + 0, // Bitfield bit offset + show_types, // Show types? + show_summary, // Show summary? + verbose, // Debug logging output? + UINT32_MAX); // Depth to dump in case this is an aggregate type + } + else + { + data.Dump (&output_stream, // Stream to dump to + 0, // Byte offset within "data" + format, // Format to use when dumping + data.GetByteSize (), // Size in bytes of each item we are dumping + 1, // Number of items to dump + UINT32_MAX, // Number of items per line + LLDB_INVALID_ADDRESS, // Invalid address, don't show any offset/address context + 0, // Bitfield bit size + 0); // Bitfield bit offset + } + + output_stream.EOL(); + + return err; +} ClangPersistentVariables::ClangPersistentVariables () : m_variables(), @@ -24,7 +111,7 @@ ClangPersistentVariables::CreateVariable (ConstString name, TypeFromUser user_type) { - ClangPersistentVariable new_var(user_type); + ClangPersistentVariable new_var(name, user_type); if (m_variables.find(name) != m_variables.end()) return NULL; @@ -35,21 +122,6 @@ } ClangPersistentVariable * -ClangPersistentVariables::CreateResultVariable (TypeFromUser user_type) -{ - StreamString s; - s.Printf("$%llu", m_result_counter); - ConstString name(s.GetString().c_str()); - - ClangPersistentVariable *ret = CreateVariable (name, user_type); - - if (ret != NULL) - ++m_result_counter; - - return ret; -} - -ClangPersistentVariable * ClangPersistentVariables::GetVariable (ConstString name) { if (m_variables.find(name) == m_variables.end()) @@ -57,3 +129,14 @@ return &m_variables[name]; } + +void +ClangPersistentVariables::GetNextResultName (std::string &name) +{ + StreamString s; + s.Printf("$%llu", m_result_counter); + + m_result_counter++; + + name = s.GetString(); +} Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=110896&r1=110895&r2=110896&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Wed Aug 11 20:56:52 2010 @@ -14,6 +14,7 @@ #include "llvm/Instructions.h" #include "llvm/Module.h" #include "llvm/Target/TargetData.h" +#include "llvm/ValueSymbolTable.h" #include "clang/AST/ASTContext.h" @@ -55,6 +56,129 @@ { } +bool +IRForTarget::createResultVariable(llvm::Module &M, + llvm::Function &F) +{ + lldb_private::Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); + + // Find the result variable + + Value *result_value = M.getNamedValue("___clang_expr_result"); + + if (!result_value) + { + if (log) + log->PutCString("Couldn't find result variable"); + return false; + } + + if (log) + log->Printf("Found result in the IR: %s", PrintValue(result_value, false).c_str()); + + GlobalVariable *result_global = dyn_cast(result_value); + + if (!result_global) + { + if (log) + log->PutCString("Result variable isn't a GlobalVariable"); + return false; + } + + // Find the metadata and follow it to the VarDecl + + NamedMDNode *named_metadata = M.getNamedMetadata("clang.global.decl.ptrs"); + + if (!named_metadata) + { + if (log) + log->PutCString("No global metadata"); + + return false; + } + + unsigned num_nodes = named_metadata->getNumOperands(); + unsigned node_index; + + MDNode *metadata_node = NULL; + + for (node_index = 0; + node_index < num_nodes; + ++node_index) + { + metadata_node = named_metadata->getOperand(node_index); + + if (metadata_node->getNumOperands() != 2) + continue; + + if (metadata_node->getOperand(0) == result_global) + break; + } + + if (!metadata_node) + { + if (log) + log->PutCString("Couldn't find result metadata"); + return false; + } + + ConstantInt *constant_int = dyn_cast(metadata_node->getOperand(1)); + + uint64_t result_decl_intptr = constant_int->getZExtValue(); + + clang::VarDecl *result_decl = reinterpret_cast(result_decl_intptr); + + // Get the next available result name from m_decl_map and create the persistent + // variable for it + + lldb_private::TypeFromParser result_decl_type (result_decl->getType().getAsOpaquePtr(), + &result_decl->getASTContext()); + std::string new_result_name; + + m_decl_map->GetPersistentResultName(new_result_name); + m_decl_map->AddPersistentVariable(new_result_name.c_str(), result_decl_type); + + if (log) + log->Printf("Creating a new result global: %s", new_result_name.c_str()); + + // Construct a new result global and set up its metadata + + GlobalVariable *new_result_global = new GlobalVariable(M, + result_global->getType()->getElementType(), + false, /* not constant */ + GlobalValue::ExternalLinkage, + NULL, /* no initializer */ + new_result_name.c_str()); + + // It's too late in compilation to create a new VarDecl for this, but we don't + // need to. We point the metadata at the old VarDecl. This creates an odd + // anomaly: a variable with a Value whose name is something like $0 and a + // Decl whose name is ___clang_expr_result. This condition is handled in + // ClangExpressionDeclMap::DoMaterialize, and the name of the variable is + // fixed up. + + ConstantInt *new_constant_int = ConstantInt::get(constant_int->getType(), + result_decl_intptr, + false); + + llvm::Value* values[2]; + values[0] = new_result_global; + values[1] = new_constant_int; + + MDNode *persistent_global_md = MDNode::get(M.getContext(), values, 2); + named_metadata->addOperand(persistent_global_md); + + if (log) + log->Printf("Replacing %s with %s", + PrintValue(result_global).c_str(), + PrintValue(new_result_global).c_str()); + + result_global->replaceAllUsesWith(new_result_global); + result_global->eraseFromParent(); + + return true; +} + static bool isObjCSelectorRef(Value *V) { GlobalVariable *GV = dyn_cast(V); @@ -234,9 +358,12 @@ uintptr_t ptr = constant_int->getZExtValue(); - clang::NamedDecl *decl = reinterpret_cast(ptr); + clang::VarDecl *decl = reinterpret_cast(ptr); + + lldb_private::TypeFromParser result_decl_type (decl->getType().getAsOpaquePtr(), + &decl->getASTContext()); - if (!m_decl_map->AddPersistentVariable(decl)) + if (!m_decl_map->AddPersistentVariable(decl->getName().str().c_str(), result_decl_type)) return false; GlobalVariable *persistent_global = new GlobalVariable(M, @@ -760,7 +887,7 @@ if (log) log->Printf(" %s (%s) placed at %d", - decl->getIdentifier()->getNameStart(), + value->getName().str().c_str(), PrintValue(value, true).c_str(), offset); @@ -797,6 +924,13 @@ Function::iterator bbi; + //////////////////////////////////////////////////////////// + // Replace __clang_expr_result with a persistent variable + // + + if (!createResultVariable(M, *function)) + return false; + ////////////////////////////////// // Run basic-block level passes // From jingham at apple.com Wed Aug 11 21:14:28 2010 From: jingham at apple.com (Jim Ingham) Date: Thu, 12 Aug 2010 02:14:28 -0000 Subject: [Lldb-commits] [lldb] r110899 - in /lldb/trunk: include/lldb/Target/Thread.h source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.h source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp source/Plugins/Process/gdb-remote/ThreadGDBRemote.h source/Target/Thread.cpp Message-ID: <20100812021428.5B5E52A6C12C@llvm.org> Author: jingham Date: Wed Aug 11 21:14:28 2010 New Revision: 110899 URL: http://llvm.org/viewvc/llvm-project?rev=110899&view=rev Log: Now that we are using the Unwinder (or Jason's new unwinder when that comes about) all the plugin-specific details of getting stack frames should be hidden behind that, and the "GetStackFrameAtIndex" and "GetStackFrameCount" algorithms become generic. So I moved them to Thread.cpp. Modified: lldb/trunk/include/lldb/Target/Thread.h lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.h lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h lldb/trunk/source/Target/Thread.cpp Modified: lldb/trunk/include/lldb/Target/Thread.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Target/Thread.h?rev=110899&r1=110898&r2=110899&view=diff ============================================================================== --- lldb/trunk/include/lldb/Target/Thread.h (original) +++ lldb/trunk/include/lldb/Target/Thread.h Wed Aug 11 21:14:28 2010 @@ -15,6 +15,7 @@ #include "lldb/Core/UserID.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/StackFrameList.h" +#include "libunwind/include/libunwind.h" #define LLDB_THREAD_MAX_STOP_EXC_DATA 8 @@ -298,10 +299,10 @@ } virtual uint32_t - GetStackFrameCount() = 0; + GetStackFrameCount(); virtual lldb::StackFrameSP - GetStackFrameAtIndex (uint32_t idx) = 0; + GetStackFrameAtIndex (uint32_t idx); lldb::StackFrameSP GetCurrentFrame (); @@ -661,6 +662,9 @@ typedef std::vector plan_stack; + virtual lldb_private::Unwind * + GetUnwinder () = 0; + //------------------------------------------------------------------ // Classes that inherit from Process can see and modify these //------------------------------------------------------------------ @@ -679,6 +683,7 @@ uint32_t m_current_frame_idx;///< The current frame for this thread int m_resume_signal; ///< The signal that should be used when continuing this thread. lldb::StateType m_resume_state; ///< The state that indicates what this thread should do when the process is resumed. + std::auto_ptr m_unwinder_ap; private: //------------------------------------------------------------------ // For Thread only Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp?rev=110899&r1=110898&r2=110899&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.cpp Wed Aug 11 21:14:28 2010 @@ -22,6 +22,10 @@ #include "lldb/Target/RegisterContext.h" #include "lldb/Breakpoint/WatchpointLocation.h" #include "lldb/Core/StreamString.h" +#include "lldb/Target/Unwind.h" +#include "LibUnwindRegisterContext.h" +#include "UnwindLibUnwind.h" +#include "UnwindMacOSXFrameBackchain.h" using namespace lldb; using namespace lldb_private; @@ -203,54 +207,28 @@ m_basic_info_string.clear(); } -uint32_t -ThreadMacOSX::GetStackFrameCount() -{ - if (m_fp_pc_pairs.empty()) - GetStackFrameData(m_fp_pc_pairs); - return m_fp_pc_pairs.size(); -} - -// Make sure that GetStackFrameAtIndex() does NOT call GetStackFrameCount() when -// getting the stack frame at index zero! This way GetStackFrameCount() (via -// GetStackFRameData()) can call this function to get the first frame in order -// to provide the first frame to a lower call for efficiency sake (avoid -// redundant lookups in the frame symbol context). -lldb::StackFrameSP -ThreadMacOSX::GetStackFrameAtIndex (uint32_t idx) +Unwind * +ThreadMacOSX::GetUnwinder () { - StackFrameSP frame_sp(m_frames.GetFrameAtIndex(idx)); - - if (frame_sp) - return frame_sp; - - // Don't try and fetch a frame while process is running - // Calling IsRunning isn't right here, because IsRunning reads the Public - // state but we need to be able to read the stack frames in the ShouldStop - // methods, which happen before the Public state has been updated. -// if (m_process.IsRunning()) -// return frame_sp; - - // Special case the first frame (idx == 0) so that we don't need to - // know how many stack frames there are to get it. If we need any other - // frames, then we do need to know if "idx" is a valid index. - if (idx == 0) - { - // If this is the first frame, we want to share the thread register - // context with the stack frame at index zero. - GetRegisterContext(); - assert (m_reg_context_sp.get()); - frame_sp.reset (new StackFrame (idx, *this, m_reg_context_sp, m_reg_context_sp->GetFP(), m_reg_context_sp->GetPC())); - } - else if (idx < GetStackFrameCount()) + if (m_unwinder_ap.get() == NULL) { - assert (idx < m_fp_pc_pairs.size()); - frame_sp.reset (new StackFrame (idx, *this, m_fp_pc_pairs[idx].first, m_fp_pc_pairs[idx].second)); + const ArchSpec target_arch (GetProcess().GetTarget().GetArchitecture ()); +#if 0 // Not sure this is the right thing to do for native, but this will all go away with Jason's new + // unwinder anyway... + if (target_arch == ArchSpec("x86_64") || target_arch == ArchSpec("i386")) + { + m_unwinder_ap.reset (new UnwindLibUnwind (*this, GetGDBProcess().GetLibUnwindAddressSpace())); + } + else +#endif + { + m_unwinder_ap.reset (new UnwindMacOSXFrameBackchain (*this)); + } } - m_frames.SetFrameAtIndex(idx, frame_sp); - return frame_sp; + return m_unwinder_ap.get(); } + void ThreadMacOSX::ClearStackFrames () { Modified: lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.h?rev=110899&r1=110898&r2=110899&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.h (original) +++ lldb/trunk/source/Plugins/Process/MacOSX-User/source/ThreadMacOSX.h Wed Aug 11 21:14:28 2010 @@ -51,12 +51,6 @@ virtual bool RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint); - virtual uint32_t - GetStackFrameCount(); - - virtual lldb::StackFrameSP - GetStackFrameAtIndex (uint32_t idx); - virtual void ClearStackFrames (); @@ -139,6 +133,9 @@ static bool GetBasicInfo (lldb::tid_t threadID, struct thread_basic_info *basic_info); + virtual lldb_private::Unwind * + GetUnwinder (); + //------------------------------------------------------------------ // Member variables. //------------------------------------------------------------------ Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp?rev=110899&r1=110898&r2=110899&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp Wed Aug 11 21:14:28 2010 @@ -38,8 +38,7 @@ Thread(process, tid), m_thread_name (), m_dispatch_queue_name (), - m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS), - m_unwinder_ap () + m_thread_dispatch_qaddr (LLDB_INVALID_ADDRESS) { // ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD | GDBR_LOG_VERBOSE, "ThreadGDBRemote::ThreadGDBRemote ( pid = %i, tid = 0x%4.4x, )", m_process.GetID(), GetID()); ProcessGDBRemoteLog::LogIf(GDBR_LOG_THREAD, "%p: ThreadGDBRemote::ThreadGDBRemote (pid = %i, tid = 0x%4.4x)", this, m_process.GetID(), GetID()); @@ -136,61 +135,6 @@ return m_unwinder_ap.get(); } -uint32_t -ThreadGDBRemote::GetStackFrameCount() -{ - Unwind *unwinder = GetUnwinder (); - if (unwinder) - return unwinder->GetFrameCount(); - return 0; -} - -// Make sure that GetStackFrameAtIndex() does NOT call GetStackFrameCount() when -// getting the stack frame at index zero! This way GetStackFrameCount() (via -// GetStackFRameData()) can call this function to get the first frame in order -// to provide the first frame to a lower call for efficiency sake (avoid -// redundant lookups in the frame symbol context). -lldb::StackFrameSP -ThreadGDBRemote::GetStackFrameAtIndex (uint32_t idx) -{ - - StackFrameSP frame_sp (m_frames.GetFrameAtIndex(idx)); - - if (frame_sp.get()) - return frame_sp; - - // Don't try and fetch a frame while process is running -// FIXME: This check isn't right because IsRunning checks the Public state, but this -// is work you need to do - for instance in ShouldStop & friends - before the public -// state has been changed. -// if (m_process.IsRunning()) -// return frame_sp; - - // Special case the first frame (idx == 0) so that we don't need to - // know how many stack frames there are to get it. If we need any other - // frames, then we do need to know if "idx" is a valid index. - if (idx == 0) - { - // If this is the first frame, we want to share the thread register - // context with the stack frame at index zero. - GetRegisterContext(); - assert (m_reg_context_sp.get()); - frame_sp.reset (new StackFrame (idx, *this, m_reg_context_sp, m_reg_context_sp->GetSP(), m_reg_context_sp->GetPC())); - } - else if (idx < GetStackFrameCount()) - { - Unwind *unwinder = GetUnwinder (); - if (unwinder) - { - addr_t pc, cfa; - if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) - frame_sp.reset (new StackFrame (idx, *this, cfa, pc)); - } - } - m_frames.SetFrameAtIndex(idx, frame_sp); - return frame_sp; -} - void ThreadGDBRemote::ClearStackFrames () { Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h?rev=110899&r1=110898&r2=110899&view=diff ============================================================================== --- lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h (original) +++ lldb/trunk/source/Plugins/Process/gdb-remote/ThreadGDBRemote.h Wed Aug 11 21:14:28 2010 @@ -54,12 +54,6 @@ virtual bool RestoreSaveFrameZero (const RegisterCheckpoint &checkpoint); - virtual uint32_t - GetStackFrameCount(); - - virtual lldb::StackFrameSP - GetStackFrameAtIndex (uint32_t idx); - virtual void ClearStackFrames (); @@ -121,12 +115,11 @@ std::string m_thread_name; std::string m_dispatch_queue_name; lldb::addr_t m_thread_dispatch_qaddr; - std::auto_ptr m_unwinder_ap; //------------------------------------------------------------------ // Member variables. //------------------------------------------------------------------ - lldb_private::Unwind * + virtual lldb_private::Unwind * GetUnwinder (); void Modified: lldb/trunk/source/Target/Thread.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Target/Thread.cpp?rev=110899&r1=110898&r2=110899&view=diff ============================================================================== --- lldb/trunk/source/Target/Thread.cpp (original) +++ lldb/trunk/source/Target/Thread.cpp Wed Aug 11 21:14:28 2010 @@ -32,6 +32,7 @@ #include "lldb/Target/ThreadPlanRunToAddress.h" #include "lldb/Target/ThreadPlanStepUntil.h" #include "lldb/Target/ThreadSpec.h" +#include "lldb/Target/Unwind.h" using namespace lldb; using namespace lldb_private; @@ -51,7 +52,9 @@ m_frames (), m_current_frame_idx (0), m_resume_signal (LLDB_INVALID_SIGNAL_NUMBER), - m_resume_state (eStateRunning) + m_resume_state (eStateRunning), + m_unwinder_ap () + { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT); if (log) @@ -790,6 +793,56 @@ exe_ctx.frame = NULL; } +uint32_t +Thread::GetStackFrameCount() +{ + Unwind *unwinder = GetUnwinder (); + if (unwinder) + return unwinder->GetFrameCount(); + return 0; +} + +lldb::StackFrameSP +Thread::GetStackFrameAtIndex (uint32_t idx) +{ + + StackFrameSP frame_sp (m_frames.GetFrameAtIndex(idx)); + + if (frame_sp.get()) + return frame_sp; + + // Don't try and fetch a frame while process is running +// FIXME: This check isn't right because IsRunning checks the Public state, but this +// is work you need to do - for instance in ShouldStop & friends - before the public +// state has been changed. +// if (m_process.IsRunning()) +// return frame_sp; + + // Special case the first frame (idx == 0) so that we don't need to + // know how many stack frames there are to get it. If we need any other + // frames, then we do need to know if "idx" is a valid index. + if (idx == 0) + { + // If this is the first frame, we want to share the thread register + // context with the stack frame at index zero. + GetRegisterContext(); + assert (m_reg_context_sp.get()); + frame_sp.reset (new StackFrame (idx, *this, m_reg_context_sp, m_reg_context_sp->GetSP(), m_reg_context_sp->GetPC())); + } + else if (idx < GetStackFrameCount()) + { + Unwind *unwinder = GetUnwinder (); + if (unwinder) + { + addr_t pc, cfa; + if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) + frame_sp.reset (new StackFrame (idx, *this, cfa, pc)); + } + } + m_frames.SetFrameAtIndex(idx, frame_sp); + return frame_sp; +} + lldb::StackFrameSP Thread::GetCurrentFrame () { From johnny.chen at apple.com Thu Aug 12 14:42:59 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Thu, 12 Aug 2010 19:42:59 -0000 Subject: [Lldb-commits] [lldb] r110943 - /lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h Message-ID: <20100812194259.ACD9C2A6C12C@llvm.org> Author: johnny Date: Thu Aug 12 14:42:59 2010 New Revision: 110943 URL: http://llvm.org/viewvc/llvm-project?rev=110943&view=rev Log: Applied Pawel Wodnicki's fix for "missing" lldb-forward-rtti.h header file. Modified: lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h Modified: lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h?rev=110943&r1=110942&r2=110943&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h (original) +++ lldb/trunk/include/lldb/Expression/ClangPersistentVariables.h Thu Aug 12 14:42:59 2010 @@ -10,7 +10,7 @@ #ifndef liblldb_ClangPersistentVariables_h_ #define liblldb_ClangPersistentVariables_h_ -#include "lldb-forward-rtti.h" +#include "lldb/lldb-forward-rtti.h" #include "lldb/Core/ConstString.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Symbol/TaggedASTType.h" @@ -99,4 +99,4 @@ } -#endif \ No newline at end of file +#endif From scallanan at apple.com Thu Aug 12 16:29:03 2010 From: scallanan at apple.com (Sean Callanan) Date: Thu, 12 Aug 2010 21:29:03 -0000 Subject: [Lldb-commits] [lldb] r110957 - in /lldb/trunk: include/lldb/Expression/ClangExpression.h include/lldb/Expression/ClangStmtVisitor.h lldb.xcodeproj/project.pbxproj source/Expression/ClangExpression.cpp source/Expression/ClangStmtVisitor.cpp Message-ID: <20100812212904.124C22A6C12C@llvm.org> Author: spyffe Date: Thu Aug 12 16:29:03 2010 New Revision: 110957 URL: http://llvm.org/viewvc/llvm-project?rev=110957&view=rev Log: Removed the ClangStmtVisitor, which is old code that translates Clang ASTs straight to DWARF. We are now using IR instead. Removed: lldb/trunk/include/lldb/Expression/ClangStmtVisitor.h lldb/trunk/source/Expression/ClangStmtVisitor.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpression.h lldb/trunk/lldb.xcodeproj/project.pbxproj lldb/trunk/source/Expression/ClangExpression.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpression.h?rev=110957&r1=110956&r2=110957&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpression.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpression.h Thu Aug 12 16:29:03 2010 @@ -59,10 +59,6 @@ Stream &stream, bool add_result_var = false); - unsigned - ConvertExpressionToDWARF (ClangExpressionVariableList &expr_local_variable_list, - StreamString &dwarf_opcode_strm); - bool ConvertIRToDWARF (ClangExpressionVariableList &excpr_local_variable_list, StreamString &dwarf_opcode_strm); Removed: lldb/trunk/include/lldb/Expression/ClangStmtVisitor.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangStmtVisitor.h?rev=110956&view=auto ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangStmtVisitor.h (original) +++ lldb/trunk/include/lldb/Expression/ClangStmtVisitor.h (removed) @@ -1,109 +0,0 @@ -//===-- ClangStmtVisitor.h --------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#ifndef liblldb_ClangStmtVisitor_h_ -#define liblldb_ClangStmtVisitor_h_ - -// C Includes -// C++ Includes - -// Other libraries and framework includes -#include "clang/AST/StmtVisitor.h" - -// Project includes -#include "lldb/Core/ClangForward.h" - -namespace lldb_private { - -class StreamString; -class ClangExpressionDeclMap; -class ClangExpressionVariableList; - -#define CLANG_STMT_RESULT void - -class ClangStmtVisitor : public clang::StmtVisitor -{ -public: - //------------------------------------------------------------------ - // Constructors and Destructors - //------------------------------------------------------------------ - ClangStmtVisitor (clang::ASTContext &ast_context, - ClangExpressionVariableList &variable_list, - ClangExpressionDeclMap *decl_map, - StreamString &strm); - virtual ~ClangStmtVisitor (); - - // Stmts. - CLANG_STMT_RESULT VisitStmt (clang::Stmt *Node); - CLANG_STMT_RESULT VisitDeclStmt (clang::DeclStmt *Node); - CLANG_STMT_RESULT VisitLabelStmt (clang::LabelStmt *Node); - CLANG_STMT_RESULT VisitGotoStmt (clang::GotoStmt *Node); - - // Exprs - CLANG_STMT_RESULT VisitExpr (clang::Expr *Node); - CLANG_STMT_RESULT VisitDeclRefExpr (clang::DeclRefExpr *Node); - CLANG_STMT_RESULT VisitPredefinedExpr (clang::PredefinedExpr *Node); - CLANG_STMT_RESULT VisitCharacterLiteral (clang::CharacterLiteral *Node); - CLANG_STMT_RESULT VisitIntegerLiteral (clang::IntegerLiteral *Node); - CLANG_STMT_RESULT VisitFloatingLiteral (clang::FloatingLiteral *Node); - CLANG_STMT_RESULT VisitStringLiteral (clang::StringLiteral *Str); - CLANG_STMT_RESULT VisitUnaryOperator (clang::UnaryOperator *Node); - CLANG_STMT_RESULT VisitSizeOfAlignOfExpr (clang::SizeOfAlignOfExpr *Node); - CLANG_STMT_RESULT VisitMemberExpr (clang::MemberExpr *Node); - CLANG_STMT_RESULT VisitExtVectorElementExpr (clang::ExtVectorElementExpr *Node); - CLANG_STMT_RESULT VisitBinaryOperator (clang::BinaryOperator *Node); -// CLANG_STMT_RESULT VisitCompoundAssignOperator (clang::CompoundAssignOperator *Node); - CLANG_STMT_RESULT VisitAddrLabelExpr (clang::AddrLabelExpr *Node); - CLANG_STMT_RESULT VisitTypesCompatibleExpr (clang::TypesCompatibleExpr *Node); - CLANG_STMT_RESULT VisitParenExpr(clang::ParenExpr *Node); - CLANG_STMT_RESULT VisitInitListExpr (clang::InitListExpr *Node); - CLANG_STMT_RESULT VisitCastExpr (clang::CastExpr *Node); -// CLANG_STMT_RESULT VisitImplicitCastExpr (clang::ImplicitCastExpr *Node); - CLANG_STMT_RESULT VisitArraySubscriptExpr (clang::ArraySubscriptExpr *Node); - // C++ - CLANG_STMT_RESULT VisitCXXNamedCastExpr (clang::CXXNamedCastExpr *Node); - CLANG_STMT_RESULT VisitCXXBoolLiteralExpr (clang::CXXBoolLiteralExpr *Node); - CLANG_STMT_RESULT VisitCXXThisExpr (clang::CXXThisExpr *Node); - CLANG_STMT_RESULT VisitCXXFunctionalCastExpr (clang::CXXFunctionalCastExpr *Node); - - // ObjC - CLANG_STMT_RESULT VisitObjCEncodeExpr (clang::ObjCEncodeExpr *Node); - CLANG_STMT_RESULT VisitObjCMessageExpr (clang::ObjCMessageExpr* Node); - CLANG_STMT_RESULT VisitObjCSelectorExpr (clang::ObjCSelectorExpr *Node); - CLANG_STMT_RESULT VisitObjCProtocolExpr (clang::ObjCProtocolExpr *Node); - CLANG_STMT_RESULT VisitObjCPropertyRefExpr (clang::ObjCPropertyRefExpr *Node); - CLANG_STMT_RESULT VisitObjCImplicitSetterGetterRefExpr (clang::ObjCImplicitSetterGetterRefExpr *Node); - CLANG_STMT_RESULT VisitObjCIvarRefExpr (clang::ObjCIvarRefExpr *Node); - CLANG_STMT_RESULT VisitObjCSuperExpr (clang::ObjCSuperExpr *Node); - -protected: - //------------------------------------------------------------------ - // Classes that inherit from ClangStmtVisitor can see and modify these - //------------------------------------------------------------------ - clang::ASTContext &m_ast_context; - ClangExpressionDeclMap *m_decl_map; - ClangExpressionVariableList &m_variable_list; - StreamString &m_stream; -private: - //------------------------------------------------------------------ - // For ClangStmtVisitor only - //------------------------------------------------------------------ - ClangStmtVisitor (const ClangStmtVisitor&); - const ClangStmtVisitor& operator= (const ClangStmtVisitor&); - - bool - EncodeUInt64 (uint64_t uval, uint32_t bit_size); - - bool - EncodeSInt64 (int64_t sval, uint32_t bit_size); -}; - -} // namespace lldb_private - -#endif // liblldb_ClangStmtVisitor_h_ Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=110957&r1=110956&r2=110957&view=diff ============================================================================== --- lldb/trunk/lldb.xcodeproj/project.pbxproj (original) +++ lldb/trunk/lldb.xcodeproj/project.pbxproj Thu Aug 12 16:29:03 2010 @@ -154,8 +154,6 @@ 26D5B0BC11B07550009A862E /* VMRange.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7E9E10F1B85900F91463 /* VMRange.cpp */; }; 26D5B0BD11B07550009A862E /* ClangExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7ED510F1B86700F91463 /* ClangExpression.cpp */; }; 26D5B0BE11B07550009A862E /* ClangExpressionVariable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7ED610F1B86700F91463 /* ClangExpressionVariable.cpp */; }; - 26D5B0BF11B07550009A862E /* ClangStmtVisitor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7ED710F1B86700F91463 /* ClangStmtVisitor.cpp */; }; - 26D5B0C011B07550009A862E /* DWARFExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7ED810F1B86700F91463 /* DWARFExpression.cpp */; }; 26D5B0C111B07550009A862E /* Condition.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EE710F1B88F00F91463 /* Condition.cpp */; }; 26D5B0C211B07550009A862E /* Host.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EE810F1B88F00F91463 /* Host.mm */; }; 26D5B0C311B07550009A862E /* Mutex.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7EE910F1B88F00F91463 /* Mutex.cpp */; }; @@ -347,6 +345,7 @@ 49E45FAF11F660FE008F7B28 /* ClangASTType.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49E45FAD11F660FE008F7B28 /* ClangASTType.cpp */; }; 49F1A74611B3388F003ED505 /* ClangExpressionDeclMap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 49F1A74511B3388F003ED505 /* ClangExpressionDeclMap.cpp */; }; 49F1A74A11B338AE003ED505 /* ClangExpressionDeclMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 49F1A74911B338AE003ED505 /* ClangExpressionDeclMap.h */; }; + 49FB515E121481B000DF8983 /* DWARFExpression.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BC7ED810F1B86700F91463 /* DWARFExpression.cpp */; }; 4C08CDE811C81EF8001610A8 /* ThreadSpec.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C08CDE711C81EF8001610A8 /* ThreadSpec.cpp */; }; 4C08CDEC11C81F1E001610A8 /* ThreadSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C08CDEB11C81F1E001610A8 /* ThreadSpec.h */; }; 4C5DBBC811E3FEC60035160F /* CommandObjectCommands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4C5DBBC611E3FEC60035160F /* CommandObjectCommands.cpp */; }; @@ -684,7 +683,6 @@ 26BC7D8610F1B77400F91463 /* VMRange.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VMRange.h; path = include/lldb/Core/VMRange.h; sourceTree = ""; }; 26BC7DC010F1B79500F91463 /* ClangExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangExpression.h; path = include/lldb/Expression/ClangExpression.h; sourceTree = ""; }; 26BC7DC110F1B79500F91463 /* ClangExpressionVariable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangExpressionVariable.h; path = include/lldb/Expression/ClangExpressionVariable.h; sourceTree = ""; }; - 26BC7DC210F1B79500F91463 /* ClangStmtVisitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ClangStmtVisitor.h; path = include/lldb/Expression/ClangStmtVisitor.h; sourceTree = ""; }; 26BC7DC310F1B79500F91463 /* DWARFExpression.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DWARFExpression.h; path = include/lldb/Expression/DWARFExpression.h; sourceTree = ""; }; 26BC7DD210F1B7D500F91463 /* Condition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Condition.h; path = include/lldb/Host/Condition.h; sourceTree = ""; }; 26BC7DD310F1B7D500F91463 /* Endian.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Endian.h; path = include/lldb/Host/Endian.h; sourceTree = ""; }; @@ -796,7 +794,6 @@ 26BC7E9E10F1B85900F91463 /* VMRange.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = VMRange.cpp; path = source/Core/VMRange.cpp; sourceTree = ""; }; 26BC7ED510F1B86700F91463 /* ClangExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangExpression.cpp; path = source/Expression/ClangExpression.cpp; sourceTree = ""; }; 26BC7ED610F1B86700F91463 /* ClangExpressionVariable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangExpressionVariable.cpp; path = source/Expression/ClangExpressionVariable.cpp; sourceTree = ""; }; - 26BC7ED710F1B86700F91463 /* ClangStmtVisitor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ClangStmtVisitor.cpp; path = source/Expression/ClangStmtVisitor.cpp; sourceTree = ""; }; 26BC7ED810F1B86700F91463 /* DWARFExpression.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DWARFExpression.cpp; path = source/Expression/DWARFExpression.cpp; sourceTree = ""; }; 26BC7EE710F1B88F00F91463 /* Condition.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Condition.cpp; path = source/Host/posix/Condition.cpp; sourceTree = ""; }; 26BC7EE810F1B88F00F91463 /* Host.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = Host.mm; path = source/Host/macosx/Host.mm; sourceTree = ""; }; @@ -1859,8 +1856,6 @@ 49D4FE871210B61C00CDB854 /* ClangPersistentVariables.cpp */, 49A8A3A311D568BF00AD3B68 /* ClangResultSynthesizer.h */, 49A8A39F11D568A300AD3B68 /* ClangResultSynthesizer.cpp */, - 26BC7DC210F1B79500F91463 /* ClangStmtVisitor.h */, - 26BC7ED710F1B86700F91463 /* ClangStmtVisitor.cpp */, 26BC7DC310F1B79500F91463 /* DWARFExpression.h */, 26BC7ED810F1B86700F91463 /* DWARFExpression.cpp */, 49307AB111DEA4F20081F992 /* IRForTarget.h */, @@ -2487,8 +2482,6 @@ 26D5B0BC11B07550009A862E /* VMRange.cpp in Sources */, 26D5B0BD11B07550009A862E /* ClangExpression.cpp in Sources */, 26D5B0BE11B07550009A862E /* ClangExpressionVariable.cpp in Sources */, - 26D5B0BF11B07550009A862E /* ClangStmtVisitor.cpp in Sources */, - 26D5B0C011B07550009A862E /* DWARFExpression.cpp in Sources */, 26D5B0C111B07550009A862E /* Condition.cpp in Sources */, 26D5B0C211B07550009A862E /* Host.mm in Sources */, 26D5B0C311B07550009A862E /* Mutex.cpp in Sources */, @@ -2688,6 +2681,7 @@ 2615DB871208A9E40021781D /* StopInfo.cpp in Sources */, 2615DBCA1208B5FC0021781D /* StopInfoMachException.cpp in Sources */, 49D4FE891210B61C00CDB854 /* ClangPersistentVariables.cpp in Sources */, + 49FB515E121481B000DF8983 /* DWARFExpression.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; Modified: lldb/trunk/source/Expression/ClangExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpression.cpp?rev=110957&r1=110956&r2=110957&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangExpression.cpp Thu Aug 12 16:29:03 2010 @@ -46,6 +46,7 @@ #include "llvm/Module.h" #include "llvm/ADT/StringRef.h" #include "llvm/LLVMContext.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/System/DynamicLibrary.h" #include "llvm/System/Host.h" @@ -61,7 +62,6 @@ #include "lldb/Expression/ClangExpression.h" #include "lldb/Expression/ClangASTSource.h" #include "lldb/Expression/ClangResultSynthesizer.h" -#include "lldb/Expression/ClangStmtVisitor.h" #include "lldb/Expression/IRForTarget.h" #include "lldb/Expression/IRToDWARF.h" #include "lldb/Symbol/ClangASTContext.h" @@ -440,29 +440,6 @@ return num_errors; } -unsigned -ClangExpression::ConvertExpressionToDWARF (ClangExpressionVariableList& expr_local_variable_list, - StreamString &dwarf_opcode_strm) -{ - CompilerInstance *compiler_instance = GetCompilerInstance(); - - DeclarationName hack_func_name(&compiler_instance->getASTContext().Idents.get("___clang_expr")); - DeclContext::lookup_result result = compiler_instance->getASTContext().getTranslationUnitDecl()->lookup(hack_func_name); - - if (result.first != result.second) - { - Decl *decl = *result.first; - Stmt *decl_stmt = decl->getBody(); - if (decl_stmt) - { - ClangStmtVisitor visitor(compiler_instance->getASTContext(), expr_local_variable_list, m_decl_map, dwarf_opcode_strm); - - visitor.Visit (decl_stmt); - } - } - return 0; -} - bool ClangExpression::ConvertIRToDWARF (ClangExpressionVariableList &expr_local_variable_list, StreamString &dwarf_opcode_strm) Removed: lldb/trunk/source/Expression/ClangStmtVisitor.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangStmtVisitor.cpp?rev=110956&view=auto ============================================================================== --- lldb/trunk/source/Expression/ClangStmtVisitor.cpp (original) +++ lldb/trunk/source/Expression/ClangStmtVisitor.cpp (removed) @@ -1,1022 +0,0 @@ -//===-- ClangStmtVisitor.cpp ------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "lldb/Expression/ClangStmtVisitor.h" - -// C Includes -// C++ Includes -// Other libraries and framework includes -#include "clang/AST/RecordLayout.h" - -#include "lldb/Core/dwarf.h" -#include "lldb/Core/Scalar.h" -#include "lldb/Core/StreamString.h" -#include "lldb/Expression/ClangExpressionDeclMap.h" -#include "lldb/Expression/ClangExpressionVariable.h" - -//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN -#ifdef ENABLE_DEBUG_PRINTF -#include -#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__) -#else -#define DEBUG_PRINTF(fmt, ...) -#endif - -// Project includes - -static lldb_private::Scalar::Type -GetScalarTypeForClangType (clang::ASTContext &ast_context, clang::QualType clang_type, uint32_t &count) -{ - count = 1; - - switch (clang_type->getTypeClass()) - { - default: - break; - - case clang::Type::FunctionNoProto: - case clang::Type::FunctionProto: - break; - - case clang::Type::IncompleteArray: - case clang::Type::VariableArray: - break; - - case clang::Type::ConstantArray: - break; - - case clang::Type::ExtVector: - case clang::Type::Vector: - // TODO: Set this to more than one??? - break; - - case clang::Type::Builtin: - switch (cast(clang_type)->getKind()) - { - default: assert(0 && "Unknown builtin type!"); - case clang::BuiltinType::Void: - break; - - case clang::BuiltinType::Bool: - case clang::BuiltinType::Char_S: - case clang::BuiltinType::SChar: - case clang::BuiltinType::WChar: - case clang::BuiltinType::Char16: - case clang::BuiltinType::Char32: - case clang::BuiltinType::Short: - case clang::BuiltinType::Int: - case clang::BuiltinType::Long: - case clang::BuiltinType::LongLong: - case clang::BuiltinType::Int128: - return lldb_private::Scalar::GetValueTypeForSignedIntegerWithByteSize ((ast_context.getTypeSize(clang_type)/CHAR_BIT)/count); - - case clang::BuiltinType::Char_U: - case clang::BuiltinType::UChar: - case clang::BuiltinType::UShort: - case clang::BuiltinType::UInt: - case clang::BuiltinType::ULong: - case clang::BuiltinType::ULongLong: - case clang::BuiltinType::UInt128: - case clang::BuiltinType::NullPtr: - return lldb_private::Scalar::GetValueTypeForUnsignedIntegerWithByteSize ((ast_context.getTypeSize(clang_type)/CHAR_BIT)/count); - - case clang::BuiltinType::Float: - case clang::BuiltinType::Double: - case clang::BuiltinType::LongDouble: - return lldb_private::Scalar::GetValueTypeForFloatWithByteSize ((ast_context.getTypeSize(clang_type)/CHAR_BIT)/count); - } - break; - // All pointer types are represented as unsigned integer encodings. - // We may nee to add a eEncodingPointer if we ever need to know the - // difference - case clang::Type::ObjCObjectPointer: - case clang::Type::BlockPointer: - case clang::Type::Pointer: - case clang::Type::LValueReference: - case clang::Type::RValueReference: - case clang::Type::MemberPointer: - return lldb_private::Scalar::GetValueTypeForUnsignedIntegerWithByteSize ((ast_context.getTypeSize(clang_type)/CHAR_BIT)/count); - - // Complex numbers are made up of floats - case clang::Type::Complex: - count = 2; - return lldb_private::Scalar::GetValueTypeForFloatWithByteSize ((ast_context.getTypeSize(clang_type)/CHAR_BIT) / count); - - case clang::Type::ObjCInterface: break; - case clang::Type::Record: break; - case clang::Type::Enum: - return lldb_private::Scalar::GetValueTypeForSignedIntegerWithByteSize ((ast_context.getTypeSize(clang_type)/CHAR_BIT)/count); - - case clang::Type::Typedef: - return GetScalarTypeForClangType(ast_context, cast(clang_type)->LookThroughTypedefs(), count); - break; - - case clang::Type::TypeOfExpr: - case clang::Type::TypeOf: - case clang::Type::Decltype: - //case clang::Type::QualifiedName: - case clang::Type::TemplateSpecialization: break; - } - count = 0; - return lldb_private::Scalar::e_void; -} - -//---------------------------------------------------------------------- -// ClangStmtVisitor constructor -//---------------------------------------------------------------------- -lldb_private::ClangStmtVisitor::ClangStmtVisitor -( - clang::ASTContext &ast_context, - lldb_private::ClangExpressionVariableList &variable_list, - lldb_private::ClangExpressionDeclMap *decl_map, - lldb_private::StreamString &strm -) : - m_ast_context (ast_context), - m_decl_map (decl_map), - m_variable_list (variable_list), - m_stream (strm) -{ -} - -//---------------------------------------------------------------------- -// Destructor -//---------------------------------------------------------------------- -lldb_private::ClangStmtVisitor::~ClangStmtVisitor() -{ -} - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitStmt (clang::Stmt *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); - - clang::Stmt::child_iterator pos; - clang::Stmt::child_iterator begin = Node->child_begin(); - clang::Stmt::child_iterator end = Node->child_end(); - bool clear_before_next_stmt = false; - for (pos = begin; pos != end; ++pos) - { -#ifdef ENABLE_DEBUG_PRINTF - pos->dump(); -#endif - clang::Stmt *child_stmt = *pos; - uint32_t pre_visit_stream_offset = m_stream.GetSize(); - bool not_null_stmt = dyn_cast(child_stmt) == NULL; - if (clear_before_next_stmt && not_null_stmt) - m_stream.PutHex8(DW_OP_APPLE_clear); - Visit (child_stmt); - if (not_null_stmt) - clear_before_next_stmt = pre_visit_stream_offset != m_stream.GetSize(); - } -} - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitDeclStmt (clang::DeclStmt *decl_stmt) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); - clang::DeclGroupRef decl_group_ref = decl_stmt->getDeclGroup(); - clang::DeclGroupRef::iterator pos, end = decl_group_ref.end(); - for (pos = decl_group_ref.begin(); pos != end; ++pos) - { - clang::Decl *decl = *pos; - if (decl) - { - clang::Decl::Kind decl_kind = decl->getKind(); - - switch (decl_kind) - { - case clang::Decl::Namespace: - case clang::Decl::Enum: - case clang::Decl::Record: - case clang::Decl::CXXRecord: - case clang::Decl::ObjCMethod: - case clang::Decl::ObjCInterface: - case clang::Decl::ObjCCategory: - case clang::Decl::ObjCProtocol: - case clang::Decl::ObjCImplementation: - case clang::Decl::ObjCCategoryImpl: - case clang::Decl::LinkageSpec: - case clang::Decl::Block: - case clang::Decl::Function: - case clang::Decl::CXXMethod: - case clang::Decl::CXXConstructor: - case clang::Decl::CXXDestructor: - case clang::Decl::CXXConversion: - case clang::Decl::Field: - case clang::Decl::Typedef: - case clang::Decl::EnumConstant: - case clang::Decl::ImplicitParam: - case clang::Decl::ParmVar: - case clang::Decl::ObjCProperty: - break; - - case clang::Decl::Var: - { - const clang::VarDecl *var_decl = cast(decl)->getCanonicalDecl(); - uint32_t expr_local_var_idx = UINT32_MAX; - if (m_variable_list.GetVariableForVarDecl (m_ast_context, var_decl, expr_local_var_idx, true)) - { - const clang::Expr* var_decl_expr = var_decl->getAnyInitializer(); - // If there is an inialization expression, then assign the - // variable. - if (var_decl_expr) - { - m_stream.PutHex8(DW_OP_APPLE_expr_local); - m_stream.PutULEB128(expr_local_var_idx); - Visit ((clang::Stmt *)var_decl_expr); - m_stream.PutHex8(DW_OP_APPLE_assign); - } - } - } - break; - - default: - assert(!"decl unhandled"); - break; - } - } - } -} - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitLabelStmt (clang::LabelStmt *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitGotoStmt (clang::GotoStmt *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -// Exprs -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitExpr (clang::Expr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitDeclRefExpr (clang::DeclRefExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); - clang::NamedDecl *decl = Node->getDecl(); - clang::QualType clang_type = Node->getType(); - -#ifdef ENABLE_DEBUG_PRINTF - //decl->dump(); - //clang_type.dump("lldb_private::ClangStmtVisitor::VisitDeclRefExpr() -> clang_type.dump() = "); -#endif - uint32_t expr_local_var_idx = UINT32_MAX; - if (m_variable_list.GetVariableForVarDecl (m_ast_context, cast(decl)->getCanonicalDecl(), expr_local_var_idx, false) && - expr_local_var_idx != UINT32_MAX) - { - m_stream.PutHex8(DW_OP_APPLE_expr_local); - m_stream.PutULEB128(expr_local_var_idx); - } - else if (m_decl_map && - m_decl_map->GetIndexForDecl(expr_local_var_idx, decl->getCanonicalDecl())) - { - m_stream.PutHex8(DW_OP_APPLE_extern); - m_stream.PutULEB128(expr_local_var_idx); - } - else - { - m_stream.PutHex8 (DW_OP_APPLE_error); - } -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitPredefinedExpr (clang::PredefinedExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitCharacterLiteral (clang::CharacterLiteral *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); - clang::QualType clang_type = Node->getType(); - uint64_t clang_type_size = m_ast_context.getTypeSize (clang_type); - if (clang_type_size <= 64) - { - // Encode the integer into our DWARF expression - if (clang_type->isSignedIntegerType()) - EncodeSInt64(Node->getValue(), clang_type_size); - else - EncodeUInt64(Node->getValue(), clang_type_size); - } - else - { - // TODO: eventually support integer math over 64 bits, probably using - // APInt as the class. - m_stream.PutHex8(DW_OP_APPLE_error); - } -} - -bool -lldb_private::ClangStmtVisitor::EncodeUInt64 (uint64_t uval, uint32_t bit_size) -{ - // If "bit_size" is zero, then encode "uval" in the most efficient way - if (bit_size <= 8 || (bit_size == 0 && uval <= UINT8_MAX)) - { - m_stream.PutHex8 (DW_OP_const1u); - m_stream.PutHex8 (uval); - } - else if (bit_size <= 16 || (bit_size == 0 && uval <= UINT16_MAX)) - { - m_stream.PutHex8 (DW_OP_const2u); - m_stream.PutHex16 (uval); - } - else if (bit_size <= 32 || (bit_size == 0 && uval <= UINT32_MAX)) - { - m_stream.PutHex8 (DW_OP_const4u); - m_stream.PutHex32 (uval); - } - else if (bit_size <= 64 || (bit_size == 0)) - { - m_stream.PutHex8 (DW_OP_const8u); - m_stream.PutHex64 (uval); - } - else - { - m_stream.PutHex8 (DW_OP_APPLE_error); - return false; - } - return true; -} - -bool -lldb_private::ClangStmtVisitor::EncodeSInt64 (int64_t sval, uint32_t bit_size) -{ - if (bit_size <= 8 || (bit_size == 0 && INT8_MIN <= sval && sval <= INT8_MAX)) - { - m_stream.PutHex8 (DW_OP_const1s); - m_stream.PutHex8 (sval); - } - else if (bit_size <= 16 || (bit_size == 0 && INT16_MIN <= sval && sval <= INT16_MAX)) - { - m_stream.PutHex8 (DW_OP_const2s); - m_stream.PutHex16 (sval); - } - else if (bit_size <= 32 || (bit_size == 0 && INT32_MIN <= sval && sval <= INT32_MAX)) - { - m_stream.PutHex8 (DW_OP_const4s); - m_stream.PutHex32 (sval); - } - else if (bit_size <= 64 || (bit_size == 0)) - { - m_stream.PutHex8 (DW_OP_const8s); - m_stream.PutHex64 (sval); - } - else - { - m_stream.PutHex8 (DW_OP_APPLE_error); - return false; - } - return true; -} - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitIntegerLiteral (clang::IntegerLiteral *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); - const llvm::APInt &ap_int = Node->getValue(); - if (ap_int.getBitWidth() <= 64) - { - clang::QualType clang_type = Node->getType(); - uint64_t clang_type_size = m_ast_context.getTypeSize (clang_type); - // Encode the integer into our DWARF expression - if (clang_type->isSignedIntegerType()) - EncodeSInt64(ap_int.getLimitedValue(), clang_type_size); - else - EncodeUInt64(ap_int.getLimitedValue(), clang_type_size); - } - else - { - // TODO: eventually support integer math over 64 bits, probably using - // APInt as the class. - m_stream.PutHex8(DW_OP_APPLE_error); - } -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitFloatingLiteral (clang::FloatingLiteral *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); - const llvm::APFloat &ap_float = Node->getValue(); - // Put the length of the float in bytes into a single byte - llvm::APInt ap_int(ap_float.bitcastToAPInt()); - const unsigned byte_size = ap_int.getBitWidth() / CHAR_BIT; - if (byte_size == sizeof(float)) - { - if (sizeof(float) == 4) - { - m_stream.PutHex8(DW_OP_APPLE_constf); - m_stream.PutHex8 (byte_size); - m_stream.PutHex32 (ap_int.getLimitedValue()); - return; - } - else if (sizeof(float) == 8) - { - m_stream.PutHex8(DW_OP_APPLE_constf); - m_stream.PutHex8 (byte_size); - m_stream.PutHex64 (ap_int.getLimitedValue()); - return; - } - } - else if (byte_size == sizeof(double)) - { - if (sizeof(double) == 4) - { - m_stream.PutHex8(DW_OP_APPLE_constf); - m_stream.PutHex8 (byte_size); - m_stream.PutHex32 (ap_int.getLimitedValue()); - return; - } - else if (sizeof(double) == 8) - { - m_stream.PutHex8(DW_OP_APPLE_constf); - m_stream.PutHex8 (byte_size); - m_stream.PutHex64 (ap_int.getLimitedValue()); - return; - } - } - else if (byte_size == sizeof(long double)) - { - if (sizeof(long double) == 8) - { - m_stream.PutHex8(DW_OP_APPLE_constf); - m_stream.PutHex8 (byte_size); - m_stream.PutHex64 (ap_int.getLimitedValue()); - return; - } - } - // TODO: eventually support float constants of all sizes using - // APFloat as the class. - m_stream.PutHex8(DW_OP_APPLE_error); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitStringLiteral (clang::StringLiteral *Str) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); - - size_t byte_length = Str->getByteLength(); - bool is_wide = Str->isWide(); - - size_t new_length = byte_length + (is_wide ? 1 : 2); - - std::string null_terminated_string (Str->getStrData(), byte_length); - - Value *val = new Value((uint8_t*)null_terminated_string.c_str(), new_length); - val->SetContext(Value::eContextTypeOpaqueClangQualType, Str->getType().getAsOpaquePtr()); - - uint32_t val_idx = m_variable_list.AppendValue(val); - - m_stream.PutHex8(DW_OP_APPLE_expr_local); - m_stream.PutULEB128(val_idx); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitUnaryOperator (clang::UnaryOperator *unary_op) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); - - Visit(unary_op->getSubExpr()); - - switch (unary_op->getOpcode()) - { - case clang::UnaryOperator::PostInc: - // Duplciate the top of stack value (which must be something that can - // be assignable/incremented) and push its current value - m_stream.PutHex8 (DW_OP_dup); // x, x - m_stream.PutHex8 (DW_OP_APPLE_value_of); // x, val(x) - m_stream.PutHex8 (DW_OP_swap); // val(x), x - m_stream.PutHex8 (DW_OP_dup); // val(x), x, x - m_stream.PutHex8 (DW_OP_lit1); // val(x), x, x, 1 - m_stream.PutHex8 (DW_OP_plus); // val(x), x, val(x)+1 - m_stream.PutHex8 (DW_OP_APPLE_assign); // val(x), x - m_stream.PutHex8 (DW_OP_drop); // val(x) - break; - - case clang::UnaryOperator::PostDec: - // Duplciate the top of stack value (which must be something that can - // be assignable/incremented) and push its current value - m_stream.PutHex8 (DW_OP_dup); // x, x - m_stream.PutHex8 (DW_OP_APPLE_value_of); // x, val(x) - m_stream.PutHex8 (DW_OP_swap); // val(x), x - m_stream.PutHex8 (DW_OP_dup); // val(x), x, x - m_stream.PutHex8 (DW_OP_lit1); // val(x), x, x, 1 - m_stream.PutHex8 (DW_OP_minus); // val(x), x, val(x)-1 - m_stream.PutHex8 (DW_OP_APPLE_assign); // val(x), x - m_stream.PutHex8 (DW_OP_drop); // val(x) - break; - - case clang::UnaryOperator::PreInc: - m_stream.PutHex8 (DW_OP_dup); // x, x - m_stream.PutHex8 (DW_OP_APPLE_value_of); // x, val(x) - m_stream.PutHex8 (DW_OP_lit1); // x, val(x), 1 - m_stream.PutHex8 (DW_OP_plus); // x, val(x)+1 - m_stream.PutHex8 (DW_OP_APPLE_assign); // x with new value - break; - - case clang::UnaryOperator::PreDec: - m_stream.PutHex8 (DW_OP_dup); // x, x - m_stream.PutHex8 (DW_OP_APPLE_value_of); // x, val(x) - m_stream.PutHex8 (DW_OP_lit1); // x, val(x), 1 - m_stream.PutHex8 (DW_OP_minus); // x, val(x)-1 - m_stream.PutHex8 (DW_OP_APPLE_assign); // x with new value - break; - - case clang::UnaryOperator::AddrOf: - m_stream.PutHex8 (DW_OP_APPLE_address_of); - break; - - case clang::UnaryOperator::Deref: - m_stream.PutHex8 (DW_OP_APPLE_deref_type); - break; - - case clang::UnaryOperator::Plus: - m_stream.PutHex8 (DW_OP_abs); - break; - - case clang::UnaryOperator::Minus: - m_stream.PutHex8 (DW_OP_neg); - break; - - case clang::UnaryOperator::Not: - m_stream.PutHex8 (DW_OP_not); - break; - - case clang::UnaryOperator::LNot: - m_stream.PutHex8 (DW_OP_lit0); - m_stream.PutHex8 (DW_OP_eq); - break; - - case clang::UnaryOperator::Real: - m_stream.PutHex8(DW_OP_APPLE_error); - break; - - case clang::UnaryOperator::Imag: - m_stream.PutHex8(DW_OP_APPLE_error); - break; - - case clang::UnaryOperator::Extension: - m_stream.PutHex8(DW_OP_APPLE_error); - break; - - case clang::UnaryOperator::OffsetOf: - break; - - default: - assert(!"Unknown unary operator!"); - break; - } -} - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitCastExpr (clang::CastExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -// CastExpr::CastKind cast_kind = Node->getCastKind(); -// switch (cast_kind) -// { -// case CastExpr::CK_Unknown: -// case CastExpr::CK_BitCast: // Used for reinterpret_cast. -// case CastExpr::CK_NoOp: // Used for const_cast. -// case CastExpr::CK_BaseToDerived: // Base to derived class casts. -// case CastExpr::CK_DerivedToBase: // Derived to base class casts. -// case CastExpr::CK_Dynamic: // Dynamic cast. -// case CastExpr::CK_ToUnion: // Cast to union (GCC extension). -// case CastExpr::CK_ArrayToPointerDecay: // Array to pointer decay. -// case CastExpr::CK_FunctionToPointerDecay: // Function to pointer decay. -// case CastExpr::CK_NullToMemberPointer: // Null pointer to member pointer. -// case CastExpr::CK_BaseToDerivedMemberPointer: // Member pointer in base class to member pointer in derived class. -// case CastExpr::CK_DerivedToBaseMemberPointer: // Member pointer in derived class to member pointer in base class. -// case CastExpr::CK_UserDefinedConversion: // Conversion using a user defined type conversion function. -// case CastExpr::CK_ConstructorConversion: // Conversion by constructor -// case CastExpr::CK_IntegralToPointer: // Integral to pointer -// case CastExpr::CK_PointerToIntegral: // Pointer to integral -// case CastExpr::CK_ToVoid: // Cast to void -// case CastExpr::CK_VectorSplat: // Casting from an integer/floating type to an extended -// // vector type with the same element type as the src type. Splats the -// // src expression into the destination expression. -// case CastExpr::CK_IntegralCast: // Casting between integral types of different size. -// case CastExpr::CK_IntegralToFloating: // Integral to floating point. -// case CastExpr::CK_FloatingToIntegral: // Floating point to integral. -// case CastExpr::CK_FloatingCast: // Casting between floating types of different size. -// m_stream.PutHex8(DW_OP_APPLE_error); -// break; -// } - uint32_t cast_type_count = 0; - lldb_private::Scalar::Type cast_type_encoding = GetScalarTypeForClangType (m_ast_context, Node->getType(), cast_type_count); - - - Visit (Node->getSubExpr()); - - // Simple scalar cast - if (cast_type_encoding != lldb_private::Scalar::e_void && cast_type_count == 1) - { - // Only cast if our scalar types mismatch - uint32_t castee_type_count = 0; - lldb_private::Scalar::Type castee_type_encoding = GetScalarTypeForClangType (m_ast_context, Node->getSubExpr()->getType(), castee_type_count); - if (cast_type_encoding != castee_type_encoding && - castee_type_encoding != lldb_private::Scalar::e_void) - { - m_stream.PutHex8(DW_OP_APPLE_scalar_cast); - m_stream.PutHex8(cast_type_encoding); - } - } - else - { - // Handle more complex casts with clang types soon! - m_stream.PutHex8(DW_OP_APPLE_error); - } -} - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitArraySubscriptExpr (clang::ArraySubscriptExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); - Visit (Node->getBase()); - Visit (Node->getIdx()); - m_stream.PutHex8(DW_OP_APPLE_array_ref); -} - -// -//CLANG_STMT_RESULT -//lldb_private::ClangStmtVisitor::VisitImplicitCastExpr (clang::ImplicitCastExpr *Node) -//{ -// DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -// m_stream.PutHex8(DW_OP_APPLE_scalar_cast); -// Visit (Node->getSubExpr()); -//} - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitSizeOfAlignOfExpr (clang::SizeOfAlignOfExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitMemberExpr (clang::MemberExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); - clang::Expr *parent = Node->getBase(); - Visit (parent); - clang::QualType parent_clang_type = parent->getType(); - clang::NamedDecl *member_named_decl = cast(Node->getMemberDecl()->getCanonicalDecl()); - -// DeclarationName member_name = member->getDeclName(); - - clang::Type::TypeClass parent_type_class = parent_clang_type->getTypeClass(); - if (parent_type_class == clang::Type::Pointer) - { - clang::PointerType *pointer_type = cast(parent_clang_type.getTypePtr()); - parent_clang_type = pointer_type->getPointeeType(); - parent_type_class = parent_clang_type->getTypeClass(); - } - - switch (parent_type_class) - { - case clang::Type::Record: - { - const clang::RecordType *record_type = cast(parent_clang_type.getTypePtr()); - const clang::RecordDecl *record_decl = record_type->getDecl(); - assert(record_decl); - const clang::ASTRecordLayout &record_layout = m_ast_context.getASTRecordLayout(record_decl); - uint32_t field_idx = 0; - clang::RecordDecl::field_iterator field, field_end; - for (field = record_decl->field_begin(), field_end = record_decl->field_end(); field != field_end; ++field, ++field_idx) - { - clang::NamedDecl *field_named_decl = cast(field->getCanonicalDecl()); - if (field_named_decl == member_named_decl) - { - std::pair field_type_info = m_ast_context.getTypeInfo(field->getType()); - uint64_t field_bit_offset = record_layout.getFieldOffset (field_idx); - uint64_t field_byte_offset = field_bit_offset / 8; - uint32_t field_bitfield_bit_size = 0; - //uint32_t field_bitfield_bit_offset = field_bit_offset % 8; - - if (field->isBitField()) - { - clang::Expr* bit_width_expr = field->getBitWidth(); - if (bit_width_expr) - { - llvm::APSInt bit_width_apsint; - if (bit_width_expr->isIntegerConstantExpr(bit_width_apsint, m_ast_context)) - { - field_bitfield_bit_size = bit_width_apsint.getLimitedValue(UINT32_MAX); - } - } - } - - if (Node->isArrow()) - { - m_stream.PutHex8(DW_OP_deref); - } - else - { - m_stream.PutHex8(DW_OP_APPLE_address_of); - } - - if (field_byte_offset) - { - if (EncodeUInt64(field_byte_offset, 0)) - { - m_stream.PutHex8(DW_OP_plus); - } - } - m_stream.PutHex8(DW_OP_APPLE_clang_cast); - m_stream.PutPointer(field->getType().getAsOpaquePtr()); - break; - } - } - } - break; - - default: - assert(!"Unhandled MemberExpr"); - break; - } -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitExtVectorElementExpr (clang::ExtVectorElementExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitParenExpr(clang::ParenExpr *paren_expr) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); - Visit (paren_expr->getSubExpr()); -} - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitInitListExpr (clang::InitListExpr *init_list_expr) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitBinaryOperator (clang::BinaryOperator *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); - - Visit(Node->getLHS()); - Visit(Node->getRHS()); - - switch (Node->getOpcode()) - { - default: assert(0 && "Unknown binary operator!"); - case clang::BinaryOperator::PtrMemD: m_stream.PutHex8(DW_OP_APPLE_error); break; - case clang::BinaryOperator::PtrMemI: m_stream.PutHex8(DW_OP_APPLE_error); break; - case clang::BinaryOperator::Mul: m_stream.PutHex8(DW_OP_mul); break; - case clang::BinaryOperator::Div: m_stream.PutHex8(DW_OP_div); break; - case clang::BinaryOperator::Rem: m_stream.PutHex8(DW_OP_mod); break; - case clang::BinaryOperator::Add: m_stream.PutHex8(DW_OP_plus); break; - case clang::BinaryOperator::Sub: m_stream.PutHex8(DW_OP_minus); break; - case clang::BinaryOperator::Shl: m_stream.PutHex8(DW_OP_shl); break; - case clang::BinaryOperator::Shr: m_stream.PutHex8(DW_OP_shr); break; - case clang::BinaryOperator::LT: m_stream.PutHex8(DW_OP_lt); break; - case clang::BinaryOperator::GT: m_stream.PutHex8(DW_OP_gt); break; - case clang::BinaryOperator::LE: m_stream.PutHex8(DW_OP_le); break; - case clang::BinaryOperator::GE: m_stream.PutHex8(DW_OP_ge); break; - case clang::BinaryOperator::EQ: m_stream.PutHex8(DW_OP_eq); break; - case clang::BinaryOperator::NE: m_stream.PutHex8(DW_OP_ne); break; - case clang::BinaryOperator::And: m_stream.PutHex8(DW_OP_and); break; - case clang::BinaryOperator::Xor: m_stream.PutHex8(DW_OP_xor); break; - case clang::BinaryOperator::Or : m_stream.PutHex8(DW_OP_or); break; - case clang::BinaryOperator::LAnd: - // Do we need to call an operator here on objects? If so - // we will need a DW_OP_apple_logical_and - m_stream.PutHex8(DW_OP_lit0); - m_stream.PutHex8(DW_OP_ne); - m_stream.PutHex8(DW_OP_swap); - m_stream.PutHex8(DW_OP_lit0); - m_stream.PutHex8(DW_OP_ne); - m_stream.PutHex8(DW_OP_and); - break; - - case clang::BinaryOperator::LOr : - // Do we need to call an operator here on objects? If so - // we will need a DW_OP_apple_logical_or - m_stream.PutHex8(DW_OP_lit0); - m_stream.PutHex8(DW_OP_ne); - m_stream.PutHex8(DW_OP_swap); - m_stream.PutHex8(DW_OP_lit0); - m_stream.PutHex8(DW_OP_ne); - m_stream.PutHex8(DW_OP_or); - break; - - case clang::BinaryOperator::Assign: - m_stream.PutHex8(DW_OP_APPLE_assign); - break; - - case clang::BinaryOperator::MulAssign: - m_stream.PutHex8(DW_OP_over); - m_stream.PutHex8(DW_OP_swap); - m_stream.PutHex8(DW_OP_mul); - m_stream.PutHex8(DW_OP_APPLE_assign); - break; - - case clang::BinaryOperator::DivAssign: - m_stream.PutHex8(DW_OP_over); - m_stream.PutHex8(DW_OP_swap); - m_stream.PutHex8(DW_OP_div); - m_stream.PutHex8(DW_OP_APPLE_assign); - break; - - case clang::BinaryOperator::RemAssign: - m_stream.PutHex8(DW_OP_over); - m_stream.PutHex8(DW_OP_swap); - m_stream.PutHex8(DW_OP_mod); - m_stream.PutHex8(DW_OP_APPLE_assign); - break; - - case clang::BinaryOperator::AddAssign: - m_stream.PutHex8(DW_OP_over); - m_stream.PutHex8(DW_OP_swap); - m_stream.PutHex8(DW_OP_plus); - m_stream.PutHex8(DW_OP_APPLE_assign); - break; - - case clang::BinaryOperator::SubAssign: - m_stream.PutHex8(DW_OP_over); - m_stream.PutHex8(DW_OP_swap); - m_stream.PutHex8(DW_OP_minus); - m_stream.PutHex8(DW_OP_APPLE_assign); - break; - - case clang::BinaryOperator::ShlAssign: - m_stream.PutHex8(DW_OP_over); - m_stream.PutHex8(DW_OP_swap); - m_stream.PutHex8(DW_OP_shl); - m_stream.PutHex8(DW_OP_APPLE_assign); - break; - - case clang::BinaryOperator::ShrAssign: - m_stream.PutHex8(DW_OP_over); - m_stream.PutHex8(DW_OP_swap); - m_stream.PutHex8(DW_OP_shr); - m_stream.PutHex8(DW_OP_APPLE_assign); - break; - - case clang::BinaryOperator::AndAssign: - m_stream.PutHex8(DW_OP_over); - m_stream.PutHex8(DW_OP_swap); - m_stream.PutHex8(DW_OP_and); - m_stream.PutHex8(DW_OP_APPLE_assign); - break; - - case clang::BinaryOperator::OrAssign: - m_stream.PutHex8(DW_OP_over); - m_stream.PutHex8(DW_OP_swap); - m_stream.PutHex8(DW_OP_or); - m_stream.PutHex8(DW_OP_APPLE_assign); - break; - - case clang::BinaryOperator::XorAssign: - m_stream.PutHex8(DW_OP_over); - m_stream.PutHex8(DW_OP_swap); - m_stream.PutHex8(DW_OP_xor); - m_stream.PutHex8(DW_OP_APPLE_assign); - break; - - case clang::BinaryOperator::Comma: - // Nothing needs to be done here right? - break; - } -} - - -//CLANG_STMT_RESULT -//lldb_private::ClangStmtVisitor::VisitCompoundAssignOperator (CompoundAssignOperator *Node) -//{ -// DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -// -//} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitAddrLabelExpr (clang::AddrLabelExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitTypesCompatibleExpr (clang::TypesCompatibleExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - - - // C++ -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitCXXNamedCastExpr (clang::CXXNamedCastExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitCXXBoolLiteralExpr (clang::CXXBoolLiteralExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitCXXThisExpr (clang::CXXThisExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitCXXFunctionalCastExpr (clang::CXXFunctionalCastExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - - - // ObjC -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitObjCEncodeExpr (clang::ObjCEncodeExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitObjCMessageExpr (clang::ObjCMessageExpr* Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitObjCSelectorExpr (clang::ObjCSelectorExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitObjCProtocolExpr (clang::ObjCProtocolExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitObjCPropertyRefExpr (clang::ObjCPropertyRefExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitObjCImplicitSetterGetterRefExpr (clang::ObjCImplicitSetterGetterRefExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitObjCIvarRefExpr (clang::ObjCIvarRefExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - -CLANG_STMT_RESULT -lldb_private::ClangStmtVisitor::VisitObjCSuperExpr (clang::ObjCSuperExpr *Node) -{ - DEBUG_PRINTF("%s\n", __PRETTY_FUNCTION__); -} - - From scallanan at apple.com Thu Aug 12 18:45:39 2010 From: scallanan at apple.com (Sean Callanan) Date: Thu, 12 Aug 2010 23:45:39 -0000 Subject: [Lldb-commits] [lldb] r110980 - in /lldb/trunk: include/lldb/Expression/ClangASTSource.h source/Expression/ClangASTSource.cpp Message-ID: <20100812234539.2ECC82A6C12C@llvm.org> Author: spyffe Date: Thu Aug 12 18:45:38 2010 New Revision: 110980 URL: http://llvm.org/viewvc/llvm-project?rev=110980&view=rev Log: Added documentation to ClangASTSource and NameSearchContext. Modified: lldb/trunk/include/lldb/Expression/ClangASTSource.h lldb/trunk/source/Expression/ClangASTSource.cpp Modified: lldb/trunk/include/lldb/Expression/ClangASTSource.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangASTSource.h?rev=110980&r1=110979&r2=110980&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangASTSource.h (original) +++ lldb/trunk/include/lldb/Expression/ClangASTSource.h Thu Aug 12 18:45:38 2010 @@ -16,40 +16,130 @@ class ClangExpressionDeclMap; +//---------------------------------------------------------------------- +/// @class ClangASTSource ClangASTSource.h "lldb/Expression/ClangASTSource.h" +/// @brief Provider for named objects defined in the debug info for Clang +/// +/// As Clang parses an expression, it may encounter names that are not +/// defined inside the expression, including variables, functions, and +/// types. Clang knows the name it is looking for, but nothing else. +/// The ExternalSemaSource class provides Decls (VarDecl, FunDecl, TypeDecl) +/// to Clang for these names, consulting the ClangExpressionDeclMap to do +/// the actual lookups. +//---------------------------------------------------------------------- class ClangASTSource : public clang::ExternalSemaSource { - clang::ASTContext &Context; - ClangExpressionDeclMap &DeclMap; + clang::ASTContext &Context; ///< The parser's AST context, for copying types into + ClangExpressionDeclMap &DeclMap; ///< The object that looks up named entities in LLDB public: friend struct NameSearchContext; + //------------------------------------------------------------------ + /// Constructor + /// + /// Initializes class variabes. + /// + /// @param[in] context + /// A reference to the AST context provided by the parser. + /// + /// @param[in] declMap + /// A reference to the LLDB object that handles entity lookup. + //------------------------------------------------------------------ ClangASTSource(clang::ASTContext &context, ClangExpressionDeclMap &declMap) : Context(context), DeclMap(declMap) {} + + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ ~ClangASTSource(); + //------------------------------------------------------------------ + /// Interface stub that returns NULL. + //------------------------------------------------------------------ clang::Decl *GetExternalDecl(uint32_t); + + //------------------------------------------------------------------ + /// Interface stub that returns NULL. + //------------------------------------------------------------------ clang::Stmt *GetExternalDeclStmt(uint64_t); + //------------------------------------------------------------------ + /// Interface stub that returns an undifferentiated Selector. + //------------------------------------------------------------------ clang::Selector GetExternalSelector(uint32_t); + + //------------------------------------------------------------------ + /// Interface stub that returns 0. + //------------------------------------------------------------------ uint32_t GetNumExternalSelectors(); + //------------------------------------------------------------------ + /// Look up all Decls that match a particular name. Only handles + /// Identifiers. Passes the request on to DeclMap, and calls + /// SetExternalVisibleDeclsForName with the result. + /// + /// @param[in] DC + /// The DeclContext to register the found Decls in. + /// + /// @param[in] Name + /// The name to find entries for. + /// + /// @return + /// Whatever SetExternalVisibleDeclsForName returns. + //------------------------------------------------------------------ clang::DeclContext::lookup_result FindExternalVisibleDeclsByName(const clang::DeclContext *DC, clang::DeclarationName Name); + //------------------------------------------------------------------ + /// Interface stub that returns true. + //------------------------------------------------------------------ bool FindExternalLexicalDecls(const clang::DeclContext *DC, llvm::SmallVectorImpl &Decls); + //------------------------------------------------------------------ + /// Called on entering a translation unit. Tells Clang by calling + /// setHasExternalVisibleStorage() and setHasExternalLexicalStorage() + /// that this object has something to say about undefined names. + /// + /// @param[in] ASTConsumer + /// Unused. + //------------------------------------------------------------------ void StartTranslationUnit(clang::ASTConsumer *Consumer); }; - -// API for ClangExpressionDeclMap + +//---------------------------------------------------------------------- +/// @class NameSearchContext ClangASTSource.h "lldb/Expression/ClangASTSource.h" +/// @brief Container for all objects relevant to a single name lookup +/// +/// LLDB needs to create Decls for entities it finds. This class communicates +/// what name is being searched for and provides helper functions to construct +/// Decls given appropriate type information. +//---------------------------------------------------------------------- struct NameSearchContext { - ClangASTSource &ASTSource; - llvm::SmallVectorImpl &Decls; - clang::DeclarationName &Name; - const clang::DeclContext *DC; - + ClangASTSource &ASTSource; ///< The AST source making the request + llvm::SmallVectorImpl &Decls; ///< The list of declarations already constructed + clang::DeclarationName &Name; ///< The name being looked for + const clang::DeclContext *DC; ///< The DeclContext to put declarations into + + //------------------------------------------------------------------ + /// Constructor + /// + /// Initializes class variables. + /// + /// @param[in] astSource + /// A reference to the AST source making a request. + /// + /// @param[in] decls + /// A reference to a list into which new Decls will be placed. This + /// list is typically empty when the function is called. + /// + /// @param[in] name + /// The name being searched for (always an Identifier). + /// + /// @param[in] dc + /// The DeclContext to register Decls in. + //------------------------------------------------------------------ NameSearchContext (ClangASTSource &astSource, llvm::SmallVectorImpl &decls, clang::DeclarationName &name, @@ -59,10 +149,44 @@ Name(name), DC(dc) {} + //------------------------------------------------------------------ + /// Return the AST context for the current search. Useful when copying + /// types. + //------------------------------------------------------------------ clang::ASTContext *GetASTContext(); + + //------------------------------------------------------------------ + /// Create a VarDecl with the name being searched for and the provided + /// type and register it in the right places. + /// + /// @param[in] type + /// The opaque QualType for the VarDecl being registered. + //------------------------------------------------------------------ clang::NamedDecl *AddVarDecl(void *type); + + //------------------------------------------------------------------ + /// Create a FunDecl with the name being searched for and the provided + /// type and register it in the right places. + /// + /// @param[in] type + /// The opaque QualType for the FunDecl being registered. + //------------------------------------------------------------------ clang::NamedDecl *AddFunDecl(void *type); + + //------------------------------------------------------------------ + /// Create a FunDecl with the name being searched for and generic + /// type (i.e. intptr_t NAME_GOES_HERE(...)) and register it in the + /// right places. + //------------------------------------------------------------------ clang::NamedDecl *AddGenericFunDecl(); + + //------------------------------------------------------------------ + /// Create a TypeDecl with the name being searched for and the provided + /// type and register it in the right places. + /// + /// @param[in] type + /// The opaque QualType for the TypeDecl being registered. + //------------------------------------------------------------------ clang::NamedDecl *AddTypeDecl(void *type); }; Modified: lldb/trunk/source/Expression/ClangASTSource.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangASTSource.cpp?rev=110980&r1=110979&r2=110980&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangASTSource.cpp (original) +++ lldb/trunk/source/Expression/ClangASTSource.cpp Thu Aug 12 18:45:38 2010 @@ -111,6 +111,10 @@ false, true); + // We have to do more than just synthesize the FunctionDecl. We have to + // synthesize ParmVarDecls for all of the FunctionDecl's arguments. To do + // this, we raid the function's FunctionProtoType for types. + QualType QT = QualType::getFromOpaquePtr(type); clang::Type *T = QT.getTypePtr(); const FunctionProtoType *FPT = T->getAs(); From scallanan at apple.com Thu Aug 12 19:28:39 2010 From: scallanan at apple.com (Sean Callanan) Date: Fri, 13 Aug 2010 00:28:39 -0000 Subject: [Lldb-commits] [lldb] r110990 - in /lldb/trunk: include/lldb/Expression/ClangExpression.h source/Commands/CommandObjectExpression.cpp source/Expression/ClangExpression.cpp source/Expression/ClangFunction.cpp Message-ID: <20100813002839.733F92A6C12C@llvm.org> Author: spyffe Date: Thu Aug 12 19:28:39 2010 New Revision: 110990 URL: http://llvm.org/viewvc/llvm-project?rev=110990&view=rev Log: Documented ClangExpression and made parts of it more sane (i.e., removed dead arguments, made sensible defaults, etc.) Modified: lldb/trunk/include/lldb/Expression/ClangExpression.h lldb/trunk/source/Commands/CommandObjectExpression.cpp lldb/trunk/source/Expression/ClangExpression.cpp lldb/trunk/source/Expression/ClangFunction.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpression.h?rev=110990&r1=110989&r2=110990&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpression.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpression.h Thu Aug 12 19:28:39 2010 @@ -35,94 +35,252 @@ class RecordingMemoryManager; +//---------------------------------------------------------------------- +/// @class ClangExpression ClangExpression.h "lldb/Expression/ClangExpression.h" +/// @brief Encapsulates a single expression for use with Clang +/// +/// LLDB uses expressions for various purposes, notably to call functions +/// and as a backend for the expr command. ClangExpression encapsulates +/// the objects needed to parse and interpret or JIT an expression. It +/// uses the Clang parser to produce LLVM IR from the expression. +//---------------------------------------------------------------------- class ClangExpression { public: - //------------------------------------------------------------------ - // Constructors and Destructors + /// Constructor + /// + /// Initializes class variabes. + /// + /// @param[in] target_triple + /// The LLVM-friendly target triple for use in initializing the + /// compiler. + /// + /// @param[in] expr_decl_map + /// The object that looks up externally-defined names in LLDB's + /// debug information. //------------------------------------------------------------------ ClangExpression(const char *target_triple, ClangExpressionDeclMap *expr_decl_map); + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ ~ClangExpression(); - - unsigned Compile(); - + + //------------------------------------------------------------------ + /// Parse a single expression and convert it to IR using Clang. Wrap + /// the expression in a function with signature void ___clang_expr(void*). + /// + /// @param[in] expr_text + /// The text of the expression to be parsed. + /// + /// @param[in] stream + /// The stream to print errors to. + /// + /// @param[in] add_result_var + /// True if a special result variable should be generated for + /// the expression. + /// + /// @return + /// The number of errors encountered during parsing. 0 means + /// success. + //------------------------------------------------------------------ unsigned ParseExpression (const char *expr_text, Stream &stream, bool add_result_var = false); + //------------------------------------------------------------------ + /// Parse a single expression and convert it to IR using Clang. Don't + /// wrap the expression in anything at all. + /// + /// @param[in] expr_text + /// The text of the expression to be parsed. + /// + /// @param[in] stream + /// The stream to print errors to. + /// + /// @param[in] add_result_var + /// True if a special result variable should be generated for + /// the expression. + /// + /// @return + /// The number of errors encountered during parsing. 0 means + /// success. + //------------------------------------------------------------------ unsigned ParseBareExpression (llvm::StringRef expr_text, Stream &stream, bool add_result_var = false); + //------------------------------------------------------------------ + /// Convert the IR for an already-parsed expression to DWARF if possible. + /// + /// @param[in] expr_local_variable_list + /// The list of local variables the expression uses, with types, for + /// use by the DWARF parser. + /// + /// @param[in] dwarf_opcode_strm + /// The stream to place the resulting DWARF code into. + /// + /// @return + /// True on success; false on failure. On failure, it may be appropriate + /// to call PrepareIRForTarget(). + //------------------------------------------------------------------ bool ConvertIRToDWARF (ClangExpressionVariableList &excpr_local_variable_list, StreamString &dwarf_opcode_strm); + //------------------------------------------------------------------ + /// Prepare the IR for an already-parsed expression for execution in the + /// target process by (among other things) making all externally-defined + /// variables point to offsets from the void* argument. + /// + /// @return + /// True on success; false on failure. On failure, this expression + /// cannot be executed by LLDB. + //------------------------------------------------------------------ bool - PrepareIRForTarget (ClangExpressionVariableList &excpr_local_variable_list); + PrepareIRForTarget (); + //------------------------------------------------------------------ + /// Use the JIT to compile an already-prepared expression from IR into + /// machine code, but keep the code in the current process for now. + /// + /// @param[in] func_name + /// The name of the function to be JITted. By default, the function + /// wrapped by ParseExpression(). + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ bool - JITFunction (const ExecutionContext &exc_context, const char *func_name); + JITFunction (const char *func_name = "___clang_expr"); + //------------------------------------------------------------------ + /// Write the machine code generated by the JIT into the target's memory. + /// + /// @param[in] exc_context + /// The execution context that the JITted code must be copied into. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ bool WriteJITCode (const ExecutionContext &exc_context); + //------------------------------------------------------------------ + /// Write the machine code generated by the JIT into the target process. + /// + /// @param[in] func_name + /// The name of the function whose address is being requested. + /// By default, the function wrapped by ParseExpression(). + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ lldb::addr_t - GetFunctionAddress (const char *name); + GetFunctionAddress (const char *func_name = "___clang_expr"); + //------------------------------------------------------------------ + /// Disassemble the machine code for a JITted function from the target + /// process's memory and print the result to a stream. + /// + /// @param[in] stream + /// The stream to print disassembly to. + /// + /// @param[in] exc_context + /// The execution context to get the machine code from. + /// + /// @param[in] func_name + /// The name of the function to be disassembled. By default, the + /// function wrapped by ParseExpression(). + /// + /// @return + /// The error generated. If .Success() is true, disassembly succeeded. + //------------------------------------------------------------------ Error - DisassembleFunction (Stream &stream, ExecutionContext &exc_context, const char *name); + DisassembleFunction (Stream &stream, ExecutionContext &exc_context, const char *func_name = "___clang_expr"); + //------------------------------------------------------------------ + /// Return the Clang compiler instance being used by this expression. + //------------------------------------------------------------------ clang::CompilerInstance * GetCompilerInstance () { return m_clang_ap.get(); } + //------------------------------------------------------------------ + /// Return the AST context being used by this expression. + //------------------------------------------------------------------ clang::ASTContext * GetASTContext (); + //------------------------------------------------------------------ + /// Return the mutex being used to serialize access to Clang. + //------------------------------------------------------------------ static Mutex & GetClangMutex (); protected: - - // This class is a pass-through for the default JIT memory manager, - // which just records the memory regions that were handed out so we - // can copy them into the target later on. - - //------------------------------------------------------------------ // Classes that inherit from ClangExpression can see and modify these //------------------------------------------------------------------ + //---------------------------------------------------------------------- + /// @class JittedFunction ClangExpression.h "lldb/Expression/ClangExpression.h" + /// @brief Encapsulates a single function that has been generated by the JIT. + /// + /// Functions that have been generated by the JIT are first resident in the + /// local process, and then placed in the target process. JittedFunction + /// represents a function possibly resident in both. + //---------------------------------------------------------------------- struct JittedFunction { - std::string m_name; - lldb::addr_t m_local_addr; - lldb::addr_t m_remote_addr; - + std::string m_name; ///< The function's name + lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory + lldb::addr_t m_remote_addr; ///< The address of the function in the target's memory + + //------------------------------------------------------------------ + /// Constructor + /// + /// Initializes class variabes. + /// + /// @param[in] name + /// The name of the function. + /// + /// @param[in] local_addr + /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if + /// it is not present in LLDB's memory. + /// + /// @param[in] remote_addr + /// The address of the function in the target, or LLDB_INVALID_ADDRESS + /// if it is not present in the target's memory. + //------------------------------------------------------------------ JittedFunction (const char *name, - lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, - lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) : + lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, + lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) : m_name (name), m_local_addr (local_addr), m_remote_addr (remote_addr) {} }; - std::string m_target_triple; - ClangExpressionDeclMap *m_decl_map; - std::auto_ptr m_clang_ap; - clang::CodeGenerator *m_code_generator_ptr; // This will be deleted by the Execution Engine. - RecordingMemoryManager *m_jit_mm_ptr; // This will be deleted by the Execution Engine. - std::auto_ptr m_execution_engine; - std::vector m_jitted_functions; + std::string m_target_triple; ///< The target triple used to initialize LLVM + ClangExpressionDeclMap *m_decl_map; ///< The class used to look up entities defined in the debug info + std::auto_ptr m_clang_ap; ///< The Clang compiler used to parse expressions into IR + clang::CodeGenerator *m_code_generator_ptr; ///< [owned by the Execution Engine] The Clang object that generates IR + RecordingMemoryManager *m_jit_mm_ptr; ///< [owned by the Execution Engine] The memory manager that allocates code pages on the JIT's behalf + std::auto_ptr m_execution_engine; ///< The LLVM JIT + std::vector m_jitted_functions; ///< A vector of all functions that have been JITted into machine code (just one, if ParseExpression() was called) private: - - bool CreateCompilerInstance(bool &IsAST); + //------------------------------------------------------------------ + /// Initialize m_clang_ap to a compiler instance with all the options + /// required by the expression parser. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ + bool CreateCompilerInstance(); //------------------------------------------------------------------ // For ClangExpression only Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=110990&r1=110989&r2=110990&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Thu Aug 12 19:28:39 2010 @@ -267,7 +267,7 @@ { if (log) log->Printf("Code cannot be interpreted and must be run in the target."); - success = clang_expr.PrepareIRForTarget (expr_local_vars); + success = clang_expr.PrepareIRForTarget (); } if (!success) @@ -283,7 +283,7 @@ } else { - if (!clang_expr.JITFunction (m_exe_ctx, "___clang_expr")) + if (!clang_expr.JITFunction ()) { error_stream.PutCString ("error: IR could not be JIT compiled\n"); return false; @@ -295,7 +295,7 @@ return false; } - lldb::addr_t function_address(clang_expr.GetFunctionAddress ("___clang_expr")); + lldb::addr_t function_address(clang_expr.GetFunctionAddress ()); if (function_address == LLDB_INVALID_ADDRESS) { @@ -318,7 +318,7 @@ StreamString insns; - Error err = clang_expr.DisassembleFunction(insns, m_exe_ctx, "___clang_expr"); + Error err = clang_expr.DisassembleFunction(insns, m_exe_ctx); if (!err.Success()) { Modified: lldb/trunk/source/Expression/ClangExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpression.cpp?rev=110990&r1=110989&r2=110990&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpression.cpp (original) +++ lldb/trunk/source/Expression/ClangExpression.cpp Thu Aug 12 19:28:39 2010 @@ -217,7 +217,7 @@ } bool -ClangExpression::CreateCompilerInstance (bool &IsAST) +ClangExpression::CreateCompilerInstance () { // Initialize targets first, so that --version shows registered targets. static struct InitializeLLVM { @@ -313,8 +313,7 @@ TextDiagnosticBuffer text_diagnostic_buffer; - bool IsAST = false; - if (!CreateCompilerInstance (IsAST)) + if (!CreateCompilerInstance ()) { stream.Printf("error: couldn't create compiler instance\n"); return 1; @@ -462,7 +461,7 @@ } bool -ClangExpression::PrepareIRForTarget (ClangExpressionVariableList &expr_local_variable_list) +ClangExpression::PrepareIRForTarget () { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); @@ -498,7 +497,7 @@ } bool -ClangExpression::JITFunction (const ExecutionContext &exc_context, const char *name) +ClangExpression::JITFunction (const char *name) { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); @@ -747,89 +746,3 @@ return ret; } - -unsigned -ClangExpression::Compile() -{ - Mutex::Locker locker(GetClangMutex ()); - bool IsAST = false; - - if (CreateCompilerInstance(IsAST)) - { - // Validate/process some options - if (m_clang_ap->getHeaderSearchOpts().Verbose) - llvm::errs() << "clang-cc version " CLANG_VERSION_STRING - << " based upon " << PACKAGE_STRING - << " hosted on " << llvm::sys::getHostTriple() << "\n"; - - // Enforce certain implications. - if (!m_clang_ap->getFrontendOpts().ViewClassInheritance.empty()) - m_clang_ap->getFrontendOpts().ProgramAction = frontend::InheritanceView; -// if (!compiler_instance->getFrontendOpts().FixItSuffix.empty()) -// compiler_instance->getFrontendOpts().ProgramAction = frontend::FixIt; - - for (unsigned i = 0, e = m_clang_ap->getFrontendOpts().Inputs.size(); i != e; ++i) { - - // If we aren't using an AST file, setup the file and source managers and - // the preprocessor. - if (!IsAST) { - if (!i) { - // Create a file manager object to provide access to and cache the - // filesystem. - m_clang_ap->createFileManager(); - - // Create the source manager. - m_clang_ap->createSourceManager(); - } else { - // Reset the ID tables if we are reusing the SourceManager. - m_clang_ap->getSourceManager().clearIDTables(); - } - - // Create the preprocessor. - m_clang_ap->createPreprocessor(); - } - - llvm::OwningPtr Act(CreateFrontendAction(*m_clang_ap.get())); - if (!Act) - break; - - if (Act->BeginSourceFile(*m_clang_ap, - m_clang_ap->getFrontendOpts().Inputs[i].second, - m_clang_ap->getFrontendOpts().Inputs[i].first)) { - Act->Execute(); - Act->EndSourceFile(); - } - } - - if (m_clang_ap->getDiagnosticOpts().ShowCarets) - { - unsigned NumWarnings = m_clang_ap->getDiagnostics().getNumWarnings(); - unsigned NumErrors = m_clang_ap->getDiagnostics().getNumErrors() - - m_clang_ap->getDiagnostics().getNumErrorsSuppressed(); - - if (NumWarnings || NumErrors) - { - if (NumWarnings) - fprintf (stderr, "%u warning%s%s", NumWarnings, (NumWarnings == 1 ? "" : "s"), (NumErrors ? " and " : "")); - if (NumErrors) - fprintf (stderr, "%u error%s", NumErrors, (NumErrors == 1 ? "" : "s")); - fprintf (stderr, " generated.\n"); - } - } - - if (m_clang_ap->getFrontendOpts().ShowStats) { - m_clang_ap->getFileManager().PrintStats(); - fprintf(stderr, "\n"); - } - - // Return the appropriate status when verifying diagnostics. - // - // FIXME: If we could make getNumErrors() do the right thing, we wouldn't need - // this. - if (m_clang_ap->getDiagnosticOpts().VerifyDiagnostics) - return static_cast(m_clang_ap->getDiagnosticClient()).HadErrors(); - - return m_clang_ap->getDiagnostics().getNumErrors(); - } - return 1; -} Modified: lldb/trunk/source/Expression/ClangFunction.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangFunction.cpp?rev=110990&r1=110989&r2=110990&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangFunction.cpp (original) +++ lldb/trunk/source/Expression/ClangFunction.cpp Thu Aug 12 19:28:39 2010 @@ -258,7 +258,7 @@ if (!m_JITted) { // Next we should JIT it and insert the result into the target program. - if (!JITFunction (exe_ctx, m_wrapper_function_name.c_str())) + if (!JITFunction (m_wrapper_function_name.c_str())) return false; if (!WriteJITCode (exe_ctx)) From johnny.chen at apple.com Thu Aug 12 19:42:30 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 13 Aug 2010 00:42:30 -0000 Subject: [Lldb-commits] [lldb] r110992 - in /lldb/trunk/source/Commands: CommandObjectExpression.cpp CommandObjectExpression.h Message-ID: <20100813004230.4CE7E2A6C12C@llvm.org> Author: johnny Date: Thu Aug 12 19:42:30 2010 New Revision: 110992 URL: http://llvm.org/viewvc/llvm-project?rev=110992&view=rev Log: Modified CommandObjectExpression::EvaluateExpression() so that it takes an additional (ComandReturnObject *) result parameter (default to NULL) and does the right thing in setting the result status. Also removed used variable ast_context. Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp lldb/trunk/source/Commands/CommandObjectExpression.h Modified: lldb/trunk/source/Commands/CommandObjectExpression.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.cpp?rev=110992&r1=110991&r2=110992&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.cpp (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.cpp Thu Aug 12 19:42:30 2010 @@ -189,10 +189,11 @@ } bool -CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream &output_stream, Stream &error_stream) +CommandObjectExpression::EvaluateExpression (const char *expr, bool bare, Stream &output_stream, Stream &error_stream, + CommandReturnObject *result) { Log *log = lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS); - + //////////////////////////////////// // Set up the target and compiler // @@ -251,7 +252,6 @@ bool success; bool canInterpret = false; - clang::ASTContext *ast_context = clang_expr.GetASTContext (); ClangPersistentVariable *expr_result = 0; Error expr_error; @@ -382,21 +382,27 @@ { StreamString ss; - Error err = expr_result->Print (ss, - m_exe_ctx, - m_options.format, - m_options.show_types, - m_options.show_summary, - m_options.debug); + Error rc = expr_result->Print (ss, + m_exe_ctx, + m_options.format, + m_options.show_types, + m_options.show_summary, + m_options.debug); - if (err.Success()) - output_stream.PutCString(ss.GetString().c_str()); - else - error_stream.Printf ("Couldn't print result : %s\n", err.AsCString("unknown error")); + if (rc.Fail()) { + error_stream.Printf ("Couldn't print result : %s\n", rc.AsCString()); + return false; + } + + output_stream.PutCString(ss.GetString().c_str()); + if (result) + result->SetStatus (eReturnStatusSuccessFinishResult); } else { error_stream.Printf ("Expression produced no result\n"); + if (result) + result->SetStatus (eReturnStatusSuccessFinishNoResult); } return true; @@ -482,7 +488,11 @@ if (expr == NULL) expr = command; - return EvaluateExpression (expr, false, result.GetOutputStream(), result.GetErrorStream()); + if (EvaluateExpression (expr, false, result.GetOutputStream(), result.GetErrorStream(), &result)) + return true; + + result.SetStatus (eReturnStatusFailed); + return false; } lldb::OptionDefinition Modified: lldb/trunk/source/Commands/CommandObjectExpression.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Commands/CommandObjectExpression.h?rev=110992&r1=110991&r2=110992&view=diff ============================================================================== --- lldb/trunk/source/Commands/CommandObjectExpression.h (original) +++ lldb/trunk/source/Commands/CommandObjectExpression.h Thu Aug 12 19:42:30 2010 @@ -87,10 +87,11 @@ size_t bytes_len); bool - EvaluateExpression (const char *expr, + EvaluateExpression (const char *expr, bool bare, - Stream &output_stream, - Stream &error_stream); + Stream &output_stream, + Stream &error_stream, + CommandReturnObject *result = NULL); CommandOptions m_options; ExecutionContext m_exe_ctx; From johnny.chen at apple.com Fri Aug 13 15:12:05 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 13 Aug 2010 20:12:05 -0000 Subject: [Lldb-commits] [lldb] r111035 - in /lldb/trunk/test/persistent_variables: ./ TestPersistentVariables.py Message-ID: <20100813201205.4E49A2A6C12C@llvm.org> Author: johnny Date: Fri Aug 13 15:12:05 2010 New Revision: 111035 URL: http://llvm.org/viewvc/llvm-project?rev=111035&view=rev Log: Added a test case to exercise persistent variables in combination with the "expr" command. Added: lldb/trunk/test/persistent_variables/ lldb/trunk/test/persistent_variables/TestPersistentVariables.py Added: lldb/trunk/test/persistent_variables/TestPersistentVariables.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/persistent_variables/TestPersistentVariables.py?rev=111035&view=auto ============================================================================== --- lldb/trunk/test/persistent_variables/TestPersistentVariables.py (added) +++ lldb/trunk/test/persistent_variables/TestPersistentVariables.py Fri Aug 13 15:12:05 2010 @@ -0,0 +1,57 @@ +""" +Test that lldb persistent variables works correctly. +""" + +import os, time +import unittest2 +import lldb +from lldbtest import * + +class TestPersistentVariables(TestBase): + + mydir = "persistent_variables" + + def test_persistent_variables(self): + """Test that lldb persistent variables works correctly.""" + res = self.res + + self.ci.HandleCommand("file ../array_types/a.out", res) + self.assertTrue(res.Succeeded(), CURRENT_EXECUTABLE_SET) + + self.ci.HandleCommand("breakpoint set --name main", res) + self.assertTrue(res.Succeeded()) + + self.ci.HandleCommand("run", res) + self.assertTrue(res.Succeeded(), RUN_STOPPED) + + self.ci.HandleCommand("expr int $i = 5; $i + 1", res) + self.assertTrue(res.Succeeded(), CMD_MSG('expr int $i = 5; $i + 1')) + #print res.GetOutput() + # $0 = (int)6 + + self.ci.HandleCommand("expr $i + 3", res) + self.assertTrue(res.Succeeded(), CMD_MSG('expr $i + 3')) + #print res.GetOutput() + # $1 = (int)8 + + self.ci.HandleCommand("expr $1 + $0", res) + self.assertTrue(res.Succeeded(), CMD_MSG('expr $1 + $0')) + #print res.GetOutput() + # $2 = (int)14 + + self.ci.HandleCommand("expr $2", res) + self.assertTrue(res.Succeeded() and + res.GetOutput().startswith("$3 = (int) 14"), + CMD_MSG('expr $2')) + #print res.GetOutput() + # $3 = (int)14 + + self.ci.HandleCommand("continue", res) + self.ci.HandleCommand("quit", res) + + +if __name__ == '__main__': + import atexit + lldb.SBDebugger.Initialize() + atexit.register(lambda: lldb.SBDebugger.Terminate()) + unittest2.main() From scallanan at apple.com Fri Aug 13 17:29:55 2010 From: scallanan at apple.com (Sean Callanan) Date: Fri, 13 Aug 2010 22:29:55 -0000 Subject: [Lldb-commits] [lldb] r111049 - in /lldb/trunk: include/lldb/Expression/ClangExpressionDeclMap.h source/Expression/ClangExpressionDeclMap.cpp source/Expression/IRForTarget.cpp Message-ID: <20100813222955.2D3A92A6C12C@llvm.org> Author: spyffe Date: Fri Aug 13 17:29:54 2010 New Revision: 111049 URL: http://llvm.org/viewvc/llvm-project?rev=111049&view=rev Log: Added documentation to ClangExpressionDeclMap. Also cleaned up its API a tiny bit (but not the extensive amount that is actually needed. That's still coming.) Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp lldb/trunk/source/Expression/IRForTarget.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h?rev=111049&r1=111048&r2=111049&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionDeclMap.h Fri Aug 13 17:29:54 2010 @@ -36,80 +36,339 @@ class Function; class NameSearchContext; class Variable; - + +//---------------------------------------------------------------------- +/// @class ClangExpressionDeclMap ClangExpressionDeclMap.h "lldb/Expression/ClangExpressionDeclMap.h" +/// @brief Manages named entities that are defined in LLDB's debug information. +/// +/// The Clang parser uses the ClangASTSource as an interface to request named +/// entities from outside an expression. The ClangASTSource reports back, listing +/// all possible objects corresponding to a particular name. But it in turn +/// relies on ClangExpressionDeclMap, which performs several important functions. +/// +/// First, it records what variables and functions were looked up and what Decls +/// were returned for them. +/// +/// Second, it constructs a struct on behalf of IRForTarget, recording which +/// variables should be placed where and relaying this information back so that +/// IRForTarget can generate context-independent code. +/// +/// Third, it "materializes" this struct on behalf of the expression command, +/// finding the current values of each variable and placing them into the +/// struct so that it can be passed to the JITted version of the IR. +/// +/// Fourth and finally, it "dematerializes" the struct after the JITted code has +/// has executed, placing the new values back where it found the old ones. +//---------------------------------------------------------------------- class ClangExpressionDeclMap { public: + //------------------------------------------------------------------ + /// Constructor + /// + /// Initializes class variabes. + /// + /// @param[in] exe_ctx + /// The execution context to use when finding types for variables. + /// Also used to find a "scratch" AST context to store result types. + //------------------------------------------------------------------ ClangExpressionDeclMap(ExecutionContext *exe_ctx); - ~ClangExpressionDeclMap(); - // Interface for ClangStmtVisitor - bool GetIndexForDecl (uint32_t &index, - const clang::Decl *decl); + //------------------------------------------------------------------ + /// Destructor + //------------------------------------------------------------------ + ~ClangExpressionDeclMap(); - // Interface for IRForTarget + //------------------------------------------------------------------ + /// [Used by IRForTarget] Get a new result variable name of the form + /// $n, where n is a natural number starting with 0. + /// + /// @param[in] name + /// The std::string to place the name into. + //------------------------------------------------------------------ void GetPersistentResultName (std::string &name); + + //------------------------------------------------------------------ + /// [Used by IRForTarget] Add a variable to the list of persistent + /// variables for the process. + /// + /// @param[in] name + /// The name of the persistent variable, usually $something. + /// + /// @param[in] type + /// The type of the variable, in the Clang parser's context. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ bool AddPersistentVariable (const char *name, TypeFromParser type); + + //------------------------------------------------------------------ + /// [Used by IRForTarget] Add a variable to the struct that needs to + /// be materialized each time the expression runs. + /// + /// @param[in] value + /// The LLVM IR value for this variable. + /// + /// @param[in] decl + /// The Clang declaration for the variable. + /// + /// @param[in] name + /// The name of the variable. + /// + /// @param[in] type + /// The type of the variable. + /// + /// @param[in] size + /// The size of the variable in bytes. + /// + /// @param[in] alignment + /// The required alignment of the variable in bytes. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ bool AddValueToStruct (llvm::Value *value, const clang::NamedDecl *decl, std::string &name, - void *type, - clang::ASTContext *ast_context, + TypeFromParser type, size_t size, off_t alignment); + + //------------------------------------------------------------------ + /// [Used by IRForTarget] Finalize the struct, laying out the position + /// of each object in it. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ bool DoStructLayout (); + + //------------------------------------------------------------------ + /// [Used by IRForTarget] Get general information about the laid-out + /// struct after DoStructLayout() has been called. + /// + /// @param[out] num_elements + /// The number of elements in the struct. + /// + /// @param[out] size + /// The size of the struct, in bytes. + /// + /// @param[out] alignment + /// The alignment of the struct, in bytes. + /// + /// @return + /// True if the information could be retrieved; false otherwise. + //------------------------------------------------------------------ bool GetStructInfo (uint32_t &num_elements, size_t &size, off_t &alignment); + + //------------------------------------------------------------------ + /// [Used by IRForTarget] Get specific information about one field + /// of the laid-out struct after DoStructLayout() has been called. + /// + /// @param[out] decl + /// The parsed Decl for the field, as generated by ClangASTSource + /// on ClangExpressionDeclMap's behalf. In the case of the result + /// value, this will have the name ___clang_result even if the + /// result value ends up having the name $1. This is an + /// implementation detail of IRForTarget. + /// + /// @param[out] value + /// The IR value for the field (usually a GlobalVariable). In + /// the case of the result value, this will have the correct + /// name ($1, for instance). This is an implementation detail + /// of IRForTarget. + /// + /// @param[out] offset + /// The offset of the field from the beginning of the struct. + /// As long as the struct is aligned according to its required + /// alignment, this offset will align the field correctly. + /// + /// @param[in] index + /// The index of the field about which information is requested. + /// + /// @return + /// True if the information could be retrieved; false otherwise. + //------------------------------------------------------------------ bool GetStructElement (const clang::NamedDecl *&decl, llvm::Value *&value, off_t &offset, uint32_t index); + //------------------------------------------------------------------ + /// [Used by IRForTarget] Get information about a function given its + /// Decl. + /// + /// @param[in] decl + /// The parsed Decl for the Function, as generated by ClangASTSource + /// on ClangExpressionDeclMap's behalf. + /// + /// @param[out] value + /// A pointer to the address where a Value for the function's address + /// can be stored. IRForTarget typically places a ConstantExpr here. + /// + /// @param[out] ptr + /// The absolute address of the function in the target. + /// + /// @return + /// True if the information could be retrieved; false otherwise. + //------------------------------------------------------------------ bool GetFunctionInfo (const clang::NamedDecl *decl, llvm::Value**& value, uint64_t &ptr); + + //------------------------------------------------------------------ + /// [Used by IRForTarget] Get the address of a function given nothing + /// but its name. Some functions are needed but didn't get Decls made + /// during parsing -- specifically, sel_registerName is never called + /// in the generated IR but we need to call it nonetheless. + /// + /// @param[in] name + /// The name of the function. + /// + /// @param[out] ptr + /// The absolute address of the function in the target. + /// + /// @return + /// True if the address could be retrieved; false otherwise. + //------------------------------------------------------------------ bool GetFunctionAddress (const char *name, uint64_t &ptr); - // Interface for DwarfExpression + //------------------------------------------------------------------ + /// [Used by DWARFExpression] Get the LLDB value for a variable given + /// its unique index into the value map. + /// + /// @param[in] index + /// The index of the variable into the tuple array, which keeps track + /// of Decls, types, and Values. + /// + /// @return + /// The LLDB value for the variable. + //------------------------------------------------------------------ Value *GetValueForIndex (uint32_t index); - // Interface for CommandObjectExpression + //------------------------------------------------------------------ + /// [Used by CommandObjectExpression] Materialize the entire struct + /// at a given address, which should be aligned as specified by + /// GetStructInfo(). + /// + /// @param[in] exe_ctx + /// The execution context at which to dump the struct. + /// + /// @param[in] struct_address + /// The address at which the struct should be written. + /// + /// @param[in] error + /// An Error to populate with any messages related to + /// materializing the struct. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ bool Materialize(ExecutionContext *exe_ctx, lldb::addr_t &struct_address, Error &error); + //------------------------------------------------------------------ + /// [Used by CommandObjectExpression] Pretty-print a materialized + /// struct, which must have been materialized by Materialize(), + /// byte for byte on a given stream. + /// + /// @param[in] exe_ctx + /// The execution context from which to read the struct. + /// + /// @param[in] s + /// The stream on which to write the pretty-printed output. + /// + /// @param[in] error + /// An Error to populate with any messages related to + /// pretty-printing the struct. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ bool DumpMaterializedStruct(ExecutionContext *exe_ctx, Stream &s, Error &error); + //------------------------------------------------------------------ + /// [Used by CommandObjectExpression] Deaterialize the entire struct. + /// + /// @param[in] exe_ctx + /// The execution context from which to read the struct. + /// + /// @param[out] result + /// A ClangPersistentVariable containing the result of the + /// expression, for potential re-use. + /// + /// @param[in] error + /// An Error to populate with any messages related to + /// dematerializing the struct. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ bool Dematerialize(ExecutionContext *exe_ctx, ClangPersistentVariable *&result, Error &error); - // Interface for ClangASTSource + //------------------------------------------------------------------ + /// [Used by ClangASTSource] Find all entities matching a given name, + /// using a NameSearchContext to make Decls for them. + /// + /// @param[in] context + /// The NameSearchContext that can construct Decls for this name. + /// + /// @param[in] name + /// The name as a plain C string. The NameSearchContext contains + /// a DeclarationName for the name so at first the name may seem + /// redundant, but ClangExpressionDeclMap operates in RTTI land so + /// it can't access DeclarationName. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ void GetDecls (NameSearchContext &context, const char *name); -private: +private: + //---------------------------------------------------------------------- + /// @class Tuple ClangExpressionDeclMap.h "lldb/Expression/ClangExpressionDeclMap.h" + /// @brief A single entity that has been looked up on the behalf of the parser. + /// + /// When the Clang parser requests entities by name, ClangExpressionDeclMap + /// records what was looked up in a list of Tuples. + //---------------------------------------------------------------------- struct Tuple { - const clang::NamedDecl *m_decl; - TypeFromParser m_parser_type; - TypeFromUser m_user_type; - lldb_private::Value *m_value; /* owned by ClangExpressionDeclMap */ - llvm::Value *m_llvm_value; + const clang::NamedDecl *m_decl; ///< The Decl generated for the entity. + TypeFromParser m_parser_type; ///< The type of the entity, as reported to the parser. + TypeFromUser m_user_type; ///< The type of the entity, as found in LLDB. + lldb_private::Value *m_value; ///< [owned by ClangExpressionDeclMap] A LLDB Value for the entity. + llvm::Value *m_llvm_value; ///< A LLVM IR Value for the entity, usually a GlobalVariable. }; + //---------------------------------------------------------------------- + /// @class StructMember ClangExpressionDeclMap.h "lldb/Expression/ClangExpressionDeclMap.h" + /// @brief An entity that needs to be materialized in order to make the + /// expression work. + /// + /// IRForTarget identifies those entities that actually made it into the + /// final IR and adds them to a list of StructMembers; this list is used + /// as the basis of struct layout and its fields are used for + /// materializing/dematerializing the struct. + //---------------------------------------------------------------------- struct StructMember { - const clang::NamedDecl *m_decl; - llvm::Value *m_value; - std::string m_name; - TypeFromParser m_parser_type; - off_t m_offset; - size_t m_size; - off_t m_alignment; + const clang::NamedDecl *m_decl; ///< The Decl generated for the entity. + llvm::Value *m_value; ///< A LLVM IR Value for he entity, usually a GlobalVariable. + std::string m_name; ///< The name of the entity, for use in materialization. + TypeFromParser m_parser_type; ///< The expected type of the entity, for use in materialization. + off_t m_offset; ///< The laid-out offset of the entity in the struct. Only valid after DoStructLayout(). + size_t m_size; ///< The size of the entity. + off_t m_alignment; ///< The required alignment of the entity, in bytes. }; typedef std::vector TupleVector; @@ -118,44 +377,237 @@ typedef std::vector StructMemberVector; typedef StructMemberVector::iterator StructMemberIterator; - TupleVector m_tuples; - StructMemberVector m_members; - ExecutionContext *m_exe_ctx; - SymbolContext *m_sym_ctx; /* owned by ClangExpressionDeclMap */ - ClangPersistentVariables *m_persistent_vars; - off_t m_struct_alignment; - size_t m_struct_size; - bool m_struct_laid_out; - lldb::addr_t m_allocated_area; - lldb::addr_t m_materialized_location; - std::string m_result_name; - + TupleVector m_tuples; ///< All entities that were looked up for the parser. + StructMemberVector m_members; ///< All fields of the struct that need to be materialized. + ExecutionContext *m_exe_ctx; ///< The execution context where this expression was first defined. It determines types for all the external variables, even if the expression is re-used. + SymbolContext *m_sym_ctx; ///< [owned by ClangExpressionDeclMap] The symbol context where this expression was first defined. + ClangPersistentVariables *m_persistent_vars; ///< The list of persistent variables to use when resolving symbols in the expression and when creating new ones (like the result). + off_t m_struct_alignment; ///< The alignment of the struct in bytes. + size_t m_struct_size; ///< The size of the struct in bytes. + bool m_struct_laid_out; ///< True if the struct has been laid out and the layout is valid (that is, no new fields have been added since). + lldb::addr_t m_allocated_area; ///< The base of the memory allocated for the struct. Starts on a potentially unaligned address and may therefore be larger than the struct. + lldb::addr_t m_materialized_location; ///< The address at which the struct is placed. Falls inside the allocated area. + std::string m_result_name; ///< The name of the result variable ($1, for example) + + //------------------------------------------------------------------ + /// Given a symbol context, find a variable that matches the given + /// name and type. We need this for expression re-use; we may not + /// always get the same lldb::Variable back, and we want the expression + /// to work wherever it can. Returns the variable defined in the + /// tightest scope. + /// + /// @param[in] sym_ctx + /// The SymbolContext to search for the variable. + /// + /// @param[in] name + /// The name as a plain C string. + /// + /// @param[in] type + /// The required type for the variable. This function may be called + /// during parsing, in which case we don't know its type; hence the + /// default. + /// + /// @return + /// The LLDB Variable found, or NULL if none was found. + //------------------------------------------------------------------ Variable *FindVariableInScope(const SymbolContext &sym_ctx, const char *name, TypeFromUser *type = NULL); + //------------------------------------------------------------------ + /// Get the index into the Tuple array for the given Decl. Implements + /// vanilla linear search. + /// + /// @param[out] index + /// The index into the Tuple array that corresponds to the Decl. + /// + /// @param[in] decl + /// The Decl to be looked up. + /// + /// @return + /// True if the Decl was found; false otherwise. + //------------------------------------------------------------------ + bool GetIndexForDecl (uint32_t &index, + const clang::Decl *decl); + + //------------------------------------------------------------------ + /// Get the value of a variable in a given execution context and return + /// the associated Types if needed. + /// + /// @param[in] exe_ctx + /// The execution context to look for the variable in. + /// + /// @param[in] var + /// The variable to evaluate. + /// + /// @param[in] parser_ast_context + /// The AST context of the parser, to store the found type in. + /// + /// @param[out] found_type + /// The type of the found value, as it was found in the user process. + /// This is only useful when the variable is being inspected on behalf + /// of the parser, hence the default. + /// + /// @param[out] parser_type + /// The type of the found value, as it was copied into the parser's + /// AST context. This is only useful when the variable is being + /// inspected on behalf of the parser, hence the default. + /// + /// @param[in] decl + /// The Decl to be looked up. + /// + /// @return + /// The LLDB Value for the variable. + //------------------------------------------------------------------ Value *GetVariableValue(ExecutionContext &exe_ctx, Variable *var, clang::ASTContext *parser_ast_context, TypeFromUser *found_type = NULL, TypeFromParser *parser_type = NULL); + //------------------------------------------------------------------ + /// Use the NameSearchContext to generate a Decl for the given LLDB + /// Variable, and put it in the Tuple list. + /// + /// @param[in] context + /// The NameSearchContext to use when constructing the Decl. + /// + /// @param[in] var + /// The LLDB Variable that needs a Decl. + //------------------------------------------------------------------ void AddOneVariable(NameSearchContext &context, Variable *var); + + //------------------------------------------------------------------ + /// Use the NameSearchContext to generate a Decl for the given + /// persistent variable, and put it in the Tuple list. + /// + /// @param[in] context + /// The NameSearchContext to use when constructing the Decl. + /// + /// @param[in] pvar + /// The persistent variable that needs a Decl. + //------------------------------------------------------------------ void AddOneVariable(NameSearchContext &context, ClangPersistentVariable *pvar); + + //------------------------------------------------------------------ + /// Use the NameSearchContext to generate a Decl for the given + /// function. (Functions are not placed in the Tuple list.) Can + /// handle both fully typed functions and generic functions. + /// + /// @param[in] context + /// The NameSearchContext to use when constructing the Decl. + /// + /// @param[in] fun + /// The Function that needs to be created. If non-NULL, this is + /// a fully-typed function. + /// + /// @param[in] sym + /// The Symbol that corresponds to a function that needs to be + /// created with generic type (unitptr_t foo(...)). + //------------------------------------------------------------------ void AddOneFunction(NameSearchContext &context, Function *fun, Symbol *sym); + + //------------------------------------------------------------------ + /// Use the NameSearchContext to generate a Decl for the given + /// type. (Types are not placed in the Tuple list.) + /// + /// @param[in] context + /// The NameSearchContext to use when constructing the Decl. + /// + /// @param[in] type + /// The LLDB Type that needs to be created. + //------------------------------------------------------------------ void AddOneType(NameSearchContext &context, Type *type); + //------------------------------------------------------------------ + /// Actually do the task of materializing or dematerializing the struct. + /// Since both tasks are very similar, although ClangExpressionDeclMap + /// exposes two functions to the outside, both call DoMaterialize. + /// + /// @param[in] dematerialize + /// True if the struct is to be dematerialized; false if it is to + /// be materialized. + /// + /// @param[in] exe_ctx + /// The execution context to use. + /// + /// @param[out] result + /// If the struct is being dematerialized, a pointer into which the + /// location of the result persistent variable is placed. If not, + /// NULL. + /// + /// @param[in] err + /// An Error to populate with any messages related to + /// (de)materializing the struct. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ bool DoMaterialize (bool dematerialize, ExecutionContext *exe_ctx, - ClangPersistentVariable **result, /* must be non-NULL if D is set */ + ClangPersistentVariable **result, Error &err); + //------------------------------------------------------------------ + /// Actually do the task of materializing or dematerializing a persistent + /// variable. + /// + /// @param[in] dematerialize + /// True if the variable is to be dematerialized; false if it is to + /// be materialized. + /// + /// @param[in] exe_ctx + /// The execution context to use. + /// + /// @param[in] name + /// The name of the persistent variable. + /// + /// @param[in] addr + /// The address at which to materialize the variable. + /// + /// @param[in] err + /// An Error to populate with any messages related to + /// (de)materializing the persistent variable. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ bool DoMaterializeOnePersistentVariable(bool dematerialize, ExecutionContext &exe_ctx, const char *name, lldb::addr_t addr, Error &err); + //------------------------------------------------------------------ + /// Actually do the task of materializing or dematerializing a + /// variable. + /// + /// @param[in] dematerialize + /// True if the variable is to be dematerialized; false if it is to + /// be materialized. + /// + /// @param[in] exe_ctx + /// The execution context to use. + /// + /// @param[in] sym_ctx + /// The symbol context to use (for looking the variable up). + /// + /// @param[in] name + /// The name of the variable (for looking the variable up). + /// + /// @param[in] type + /// The required type of the variable (for looking the variable up). + /// + /// @param[in] addr + /// The address at which to materialize the variable. + /// + /// @param[in] err + /// An Error to populate with any messages related to + /// (de)materializing the persistent variable. + /// + /// @return + /// True on success; false otherwise. + //------------------------------------------------------------------ bool DoMaterializeOneVariable(bool dematerialize, ExecutionContext &exe_ctx, const SymbolContext &sym_ctx, Modified: lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp?rev=111049&r1=111048&r2=111049&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionDeclMap.cpp Fri Aug 13 17:29:54 2010 @@ -115,8 +115,7 @@ ClangExpressionDeclMap::AddValueToStruct (llvm::Value *value, const clang::NamedDecl *decl, std::string &name, - void *parser_type, - clang::ASTContext *parser_ast_context, + TypeFromParser type, size_t size, off_t alignment) { @@ -137,7 +136,7 @@ member.m_value = value; member.m_decl = decl; member.m_name = name; - member.m_parser_type = TypeFromParser(parser_type, parser_ast_context); + member.m_parser_type = type; member.m_offset = 0; member.m_size = size; member.m_alignment = alignment; Modified: lldb/trunk/source/Expression/IRForTarget.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/IRForTarget.cpp?rev=111049&r1=111048&r2=111049&view=diff ============================================================================== --- lldb/trunk/source/Expression/IRForTarget.cpp (original) +++ lldb/trunk/source/Expression/IRForTarget.cpp Fri Aug 13 17:29:54 2010 @@ -528,8 +528,7 @@ if (named_decl && !m_decl_map->AddValueToStruct(V, named_decl, name, - qual_type, - ast_context, + lldb_private::TypeFromParser(qual_type, ast_context), value_size, value_alignment)) return false; From scallanan at apple.com Fri Aug 13 17:52:29 2010 From: scallanan at apple.com (Sean Callanan) Date: Fri, 13 Aug 2010 22:52:29 -0000 Subject: [Lldb-commits] [lldb] r111053 - in /lldb/trunk: include/lldb/Expression/ClangExpressionVariable.h source/Expression/ClangExpressionVariable.cpp Message-ID: <20100813225229.3EBB22A6C12C@llvm.org> Author: spyffe Date: Fri Aug 13 17:52:29 2010 New Revision: 111053 URL: http://llvm.org/viewvc/llvm-project?rev=111053&view=rev Log: Documented ClangExpressionVariable(List), and cleaned up its API slightly. Modified: lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h lldb/trunk/source/Expression/ClangExpressionVariable.cpp Modified: lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h?rev=111053&r1=111052&r2=111053&view=diff ============================================================================== --- lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h (original) +++ lldb/trunk/include/lldb/Expression/ClangExpressionVariable.h Fri Aug 13 17:52:29 2010 @@ -24,33 +24,83 @@ namespace lldb_private { +//---------------------------------------------------------------------- +/// @class ClangExpressionVariableList ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" +/// @brief Manages local variables that the expression interpreter uses. +/// +/// The DWARF interpreter, when interpreting expressions, occasionally +/// needs to interact with chunks of memory corresponding to local variable +/// values. These locals are distinct from the externally-defined values +/// handled by ClangExpressionDeclMap, and do not persist between expressions +/// so they are not handled by ClangPersistentVariables. They are kept in a +/// list, which is encapsulated in ClangEpxressionVariableList. +//---------------------------------------------------------------------- class ClangExpressionVariableList { public: + //---------------------------------------------------------------------- + /// Constructor + //---------------------------------------------------------------------- ClangExpressionVariableList(); + + //---------------------------------------------------------------------- + /// Destructor + //---------------------------------------------------------------------- ~ClangExpressionVariableList(); + //---------------------------------------------------------------------- + /// Get or create the chunk of data corresponding to a given VarDecl. + /// + /// @param[in] var_decl + /// The Decl for which a chunk of memory is to be allocated. + /// + /// @param[out] idx + /// The index of the Decl in the list of variables. + /// + /// @param[in] can_create + /// True if the memory should be created if necessary. + /// + /// @return + /// A Value for the allocated memory. NULL if the Decl couldn't be + /// found and can_create was false, or if some error occurred during + /// allocation. + //---------------------------------------------------------------------- Value * - GetVariableForVarDecl (clang::ASTContext &ast_context, - const clang::VarDecl *var_decl, + GetVariableForVarDecl (const clang::VarDecl *var_decl, uint32_t& idx, bool can_create); + //---------------------------------------------------------------------- + /// Get the chunk of data corresponding to a given index into the list. + /// + /// @param[in] idx + /// The index of the Decl in the list of variables. + /// + /// @return + /// The value at the given index, or NULL if there is none. + //---------------------------------------------------------------------- Value * GetVariableAtIndex (uint32_t idx); - - uint32_t - AppendValue (Value *value); // takes ownership - private: + //---------------------------------------------------------------------- + /// @class ClangExpressionVariable ClangExpressionVariable.h "lldb/Expression/ClangExpressionVariable.h" + /// @brief Manages one local variable for the expression interpreter. + /// + /// The expression interpreter uses specially-created Values to hold its + /// temporary locals. These Values contain data buffers holding enough + /// space to contain a variable of the appropriate type. The VarDecls + /// are only used while creating the list and generating the DWARF code for + /// an expression; when interpreting the DWARF, the variables are identified + /// only by their index into the list of variables. + //---------------------------------------------------------------------- struct ClangExpressionVariable { - const clang::VarDecl *m_var_decl; - Value *m_value; + const clang::VarDecl *m_var_decl; ///< The VarDecl corresponding to the parsed local. + Value *m_value; ///< The LLDB Value containing the data for the local. }; typedef std::vector Variables; - Variables m_variables; + Variables m_variables; ///< The list of variables used by the expression. }; } // namespace lldb_private Modified: lldb/trunk/source/Expression/ClangExpressionVariable.cpp URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/ClangExpressionVariable.cpp?rev=111053&r1=111052&r2=111053&view=diff ============================================================================== --- lldb/trunk/source/Expression/ClangExpressionVariable.cpp (original) +++ lldb/trunk/source/Expression/ClangExpressionVariable.cpp Fri Aug 13 17:52:29 2010 @@ -33,14 +33,14 @@ } Value * -ValueForDecl(ASTContext &ast_context, const VarDecl *var_decl) +ValueForDecl(const VarDecl *var_decl) { Value *ret = new Value; ret->SetContext(Value::eContextTypeOpaqueClangQualType, var_decl->getType().getAsOpaquePtr()); - uint64_t bit_width = ast_context.getTypeSize(var_decl->getType()); + uint64_t bit_width = var_decl->getASTContext().getTypeSize(var_decl->getType()); uint32_t byte_size = (bit_width + 7 ) / 8; @@ -50,7 +50,7 @@ } Value * -ClangExpressionVariableList::GetVariableForVarDecl (ASTContext &ast_context, const VarDecl *var_decl, uint32_t& idx, bool can_create) +ClangExpressionVariableList::GetVariableForVarDecl (const VarDecl *var_decl, uint32_t& idx, bool can_create) { uint32_t num_variables = m_variables.size(); uint32_t var_index; @@ -71,7 +71,7 @@ ClangExpressionVariable val; val.m_var_decl = var_decl; - val.m_value = ValueForDecl(ast_context, var_decl); + val.m_value = ValueForDecl(var_decl); m_variables.push_back(val); return m_variables.back().m_value; @@ -85,16 +85,3 @@ return NULL; } - -uint32_t -ClangExpressionVariableList::AppendValue (Value *value) -{ - uint32_t idx = m_variables.size(); - - ClangExpressionVariable val; - val.m_var_decl = NULL; - val.m_value = value; - - m_variables.push_back(val); - return idx; -} From johnny.chen at apple.com Fri Aug 13 17:58:44 2010 From: johnny.chen at apple.com (Johnny Chen) Date: Fri, 13 Aug 2010 22:58:44 -0000 Subject: [Lldb-commits] [lldb] r111056 - /lldb/trunk/test/dotest.py Message-ID: <20100813225844.51AA62A6C12C@llvm.org> Author: johnny Date: Fri Aug 13 17:58:44 2010 New Revision: 111056 URL: http://llvm.org/viewvc/llvm-project?rev=111056&view=rev Log: Added a workaround for test suite hang while terminating by checking env variable LLDB_TESTSUITE_FORCE_FINISH and, if defined, kill the test suite. Modified: lldb/trunk/test/dotest.py Modified: lldb/trunk/test/dotest.py URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=111056&r1=111055&r2=111056&view=diff ============================================================================== --- lldb/trunk/test/dotest.py (original) +++ lldb/trunk/test/dotest.py Fri Aug 13 17:58:44 2010 @@ -187,5 +187,10 @@ # Invoke the default TextTestRunner to run the test suite. result = unittest2.TextTestRunner(verbosity=verbose).run(suite) +if ("LLDB_TESTSUITE_FORCE_FINISH" in os.environ): + import subprocess + print "Terminating Test suite..." + subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())]) + # Exiting. sys.exit(not result.wasSuccessful)