Add support for custom commands to set flags on themselves
This works for Python commands defined via a class (implement get_flags on your class) and C++ plugin commands (which can call SBCommand::GetFlags()/SetFlags())

Flags allow features such as not letting the command run if there's no target, or if the process is not stopped, ...
Commands could always check for these things themselves, but having these accessible via flags makes custom commands more consistent with built-in ones

llvm-svn: 238286
diff --git a/lldb/source/Interpreter/CommandObject.cpp b/lldb/source/Interpreter/CommandObject.cpp
index f6e5bca..29e4744 100644
--- a/lldb/source/Interpreter/CommandObject.cpp
+++ b/lldb/source/Interpreter/CommandObject.cpp
@@ -228,20 +228,20 @@
     m_exe_ctx = m_interpreter.GetExecutionContext();
 
     const uint32_t flags = GetFlags().Get();
-    if (flags & (eFlagRequiresTarget   |
-                 eFlagRequiresProcess  |
-                 eFlagRequiresThread   |
-                 eFlagRequiresFrame    |
-                 eFlagTryTargetAPILock ))
+    if (flags & (eCommandRequiresTarget   |
+                 eCommandRequiresProcess  |
+                 eCommandRequiresThread   |
+                 eCommandRequiresFrame    |
+                 eCommandTryTargetAPILock ))
     {
 
-        if ((flags & eFlagRequiresTarget) && !m_exe_ctx.HasTargetScope())
+        if ((flags & eCommandRequiresTarget) && !m_exe_ctx.HasTargetScope())
         {
             result.AppendError (GetInvalidTargetDescription());
             return false;
         }
 
-        if ((flags & eFlagRequiresProcess) && !m_exe_ctx.HasProcessScope())
+        if ((flags & eCommandRequiresProcess) && !m_exe_ctx.HasProcessScope())
         {
             if (!m_exe_ctx.HasTargetScope())
                 result.AppendError (GetInvalidTargetDescription());
@@ -250,7 +250,7 @@
             return false;
         }
         
-        if ((flags & eFlagRequiresThread) && !m_exe_ctx.HasThreadScope())
+        if ((flags & eCommandRequiresThread) && !m_exe_ctx.HasThreadScope())
         {
             if (!m_exe_ctx.HasTargetScope())
                 result.AppendError (GetInvalidTargetDescription());
@@ -261,7 +261,7 @@
             return false;
         }
         
-        if ((flags & eFlagRequiresFrame) && !m_exe_ctx.HasFrameScope())
+        if ((flags & eCommandRequiresFrame) && !m_exe_ctx.HasFrameScope())
         {
             if (!m_exe_ctx.HasTargetScope())
                 result.AppendError (GetInvalidTargetDescription());
@@ -274,13 +274,13 @@
             return false;
         }
         
-        if ((flags & eFlagRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr))
+        if ((flags & eCommandRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == nullptr))
         {
             result.AppendError (GetInvalidRegContextDescription());
             return false;
         }
 
-        if (flags & eFlagTryTargetAPILock)
+        if (flags & eCommandTryTargetAPILock)
         {
             Target *target = m_exe_ctx.GetTargetPtr();
             if (target)
@@ -288,13 +288,13 @@
         }
     }
 
-    if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused))
+    if (GetFlags().AnySet (eCommandProcessMustBeLaunched | eCommandProcessMustBePaused))
     {
         Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
         if (process == nullptr)
         {
             // A process that is not running is considered paused.
-            if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
+            if (GetFlags().Test(eCommandProcessMustBeLaunched))
             {
                 result.AppendError ("Process must exist.");
                 result.SetStatus (eReturnStatusFailed);
@@ -318,7 +318,7 @@
             case eStateDetached:
             case eStateExited:
             case eStateUnloaded:
-                if (GetFlags().Test(CommandObject::eFlagProcessMustBeLaunched))
+                if (GetFlags().Test(eCommandProcessMustBeLaunched))
                 {
                     result.AppendError ("Process must be launched.");
                     result.SetStatus (eReturnStatusFailed);
@@ -328,7 +328,7 @@
 
             case eStateRunning:
             case eStateStepping:
-                if (GetFlags().Test(CommandObject::eFlagProcessMustBePaused))
+                if (GetFlags().Test(eCommandProcessMustBePaused))
                 {
                     result.AppendError ("Process is running.  Use 'process interrupt' to pause execution.");
                     result.SetStatus (eReturnStatusFailed);
diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
index 1baf484..1e16fd3 100644
--- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
@@ -2878,6 +2878,78 @@
     return got_string;
 }
 
+uint32_t
+ScriptInterpreterPython::GetFlagsForCommandObject (StructuredData::GenericSP cmd_obj_sp)
+{
+    uint32_t result = 0;
+    
+    Locker py_lock (this,
+                    Locker::AcquireLock | Locker::NoSTDIN,
+                    Locker::FreeLock);
+    
+    static char callee_name[] = "get_flags";
+    
+    if (!cmd_obj_sp)
+        return result;
+    
+    PyObject* implementor = (PyObject*)cmd_obj_sp->GetValue();
+    
+    if (implementor == nullptr || implementor == Py_None)
+        return result;
+    
+    PyObject* pmeth  = PyObject_GetAttrString(implementor, callee_name);
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    if (pmeth == nullptr || pmeth == Py_None)
+    {
+        Py_XDECREF(pmeth);
+        return result;
+    }
+    
+    if (PyCallable_Check(pmeth) == 0)
+    {
+        if (PyErr_Occurred())
+        {
+            PyErr_Clear();
+        }
+        
+        Py_XDECREF(pmeth);
+        return result;
+    }
+    
+    if (PyErr_Occurred())
+    {
+        PyErr_Clear();
+    }
+    
+    Py_XDECREF(pmeth);
+    
+    // right now we know this function exists and is callable..
+    PyObject* py_return = PyObject_CallMethod(implementor, callee_name, nullptr);
+    
+    // if it fails, print the error but otherwise go on
+    if (PyErr_Occurred())
+    {
+        PyErr_Print();
+        PyErr_Clear();
+    }
+    
+    if (py_return != nullptr && py_return != Py_None)
+    {
+        if (PyInt_Check(py_return))
+            result = (uint32_t)PyInt_AsLong(py_return);
+        else if (PyLong_Check(py_return))
+            result = (uint32_t)PyLong_AsLong(py_return);
+    }
+    Py_XDECREF(py_return);
+    
+    return result;
+}
+
 bool
 ScriptInterpreterPython::GetLongHelpForCommandObject (StructuredData::GenericSP cmd_obj_sp,
                                                       std::string& dest)