forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			186 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			186 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			C++
		
	
	
	
//===-- BreakpointLocationCollection.cpp ------------------------*- C++ -*-===//
 | 
						|
//
 | 
						|
//                     The LLVM Compiler Infrastructure
 | 
						|
//
 | 
						|
// This file is distributed under the University of Illinois Open Source
 | 
						|
// License. See LICENSE.TXT for details.
 | 
						|
//
 | 
						|
//===----------------------------------------------------------------------===//
 | 
						|
 | 
						|
// C Includes
 | 
						|
// C++ Includes
 | 
						|
// Other libraries and framework includes
 | 
						|
// Project includes
 | 
						|
#include "lldb/Breakpoint/BreakpointLocationCollection.h"
 | 
						|
#include "lldb/Breakpoint/Breakpoint.h"
 | 
						|
#include "lldb/Breakpoint/BreakpointLocation.h"
 | 
						|
#include "lldb/Core/ModuleList.h"
 | 
						|
#include "lldb/Target/Thread.h"
 | 
						|
#include "lldb/Target/ThreadSpec.h"
 | 
						|
 | 
						|
using namespace lldb;
 | 
						|
using namespace lldb_private;
 | 
						|
 | 
						|
//----------------------------------------------------------------------
 | 
						|
// BreakpointLocationCollection constructor
 | 
						|
//----------------------------------------------------------------------
 | 
						|
BreakpointLocationCollection::BreakpointLocationCollection()
 | 
						|
    : m_break_loc_collection(), m_collection_mutex() {}
 | 
						|
 | 
						|
//----------------------------------------------------------------------
 | 
						|
// Destructor
 | 
						|
//----------------------------------------------------------------------
 | 
						|
BreakpointLocationCollection::~BreakpointLocationCollection() {}
 | 
						|
 | 
						|
void BreakpointLocationCollection::Add(const BreakpointLocationSP &bp_loc) {
 | 
						|
  std::lock_guard<std::mutex> guard(m_collection_mutex);
 | 
						|
  BreakpointLocationSP old_bp_loc =
 | 
						|
      FindByIDPair(bp_loc->GetBreakpoint().GetID(), bp_loc->GetID());
 | 
						|
  if (!old_bp_loc.get())
 | 
						|
    m_break_loc_collection.push_back(bp_loc);
 | 
						|
}
 | 
						|
 | 
						|
