Modified the host process monitor callback function Host::StartMonitoringChildProcess
to spawn a thread for each process that is being monitored. Previously
LLDB would spawn a single thread that would wait for any child process which
isn't ok to do as a shared library (LLDB.framework on Mac OSX, or lldb.so on
linux). The old single thread used to call wait4() with a pid of -1 which 
could cause it to reap child processes that it shouldn't have.

Re-wrote the way Function blocks are handles. Previously I attempted to keep
all blocks in a single memory allocation (in a std::vector). This made the
code somewhat efficient, but hard to work with. I got rid of the old BlockList
class, and went to a straight parent with children relationship. This new 
approach will allow for partial parsing of the blocks within a function.




git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@111706 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Symbol/Block.cpp b/source/Symbol/Block.cpp
index 3a132f6..28da776 100644
--- a/source/Symbol/Block.cpp
+++ b/source/Symbol/Block.cpp
@@ -17,47 +17,26 @@
 using namespace lldb;
 using namespace lldb_private;
 
-Block::Block(user_id_t uid, uint32_t depth, BlockList* blocks) :
+Block::Block(lldb::user_id_t uid) :
     UserID(uid),
-    m_block_list(blocks),
-    m_depth(depth),
-    m_ranges(),
-    m_inlineInfoSP(),
-    m_variables()
+    m_parent_scope (NULL),
+    m_sibling (NULL),
+    m_children (),
+    m_ranges (),
+    m_inlineInfoSP (),
+    m_variables (),
+    m_parsed_block_info (false),
+    m_parsed_block_variables (false),
+    m_parsed_child_blocks (false)
 {
 }
 
-Block::Block(const Block& rhs) :
-    UserID(rhs),
-    m_block_list(rhs.m_block_list),
-    m_depth(rhs.m_depth),
-    m_ranges(rhs.m_ranges),
-    m_inlineInfoSP(rhs.m_inlineInfoSP),
-    m_variables(rhs.m_variables)
-{
-}
-
-const Block&
-Block::operator= (const Block& rhs)
-{
-    if (this != &rhs)
-    {
-        UserID::operator= (rhs);
-        m_block_list = rhs.m_block_list;
-        m_depth = rhs.m_depth;
-        m_ranges = rhs.m_ranges;
-        m_inlineInfoSP = rhs.m_inlineInfoSP;
-        m_variables = rhs.m_variables;
-    }
-    return *this;
-}
-
 Block::~Block ()
 {
 }
 
 void
-Block::GetDescription(Stream *s, lldb::DescriptionLevel level, Process *process) const
+Block::GetDescription(Stream *s, Function *function, lldb::DescriptionLevel level, Process *process) const
 {
     size_t num_ranges = m_ranges.size();
     if (num_ranges)
@@ -65,9 +44,9 @@
         
         addr_t base_addr = LLDB_INVALID_ADDRESS;
         if (process)
-            base_addr = m_block_list->GetAddressRange().GetBaseAddress().GetLoadAddress(process);
+            base_addr = function->GetAddressRange().GetBaseAddress().GetLoadAddress(process);
         if (base_addr == LLDB_INVALID_ADDRESS)
-            base_addr = m_block_list->GetAddressRange().GetBaseAddress().GetFileAddress();
+            base_addr = function->GetAddressRange().GetBaseAddress().GetFileAddress();
 
         s->Printf("range%s = ", num_ranges > 1 ? "s" : "");
         std::vector<VMRange>::const_iterator pos, end = m_ranges.end();
@@ -85,9 +64,13 @@
 {
     if (depth < 0)
     {
-        // We have a depth that is less than zero, print our parent blocks
-        // first
-        m_block_list->Dump(s, GetParentUID(), depth + 1, show_context);
+        Block *parent = GetParent();
+        if (parent)
+        {
+            // We have a depth that is less than zero, print our parent blocks
+            // first
+            parent->Dump(s, base_addr, depth + 1, show_context);
+        }
     }
 
     s->Printf("%.*p: ", (int)sizeof(void*) * 2, this);
@@ -126,12 +109,9 @@
             m_variables->Dump(s, show_context);
         }
 
-        uint32_t blockID = m_block_list->GetFirstChild(GetID());
-        while (blockID != Block::InvalidID)
+        for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
         {
-            m_block_list->Dump(s, blockID, depth - 1, show_context);
-
-            blockID = m_block_list->GetSibling(blockID);
+            child_block->Dump(s, base_addr, depth - 1, show_context);
         }
 
         s->IndentLess();
@@ -140,11 +120,28 @@
 }
 
 
