Added mutex protection to the Symtab class.

Added a new SortOrder enumeration and hooked it up to the "image dump symtab"
command so we can dump symbol tables in the original order, sorted by address, 
or sorted by name.

llvm-svn: 116049
diff --git a/lldb/source/Commands/CommandObjectImage.cpp b/lldb/source/Commands/CommandObjectImage.cpp
index f8a52ae..ebbc0f1 100644
--- a/lldb/source/Commands/CommandObjectImage.cpp
+++ b/lldb/source/Commands/CommandObjectImage.cpp
@@ -156,7 +156,7 @@
 
 
 static void
-DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module)
+DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, lldb::SortOrder sort_order)
 {
     if (module)
     {
@@ -165,7 +165,7 @@
         {
             Symtab *symtab = objfile->GetSymtab();
             if (symtab)
-                symtab->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target);
+                symtab->Dump(&strm, interpreter.GetDebugger().GetExecutionContext().target, sort_order);
         }
     }
 }
@@ -634,8 +634,13 @@
                     result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
                     for (uint32_t image_idx = 0;  image_idx<num_modules; ++image_idx)
                     {
+                        if (num_dumped > 0)
+                        {
+                            result.GetOutputStream().EOL();
+                            result.GetOutputStream().EOL();
+                        }
                         num_dumped++;
-                        DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
+                        DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
                     }
                 }
                 else
@@ -672,8 +677,13 @@
                             Module *image_module = matching_modules.GetModulePointerAtIndex(i);
                             if (image_module)
                             {
+                                if (num_dumped > 0)
+                                {
+                                    result.GetOutputStream().EOL();
+                                    result.GetOutputStream().EOL();
+                                }
                                 num_dumped++;
-                                DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module);
+                                DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order);
                             }
                         }
                     }
@@ -692,9 +702,100 @@
         }
         return result.Succeeded();
     }
+    
+    virtual Options *
+    GetOptions ()
+    {
+        return &m_options;
+    }
+    
+    class CommandOptions : public Options
+    {
+    public:
 
+        CommandOptions () :
+            Options(),
+            m_sort_order (eSortOrderNone)
+        {
+        }
+
+        virtual
+        ~CommandOptions ()
+        {
+        }
+
+        virtual Error
+        SetOptionValue (int option_idx, const char *option_arg)
+        {
+            Error error;
+            char short_option = (char) m_getopt_table[option_idx].val;
+
+            switch (short_option)
+            {
+            case 's':
+                {
+                    bool found_one = false;
+                    m_sort_order = (lldb::SortOrder) Args::StringToOptionEnum (option_arg, 
+                                                                               g_option_table[option_idx].enum_values, 
+                                                                               eSortOrderNone,
+                                                                               &found_one);
+                    if (!found_one)
+                        error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n", 
+                                                       option_arg, 
+                                                       short_option);
+                }
+                break;
+
+            default:
+                error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
+                break;
+
+            }
+            return error;
+        }
+
+        void
+        ResetOptionValues ()
+        {
+            Options::ResetOptionValues();
+            m_sort_order = eSortOrderNone;
+        }
+
+        const lldb::OptionDefinition*
+        GetDefinitions ()
+        {
+            return g_option_table;
+        }
+
+        // Options table: Required for subclasses of Options.
+        static lldb::OptionDefinition g_option_table[];
+
+        SortOrder m_sort_order;
+    };
+
+protected:
+
+    CommandOptions m_options;
 };
 
+lldb::OptionEnumValueElement
+g_sort_option_enumeration[4] =
+{
+    { eSortOrderNone,       "none",     "No sorting, use the original symbol table order."},
+    { eSortOrderByAddress,  "address",  "Sort output by symbol address."},
+    { eSortOrderByName,     "name",     "Sort output by symbol name."},
+    { 0,                    NULL,       NULL }
+};
+
+
+lldb::OptionDefinition
+CommandObjectImageDumpSymtab::CommandOptions::g_option_table[] =
+{
+{ LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
+{ 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
+};
+
+
 //----------------------------------------------------------------------
 // Image section dumping command
 //----------------------------------------------------------------------
@@ -1380,8 +1481,7 @@
     {
     }
 
-    virtual
-    Options *
+    virtual Options *
     GetOptions ()
     {
         return &m_options;
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index 203c6b9..ece29d3 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -506,7 +506,7 @@
 
             switch (short_option)
             {
-                case 'a':
+            case 'a':
                 {
                     bool success;
                     m_avoid_no_debug =  Args::StringToBoolean (option_arg, true, &success);
@@ -514,7 +514,8 @@
                         error.SetErrorStringWithFormat("Invalid boolean value for option '%c'.\n", short_option);
                 }
                 break;
-                case 'm':
+            
+            case 'm':
                 {
                     bool found_one = false;
                     OptionEnumValueElement *enum_values = g_option_table[option_idx].enum_values; 
@@ -523,15 +524,17 @@
                         error.SetErrorStringWithFormat("Invalid enumeration value for option '%c'.\n", short_option);
                 }
                 break;
-                case 'r':
+            
+            case 'r':
                 {
                     m_avoid_regexp.clear();
                     m_avoid_regexp.assign(option_arg);
                 }
                 break;
-                default:
-                    error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
-                    break;
+
+            default:
+                error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
+                break;
 
             }
             return error;