bool BreakpointLocationCollection::Remove(lldb::break_id_t bp_id,
 | 
						|
                                          lldb::break_id_t bp_loc_id) {
 | 
						|
  std::lock_guard<std::mutex> guard(m_collection_mutex);
 | 
						|
  collection::iterator pos = GetIDPairIterator(bp_id, bp_loc_id); // Predicate
 | 
						|
  if (pos != m_break_loc_collection.end()) {
 | 
						|
    m_break_loc_collection.erase(pos);
 | 
						|
    return true;
 | 
						|
  }
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
class BreakpointIDPairMatches {
 | 
						|
public:
 | 
						|
  BreakpointIDPairMatches(lldb::break_id_t break_id,
 | 
						|
                          lldb::break_id_t break_loc_id)
 | 
						|
      : m_break_id(break_id), m_break_loc_id(break_loc_id) {}
 | 
						|
 | 
						|
  bool operator()(const BreakpointLocationSP &bp_loc) const {
 | 
						|
    return m_break_id == bp_loc->GetBreakpoint().GetID() &&
 | 
						|
           m_break_loc_id == bp_loc->GetID();
 | 
						|
  }
 | 
						|
 | 
						|
private:
 | 
						|
  const lldb::break_id_t m_break_id;
 | 
						|
  const lldb::break_id_t m_break_loc_id;
 | 
						|
};
 | 
						|
 | 
						|
BreakpointLocationCollection::collection::iterator
 | 
						|
BreakpointLocationCollection::GetIDPairIterator(lldb::break_id_t break_id,
 | 
						|
                                                lldb::break_id_t break_loc_id) {
 | 
						|
  return std::find_if(
 | 
						|
      m_break_loc_collection.begin(),
 | 
						|
      m_break_loc_collection.end(),                     // Search full range
 | 
						|
      BreakpointIDPairMatches(break_id, break_loc_id)); // Predicate
 | 
						|
}
 | 
						|
 | 
						|
BreakpointLocationCollection::collection::const_iterator
 | 
						|
BreakpointLocationCollection::GetIDPairConstIterator(
 | 
						|
    lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const {
 | 
						|
  return std::find_if(
 | 
						|
      m_break_loc_collection.begin(),
 | 
						|
      m_break_loc_collection.end(),                     // Search full range
 | 
						|
      BreakpointIDPairMatches(break_id, break_loc_id)); // Predicate
 | 
						|
}
 | 
						|
 | 
						|
BreakpointLocationSP
 | 
						|
BreakpointLocationCollection::FindByIDPair(lldb::break_id_t break_id,
 | 
						|
                                           lldb::break_id_t break_loc_id) {
 | 
						|
  BreakpointLocationSP stop_sp;
 | 
						|
  collection::iterator pos = GetIDPairIterator(break_id, break_loc_id);
 | 
						|
  if (pos != m_break_loc_collection.end())
 | 
						|
    stop_sp = *pos;
 | 
						|
 | 
						|
  return stop_sp;
 | 
						|
}
 | 
						|
 | 
						|
const BreakpointLocationSP BreakpointLocationCollection::FindByIDPair(
 | 
						|
    lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const {
 | 
						|
  BreakpointLocationSP stop_sp;
 | 
						|
  collection::const_iterator pos =
 | 
						|
      GetIDPairConstIterator(break_id, break_loc_id);
 | 
						|
  if (pos != m_break_loc_collection.end())
 | 
						|
    stop_sp = *pos;
 | 
						|
 | 
						|
  return stop_sp;
 | 
						|
}
 | 
						|
 | 
						|
BreakpointLocationSP BreakpointLocationCollection::GetByIndex(size_t i) {
 | 
						|
  std::lock_guard<std::mutex> guard(m_collection_mutex);
 | 
						|
  BreakpointLocationSP stop_sp;
 | 
						|
  if (i < m_break_loc_collection.size())
 | 
						|
    stop_sp = m_break_loc_collection[i];
 | 
						|
 | 
						|
  return stop_sp;
 | 
						|
}
 | 
						|
 | 
						|
const BreakpointLocationSP
 | 
						|
BreakpointLocationCollection::GetByIndex(size_t i) const {
 | 
						|
  std::lock_guard<std::mutex> guard(m_collection_mutex);
 | 
						|
  BreakpointLocationSP stop_sp;
 | 
						|
  if (i < m_break_loc_collection.size())
 | 
						|
    stop_sp = m_break_loc_collection[i];
 | 
						|
 | 
						|
  return stop_sp;
 | 
						|
}
 | 
						|
 | 
						|
bool BreakpointLocationCollection::ShouldStop(
 | 
						|
    StoppointCallbackContext *context) {
 | 
						|
  bool shouldStop = false;
 | 
						|
  size_t i = 0;
 | 
						|
  size_t prev_size = GetSize();
 | 
						|
  while (i < prev_size) {
 | 
						|
    // ShouldStop can remove the breakpoint from the list
 | 
						|
    if (GetByIndex(i)->ShouldStop(context))
 | 
						|
      shouldStop = true;
 | 
						|
 | 
						|
    if (prev_size == GetSize())
 | 
						|
      i++;
 | 
						|
    prev_size = GetSize();
 | 
						|
  }
 | 
						|
  return shouldStop;
 | 
						|
}
 | 
						|
 | 
						|
bool BreakpointLocationCollection::ValidForThisThread(Thread *thread) {
 | 
						|
  std::lock_guard<std::mutex> guard(m_collection_mutex);
 | 
						|
  collection::iterator pos, begin = m_break_loc_collection.begin(),
 | 
						|
                            end = m_break_loc_collection.end();
 | 
						|
 | 
						|
  for (pos = begin; pos != end; ++pos) {
 | 
						|
    if ((*pos)->ValidForThisThread(thread))
 | 
						|
      return true;
 | 
						|
  }
 | 
						|
  return false;
 | 
						|
}
 | 
						|
 | 
						|
bool BreakpointLocationCollection::IsInternal() const {
 | 
						|
  std::lock_guard<std::mutex> guard(m_collection_mutex);
 | 
						|
  collection::const_iterator pos, begin = m_break_loc_collection.begin(),
 | 
						|
                                  end = m_break_loc_collection.end();
 | 
						|
 | 
						|
  bool is_internal = true;
 | 
						|
 | 
						|
  for (pos = begin; pos != end; ++pos) {
 | 
						|
    if (!(*pos)->GetBreakpoint().IsInternal()) {
 | 
						|
      is_internal = false;
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return is_internal;
 | 
						|
}
 | 
						|
 | 
						|
void BreakpointLocationCollection::GetDescription(
 | 
						|
    Stream *s, lldb::DescriptionLevel level) {
 | 
						|
  std::lock_guard<std::mutex> guard(m_collection_mutex);
 | 
						|
  collection::iterator pos, begin = m_break_loc_collection.begin(),
 | 
						|
                            end = m_break_loc_collection.end();
 | 
						|
 | 
						|
  for (pos = begin; pos != end; ++pos) {
 | 
						|
    if (pos != begin)
 | 
						|
      s->PutChar(' ');
 | 
						|
    (*pos)->GetDescription(s, level);
 | 
						|
  }
 | 
						|
}
 |