+Block *
+Block::FindBlockByID (user_id_t block_id)
+{
+    if (block_id == GetID())
+        return this;
+
+    Block *matching_block = NULL;
+    for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
+    {
+        matching_block = child_block->FindBlockByID (block_id);
+        if (matching_block)
+            break;
+    }
+    return matching_block;
+}
+
 void
 Block::CalculateSymbolContext(SymbolContext* sc)
 {
+    if (m_parent_scope)
+        m_parent_scope->CalculateSymbolContext(sc);
     sc->block = this;
-    m_block_list->GetFunction()->CalculateSymbolContext(sc);
 }
 
 void
@@ -196,7 +193,10 @@
 void
 Block::DumpSymbolContext(Stream *s)
 {
-    m_block_list->GetFunction()->DumpSymbolContext(s);
+    SymbolContext sc;
+    CalculateSymbolContext(&sc);
+    if (sc.function)
+        sc.function->DumpSymbolContext(s);
     s->Printf(", Block{0x%8.8x}", GetID());
 }
 
@@ -212,37 +212,19 @@
     return VMRange::ContainsRange(m_ranges, range);
 }
 
-
-
-bool
-BlockList::BlockContainsBlockWithID (const user_id_t block_id, const user_id_t find_block_id) const
+Block *
+Block::GetParent () const
 {
-    if (block_id == Block::InvalidID)
-        return false;
-
-    if (block_id == find_block_id)
-        return true;
-    else
+    if (m_parent_scope)
     {
-        user_id_t child_block_id = GetFirstChild(block_id);
-        while (child_block_id != Block::InvalidID)
-        {
-            if (BlockContainsBlockWithID (child_block_id, find_block_id))
-                return true;
-            child_block_id = GetSibling(child_block_id);
-        }
+        SymbolContext sc;
+        m_parent_scope->CalculateSymbolContext(&sc);
+        if (sc.block)
+            return sc.block;
     }
-
-    return false;
+    return NULL;
 }
 
-bool
-Block::ContainsBlockWithID (user_id_t block_id) const
-{
-    return m_block_list->BlockContainsBlockWithID (GetID(), block_id);
-}
-
-
 void
 Block::AddRange(addr_t start_offset, addr_t end_offset)
 {
@@ -276,45 +258,29 @@
 }
 
 Block *
-Block::GetParent () const
-{
-    return m_block_list->GetBlockByID (m_block_list->GetParent(GetID()));
-}
-
-Block *
-Block::GetSibling () const
-{
-    return m_block_list->GetBlockByID (m_block_list->GetSibling(GetID()));
-}
-
-Block *
 Block::GetFirstChild () const
 {
-    return m_block_list->GetBlockByID (m_block_list->GetFirstChild(GetID()));
+    if (m_children.empty())
+        return NULL;
+    return m_children.front().get();
 }
 
-user_id_t
-Block::GetParentUID() const
+void
+Block::AddChild(const BlockSP &child_block_sp)
 {
-    return m_block_list->GetParent(GetID());
-}
+    if (child_block_sp)
+    {
+        Block *block_needs_sibling = NULL;
 
-user_id_t
-Block::GetSiblingUID() const
-{
-    return m_block_list->GetSibling(GetID());
-}
+        if (!m_children.empty())
+            block_needs_sibling = m_children.back().get();
 
-user_id_t
-Block::GetFirstChildUID() const
-{
-    return m_block_list->GetFirstChild(GetID());
-}
+        child_block_sp->SetParentScope (this);
+        m_children.push_back (child_block_sp);
 
-user_id_t
-Block::AddChild(user_id_t userID)
-{
-    return m_block_list->AddChild(GetID(), userID);
+        if (block_needs_sibling)
+            block_needs_sibling->SetSibling (child_block_sp.get());
+    }
 }
 
 void
@@ -329,12 +295,16 @@
 Block::GetVariableList (bool get_child_variables, bool can_create)
 {
     VariableListSP variable_list_sp;
-    if (m_variables.get() == NULL && can_create)
+    if (m_parsed_block_variables == false)
     {
-        SymbolContext sc;
-        CalculateSymbolContext(&sc);
-        assert(sc.module_sp);
-        sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
+        if (m_variables.get() == NULL && can_create)
+        {
+            m_parsed_block_variables = true;
+            SymbolContext sc;
+            CalculateSymbolContext(&sc);
+            assert(sc.module_sp);
+            sc.module_sp->GetSymbolVendor()->ParseVariablesForContext(sc);
+        }
     }
 
     if (m_variables.get())
@@ -387,285 +357,14 @@
     m_variables = variables;
 }
 
-uint32_t
-Block::Depth () const
-{
-    return m_depth;
-}
-
-BlockList::BlockList(Function *function, const AddressRange& range) :
-    m_function(function),
-    m_range(range),
-    m_blocks()
-{
-}
-
-BlockList::~BlockList()
-{
-}
-
-AddressRange &
-BlockList::GetAddressRange()
-{
-    return m_range;
-}
-
-const AddressRange &
-BlockList::GetAddressRange() const
-{
-    return m_range;
-}
-
 void
-BlockList::Dump(Stream *s, user_id_t blockID, uint32_t depth, bool show_context) const
+Block::SetBlockInfoHasBeenParsed (bool b, bool set_children)
 {
-    const Block* block = GetBlockByID(blockID);
-    if (block)
-        block->Dump(s, m_range.GetBaseAddress().GetFileAddress(), depth, show_context);
-}
-
-Function *
-BlockList::GetFunction()
-{
-    return m_function;
-}
-
-
-const Function *
-BlockList::GetFunction() const
-{
-    return m_function;
-}
-
-user_id_t
-BlockList::GetParent(user_id_t blockID) const
-{
-    collection::const_iterator end = m_blocks.end();
-    collection::const_iterator begin = m_blocks.begin();
-    collection::const_iterator pos = std::find_if(begin, end, UserID::IDMatches(blockID));
-
-    if (pos != end && pos != begin && pos->Depth() > 0)
+    m_parsed_block_info = b;
+    if (set_children)
     {
-        const uint32_t parent_depth = pos->Depth() - 1;
-
-        while (--pos >= begin)
-        {
-            if (pos->Depth() == parent_depth)
-                return pos->GetID();
-        }
+        m_parsed_child_blocks = true;
+        for (Block *child_block = GetFirstChild(); child_block != NULL; child_block = child_block->GetSibling())
+            child_block->SetBlockInfoHasBeenParsed (b, true);
     }
-    return Block::InvalidID;
-}
-
-user_id_t
-BlockList::GetSibling(user_id_t blockID) const
-{
-    collection::const_iterator end = m_blocks.end();
-    collection::const_iterator pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(blockID));
-
-    if (pos != end)
-    {
-        const uint32_t sibling_depth = pos->Depth();
-        while (++pos != end)
-        {
-            uint32_t depth = pos->Depth();
-            if (depth == sibling_depth)
-                return pos->GetID();
-            if (depth < sibling_depth)
-                break;
-        }
-    }
-    return Block::InvalidID;
-}
-
-user_id_t
-BlockList::GetFirstChild(user_id_t blockID) const
-{
-    if (!m_blocks.empty())
-    {
-        if (blockID == Block::RootID)
-        {
-            return m_blocks.front().GetID();
-        }
-        else
-        {
-            collection::const_iterator end = m_blocks.end();
-            collection::const_iterator pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(blockID));
-
-            if (pos != end)
-            {
-                collection::const_iterator child_pos = pos + 1;
-                if (child_pos != end)
-                {
-                    if (child_pos->Depth() == pos->Depth() + 1)
-                        return child_pos->GetID();
-                }
-            }
-        }
-    }
-    return Block::InvalidID;
-}
-
-
-// Return the current number of bytes that this object occupies in memory
-size_t
-BlockList::MemorySize() const
-{
-    size_t mem_size = sizeof(BlockList);
-
-    collection::const_iterator pos, end = m_blocks.end();
-    for (pos = m_blocks.begin(); pos != end; ++pos)
-        mem_size += pos->MemorySize();  // Each block can vary in size
-
-    return mem_size;
-
-}
-
-user_id_t
-BlockList::AddChild (user_id_t parentID, user_id_t childID)
-{
-    bool added = false;
-    if (parentID == Block::RootID)
-    {
-        assert(m_blocks.empty());
-        Block block(childID, 0, this);
-        m_blocks.push_back(block);
-        added = true;
-    }
-    else
-    {
-        collection::iterator end = m_blocks.end();
-        collection::iterator parent_pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(parentID));
-        assert(parent_pos != end);
-        if (parent_pos != end)
-        {
-            const uint32_t parent_sibling_depth = parent_pos->Depth();
-
-            collection::iterator insert_pos = parent_pos;
-            collection::iterator prev_sibling = end;
-            while (++insert_pos != end)
-            {
-                if (insert_pos->Depth() <= parent_sibling_depth)
-                    break;
-            }
-
-            Block child_block(childID, parent_pos->Depth() + 1, this);
-            collection::iterator child_pos = m_blocks.insert(insert_pos, child_block);
-            added = true;
-        }
-    }
-    if (added)
-        return childID;
-    return Block::InvalidID;
-}
-
-const Block *
-BlockList::GetBlockByID(user_id_t blockID) const
-{
-    if (m_blocks.empty() || blockID == Block::InvalidID)
-        return NULL;
-
-    if (blockID == Block::RootID)
-        blockID = m_blocks.front().GetID();
-
-    collection::const_iterator end = m_blocks.end();
-    collection::const_iterator pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(blockID));
-    if (pos != end)
-        return &(*pos);
-    return NULL;
-}
-
-Block *
-BlockList::GetBlockByID(user_id_t blockID)
-{
-    if (m_blocks.empty() || blockID == Block::InvalidID)
-        return NULL;
-
-    if (blockID == Block::RootID)
-        blockID = m_blocks.front().GetID();
-
-    collection::iterator end = m_blocks.end();
-    collection::iterator pos = std::find_if(m_blocks.begin(), end, UserID::IDMatches(blockID));
-    if (pos != end)
-        return &(*pos);
-    return NULL;
-}
-
-bool
-BlockList::AddRange(user_id_t blockID, addr_t start_offset, addr_t end_offset)
-{
-    Block *block = GetBlockByID(blockID);
-
-    if (block)
-    {
-        block->AddRange(start_offset, end_offset);
-        return true;
-    }
-    return false;
-}
-//
-//const Block *
-//BlockList::FindDeepestBlockForAddress (const Address &addr)
-//{
-//    if (m_range.Contains(addr))
-//    {
-//        addr_t block_offset = addr.GetFileAddress() - m_range.GetBaseAddress().GetFileAddress();
-//        collection::const_iterator pos, end = m_blocks.end();
-//        collection::const_iterator deepest_match_pos = end;
-//        for (pos = m_blocks.begin(); pos != end; ++pos)
-//        {
-//            if (pos->Contains (block_offset))
-//            {
-//                if (deepest_match_pos == end || deepest_match_pos->Depth() < pos->Depth())
-//                    deepest_match_pos = pos;
-//            }
-//        }
-//        if (deepest_match_pos != end)
-//            return &(*deepest_match_pos);
-//    }
-//    return NULL;
-//}
-//
-bool
-BlockList::SetInlinedFunctionInfo(user_id_t blockID, const char *name, const char *mangled, const Declaration *decl_ptr, const Declaration *call_decl_ptr)
-{
-    Block *block = GetBlockByID(blockID);
-
-    if (block)
-    {
-        block->SetInlinedFunctionInfo(name, mangled, decl_ptr, call_decl_ptr);
-        return true;
-    }
-    return false;
-}
-
-VariableListSP
-BlockList::GetVariableList(user_id_t blockID, bool get_child_variables, bool can_create)
-{
-    VariableListSP variable_list_sp;
-    Block *block = GetBlockByID(blockID);
-    if (block)
-        variable_list_sp = block->GetVariableList(get_child_variables, can_create);
-    return variable_list_sp;
-}
-
-bool
-BlockList::IsEmpty() const
-{
-    return m_blocks.empty();
-}
-
-
-
-bool
-BlockList::SetVariableList(user_id_t blockID, VariableListSP& variables)
-{
-    Block *block = GetBlockByID(blockID);
-    if (block)
-    {
-        block->SetVariableList(variables);
-        return true;
-    }
-    return false;
-
 }