<commit_before>// g++ -o glxtest glxtest.cpp -lX11 -lGL
// g++ glxcontext.cpp -lX11 -lGL -I/usr/include/python2.7 -lpython2.7 -lboost_python -DPYTHON_WRAPPER -shared -fPIC -o glxcontext.so

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <exception>
#include <string>
#include <sstream>
#include <vector>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/gl.h>
#include <GL/glx.h>

#ifdef PYTHON_WRAPPER
#include <boost/python.hpp>
#endif

#define GLX_CONTEXT_MAJOR_VERSION_ARB       0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB       0x2092
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);

std::vector<std::pair<int, int> > get_default_context_attribs() {
	std::vector<std::pair<int, int> > context_attribs;
	context_attribs.push_back(std::pair<int, int>(GLX_CONTEXT_MAJOR_VERSION_ARB, 4));
	context_attribs.push_back(std::pair<int, int>(GLX_CONTEXT_MINOR_VERSION_ARB, 0));
	context_attribs.push_back(std::pair<int, int>(GLX_CONTEXT_FLAGS_ARB,
				GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | GLX_CONTEXT_CORE_PROFILE_BIT_ARB));
	return context_attribs;
}

const std::vector<std::pair<int, int> > default_context_attribs = get_default_context_attribs();

class GLXError: virtual public std::exception {
	public:
		GLXError(const std::string &message="unknown error") throw(): message(message) {}
		virtual ~GLXError() throw() {}
		virtual const char *what() const throw() { return message.c_str(); }
	private:
		const std::string message;
};

class Context {
	public:
		Context(const std::string &display_name=":0.0", const std::vector<std::pair<int, int> > &context_attribs=default_context_attribs);
		Context(const Context &other);
		~Context();
		void bind();
		bool is_direct() const;
	private:

		void error(const char *message);
		bool has_glx_extension(const char *name);

		int *refcount;
		int (*old_error_handler)(Display*, XErrorEvent*);
		Display *display;
		int glx_major, glx_minor;
		int num_fb_configs;
		GLXFBConfig *fb_configs;
		GLXPbuffer pbuffer;
		glXCreateContextAttribsARBProc glXCreateContextAttribsARB;
		GLXContext old_context;
		GLXDrawable old_drawable;
		GLXDrawable old_read_drawable;
		GLXContext context;
};

static int error_handler(Display *display, XErrorEvent *event) {
	char buffer[2048];
	XGetErrorText(display, event->error_code, buffer, sizeof(buffer));
	throw GLXError(buffer);
	return 0;
}

bool Context::has_glx_extension(const char *name) {
	const char *extensions = glXQueryExtensionsString(display, DefaultScreen(display));
	std::istringstream s(extensions);
	std::string sub;
	while (s) {
		s >> sub;
		if (sub == name) return true;
	}
	return false;
}

Context::Context(const Context &other):
	refcount(other.refcount),
	display(other.display),
	glx_major(other.glx_major),
	glx_minor(other.glx_minor),
	num_fb_configs(other.num_fb_configs),
	fb_configs(other.fb_configs),
	glXCreateContextAttribsARB(other.glXCreateContextAttribsARB),
	old_context(other.old_context),
	context(other.context)
{
	(*refcount)++;
}

Context::Context(const std::string &display_name, const std::vector<std::pair<int, int> > &context_attribs):
	refcount(new int(1)),
	display(NULL),
	glx_major(0),
	glx_minor(0),
	num_fb_configs(0),
	fb_configs(NULL),
	glXCreateContextAttribsARB(NULL),
	old_context(NULL),
	context(NULL)
{
	int context_attribs_array[2 * context_attribs.size() + 1];
	for (size_t i = 0; i < context_attribs.size(); ++i) {
		context_attribs_array[2 * i] = context_attribs[i].first;
		context_attribs_array[2 * i + 1] = context_attribs[i].second;
	}
	context_attribs_array[2 * context_attribs.size()] = None;

	const int attrib_list[] = {
		None
	};

	old_error_handler = XSetErrorHandler(&error_handler);

	if ((display = XOpenDisplay(display_name.c_str())) == NULL)
		throw GLXError("could not open X display");
	if (!glXQueryVersion(display, &glx_major, &glx_minor))
		throw GLXError("could not get GLX version");
	if (((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1))
		throw GLXError("need at least GLX 1.3");
	if (!(fb_configs = glXChooseFBConfig(display, DefaultScreen(display), attrib_list, &num_fb_configs)))
		throw GLXError("could not determine valid framebuffer configurations");
	if (!num_fb_configs)
		throw GLXError("no valid framebuffer configurations");
	if (!(pbuffer = glXCreatePbuffer(display, fb_configs[0], attrib_list)))
		throw GLXError("could not create pixel buffer");

	old_context = glXGetCurrentContext();
	old_drawable = glXGetCurrentDrawable();
	old_read_drawable = glXGetCurrentReadDrawable();

	if (!has_glx_extension("GLX_ARB_create_context"))
		throw GLXError("could not find GLX_ARB_create_context extension");
	if (!(glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB")))
		throw GLXError("could not find glXCreateContextAttribsARB");
	if (!(context = glXCreateContextAttribsARB(display, fb_configs[0], 0, True, context_attribs_array)))
		throw GLXError("could not create GLX context");
}

void Context::bind() {
	if (!(glXMakeContextCurrent(display, pbuffer, pbuffer, context)))
		throw GLXError("could not make GLX context current");
}

bool Context::is_direct() const {
	return glXIsDirect(display, context);
}

Context::~Context() {
	(*refcount)--;
	if (!refcount) {
		if (display && old_context)
			glXMakeContextCurrent(display, old_drawable, old_read_drawable, old_context);
		if (display && context)
			glXDestroyContext(display, context);
		if (display)
			glXDestroyPbuffer(display, pbuffer);
		if (fb_configs)
			XFree(fb_configs);
		if (display)
			XCloseDisplay(display);
		XSetErrorHandler(old_error_handler);
		delete refcount;
	}
}

#ifdef PYTHON_WRAPPER
using namespace boost::python;

PyObject *type_GLXError = NULL;

void translateGLXError(GLXError const &e) {
	PyErr_SetString(type_GLXError, e.what());
}

PyObject* createExceptionClass(const char* name, PyObject* baseTypeObj=PyExc_Exception) {
	std::string scopeName = extract<std::string>(scope().attr("__name__"));
	std::string qualifiedName0 = scopeName + "." + name;
	char* qualifiedName1 = const_cast<char*>(qualifiedName0.c_str());

	PyObject* typeObj = PyErr_NewException(qualifiedName1, baseTypeObj, 0);
	if(!typeObj) throw_error_already_set();
	scope().attr(name) = handle<>(borrowed(typeObj));
	return typeObj;
}

BOOST_PYTHON_MODULE(glxcontext) {
	type_GLXError = createExceptionClass("GLXError");
	register_exception_translator<GLXError>(translateGLXError);

	class_<Context>("GLXContext",
			init<optional<const std::string &, const std::vector<std::pair<int, int> > &> >(
				// TODO translator for vector<pair<int, int> > from kwargs
				args("display_name", "context_attribs"),
				"Create a new GLX context.")
			)
		.add_property("is_direct", &Context::is_direct)
		;
}
#else
int main(int argc, const char *argv[]) {
	Context context;

	glClearColor(1.0, 1.0, 0.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT);
	glFlush();

	return 0;
}
#endif

<commit_msg>add bind to python interface<commit_after>// g++ -o glxtest glxtest.cpp -lX11 -lGL
// g++ glxcontext.cpp -lX11 -lGL -I/usr/include/python2.7 -lpython2.7 -lboost_python -DPYTHON_WRAPPER -shared -fPIC -o glxcontext.so

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <exception>
#include <string>
#include <sstream>
#include <vector>

#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <GL/gl.h>
#include <GL/glx.h>

#ifdef PYTHON_WRAPPER
#include <boost/python.hpp>
#endif

#define GLX_CONTEXT_MAJOR_VERSION_ARB       0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB       0x2092
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);

std::vector<std::pair<int, int> > get_default_context_attribs() {
	std::vector<std::pair<int, int> > context_attribs;
	context_attribs.push_back(std::pair<int, int>(GLX_CONTEXT_MAJOR_VERSION_ARB, 4));
	context_attribs.push_back(std::pair<int, int>(GLX_CONTEXT_MINOR_VERSION_ARB, 0));
	context_attribs.push_back(std::pair<int, int>(GLX_CONTEXT_FLAGS_ARB,
				GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB | GLX_CONTEXT_CORE_PROFILE_BIT_ARB));
	return context_attribs;
}

const std::vector<std::pair<int, int> > default_context_attribs = get_default_context_attribs();

class GLXError: virtual public std::exception {
	public:
		GLXError(const std::string &message="unknown error") throw(): message(message) {}
		virtual ~GLXError() throw() {}
		virtual const char *what() const throw() { return message.c_str(); }
	private:
		const std::string message;
};

class Context {
	public:
		Context(const std::string &display_name=":0.0", const std::vector<std::pair<int, int> > &context_attribs=default_context_attribs);
		Context(const Context &other);
		~Context();
		void bind();
		bool is_direct() const;
	private:

		void error(const char *message);
		bool has_glx_extension(const char *name);

		int *refcount;
		int (*old_error_handler)(Display*, XErrorEvent*);
		Display *display;
		int glx_major, glx_minor;
		int num_fb_configs;
		GLXFBConfig *fb_configs;
		GLXPbuffer pbuffer;
		glXCreateContextAttribsARBProc glXCreateContextAttribsARB;
		GLXContext old_context;
		GLXDrawable old_drawable;
		GLXDrawable old_read_drawable;
		GLXContext context;
};

static int error_handler(Display *display, XErrorEvent *event) {
	char buffer[2048];
	XGetErrorText(display, event->error_code, buffer, sizeof(buffer));
	throw GLXError(buffer);
	return 0;
}

bool Context::has_glx_extension(const char *name) {
	const char *extensions = glXQueryExtensionsString(display, DefaultScreen(display));
	std::istringstream s(extensions);
	std::string sub;
	while (s) {
		s >> sub;
		if (sub == name) return true;
	}
	return false;
}

Context::Context(const Context &other):
	refcount(other.refcount),
	display(other.display),
	glx_major(other.glx_major),
	glx_minor(other.glx_minor),
	num_fb_configs(other.num_fb_configs),
	fb_configs(other.fb_configs),
	glXCreateContextAttribsARB(other.glXCreateContextAttribsARB),
	old_context(other.old_context),
	context(other.context)
{
	(*refcount)++;
}

Context::Context(const std::string &display_name, const std::vector<std::pair<int, int> > &context_attribs):
	refcount(new int(1)),
	display(NULL),
	glx_major(0),
	glx_minor(0),
	num_fb_configs(0),
	fb_configs(NULL),
	glXCreateContextAttribsARB(NULL),
	old_context(NULL),
	context(NULL)
{
	int context_attribs_array[2 * context_attribs.size() + 1];
	for (size_t i = 0; i < context_attribs.size(); ++i) {
		context_attribs_array[2 * i] = context_attribs[i].first;
		context_attribs_array[2 * i + 1] = context_attribs[i].second;
	}
	context_attribs_array[2 * context_attribs.size()] = None;

	const int attrib_list[] = {
		None
	};

	old_error_handler = XSetErrorHandler(&error_handler);

	if ((display = XOpenDisplay(display_name.c_str())) == NULL)
		throw GLXError("could not open X display");
	if (!glXQueryVersion(display, &glx_major, &glx_minor))
		throw GLXError("could not get GLX version");
	if (((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1))
		throw GLXError("need at least GLX 1.3");
	if (!(fb_configs = glXChooseFBConfig(display, DefaultScreen(display), attrib_list, &num_fb_configs)))
		throw GLXError("could not determine valid framebuffer configurations");
	if (!num_fb_configs)
		throw GLXError("no valid framebuffer configurations");
	if (!(pbuffer = glXCreatePbuffer(display, fb_configs[0], attrib_list)))
		throw GLXError("could not create pixel buffer");

	old_context = glXGetCurrentContext();
	old_drawable = glXGetCurrentDrawable();
	old_read_drawable = glXGetCurrentReadDrawable();

	if (!has_glx_extension("GLX_ARB_create_context"))
		throw GLXError("could not find GLX_ARB_create_context extension");
	if (!(glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((const GLubyte*)"glXCreateContextAttribsARB")))
		throw GLXError("could not find glXCreateContextAttribsARB");
	if (!(context = glXCreateContextAttribsARB(display, fb_configs[0], 0, True, context_attribs_array)))
		throw GLXError("could not create GLX context");
}

void Context::bind() {
	if (!(glXMakeContextCurrent(display, pbuffer, pbuffer, context)))
		throw GLXError("could not make GLX context current");
}

bool Context::is_direct() const {
	return glXIsDirect(display, context);
}

Context::~Context() {
	(*refcount)--;
	if (!refcount) {
		if (display && old_context)
			glXMakeContextCurrent(display, old_drawable, old_read_drawable, old_context);
		if (display && context)
			glXDestroyContext(display, context);
		if (display)
			glXDestroyPbuffer(display, pbuffer);
		if (fb_configs)
			XFree(fb_configs);
		if (display)
			XCloseDisplay(display);
		XSetErrorHandler(old_error_handler);
		delete refcount;
	}
}

#ifdef PYTHON_WRAPPER
using namespace boost::python;

PyObject *type_GLXError = NULL;

void translateGLXError(GLXError const &e) {
	PyErr_SetString(type_GLXError, e.what());
}

PyObject* createExceptionClass(const char* name, PyObject* baseTypeObj=PyExc_Exception) {
	std::string scopeName = extract<std::string>(scope().attr("__name__"));
	std::string qualifiedName0 = scopeName + "." + name;
	char* qualifiedName1 = const_cast<char*>(qualifiedName0.c_str());

	PyObject* typeObj = PyErr_NewException(qualifiedName1, baseTypeObj, 0);
	if(!typeObj) throw_error_already_set();
	scope().attr(name) = handle<>(borrowed(typeObj));
	return typeObj;
}

BOOST_PYTHON_MODULE(glxcontext) {
	type_GLXError = createExceptionClass("GLXError");
	register_exception_translator<GLXError>(translateGLXError);

	class_<Context>("GLXContext",
			init<optional<const std::string &, const std::vector<std::pair<int, int> > &> >(
				// TODO translator for vector<pair<int, int> > from kwargs
				args("display_name", "context_attribs"),
				"Create a new GLX context.")
			)
		.add_property("is_direct", &Context::is_direct)
		.def("bind", &Context::bind)
		;
}
#else
int main(int argc, const char *argv[]) {
	Context context;

	glClearColor(1.0, 1.0, 0.0, 1.0);
	glClear(GL_COLOR_BUFFER_BIT);
	glFlush();

	return 0;
}
#endif

<|endoftext|>


<commit_before>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkConnectomicsNetworkThresholder.h"
#include <mitkConnectomicsStatisticsCalculator.h>
#include "vnl/vnl_random.h"

mitk::ConnectomicsNetworkThresholder::ConnectomicsNetworkThresholder()
  : m_Network( 0 )
  , m_ThresholdingScheme( mitk::ConnectomicsNetworkThresholder::ThresholdBased )
  , m_TargetThreshold( 0.0 )
  , m_TargetDensity( 1.0 )
{
}

mitk::ConnectomicsNetworkThresholder::~ConnectomicsNetworkThresholder()
{
}

mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkThresholder::GetThresholdedNetwork()
{
  mitk::ConnectomicsNetwork::Pointer result;

  if( ! CheckValidity() )
  {
    MITK_ERROR << "Aborting";
    return m_Network;
  }

  switch(m_ThresholdingScheme)
  {
  case RandomRemovalOfWeakest :
    {
      result = ThresholdByRandomRemoval( m_Network, m_TargetDensity );
      break;
    }
  case LargestLowerThanDensity :
    {
      result = ThresholdBelowDensity( m_Network, m_TargetDensity );
      break;
    }
  case ThresholdBased :
    {
      result = Threshold( m_Network, m_TargetThreshold );
      break;
    }
  default :
    {
      MITK_ERROR << "Specified unknown Thresholding Scheme";
      result = m_Network;
    }
  }

  return result;
}

bool mitk::ConnectomicsNetworkThresholder::CheckValidity()
{
  bool valid(true);

  if( m_Network.IsNull() )
  {
    valid = false;
    MITK_ERROR << "Network is NULL.";
  }

  switch(m_ThresholdingScheme)
  {
  case RandomRemovalOfWeakest :
  case LargestLowerThanDensity :
    {
      if( m_TargetDensity < 0.0 )
      {
        valid = false;
        MITK_ERROR << "Target density is negative.";
      }
      if( m_TargetDensity > 1.0 )
      {
        valid = false;
        MITK_ERROR << "Target density is larger than 1.";
      }
      break;
    }
  case ThresholdBased :
    {
      if( m_TargetThreshold < 0 )
      {
        valid = false;
        MITK_ERROR << "Target threshold is negative.";
      }
      break;
    }
  default :
    {
      valid = false;
      MITK_ERROR << "Specified unknown Thresholding Scheme";
    }
  }

  return valid;
}

mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkThresholder::ThresholdByRandomRemoval( mitk::ConnectomicsNetwork::Pointer input, double targetDensity )
{
  mitk::ConnectomicsNetwork::Pointer result = mitk::ConnectomicsNetwork::New();
  result->ImportNetwort( input );

  mitk::ConnectomicsStatisticsCalculator::Pointer calculator = mitk::ConnectomicsStatisticsCalculator::New();

  calculator->SetNetwork( result );
  calculator->Update();

  //the random number generator
  vnl_random rng( (unsigned int) rand() );

  bool notBelow( targetDensity < calculator->GetConnectionDensity() );

  double minWeight( result->GetMaximumWeight() );
  int count( 0 );

  while( notBelow )
  {
 //   result = Threshold( result, loop );
    std::vector< EdgeDescriptorType > candidateVector;

    // determine minimum weight and number of edges having that weight
    NetworkType* boostGraph = result->GetBoostGraph();
    EdgeIteratorType iterator, end;
    // sets iterator to start end end to end
    boost::tie(iterator, end) = boost::edges( *boostGraph );

    for ( ; iterator != end; ++iterator)
    {
      double tempWeight;

      // the value of an iterator is a descriptor
      tempWeight = (*boostGraph)[ *iterator ].weight;

      if( mitk::Equal( tempWeight, minWeight ) )
      {
        candidateVector.push_back( *iterator );
        count++;
      }
      else if( tempWeight < minWeight )
      {
        candidateVector.clear();
        candidateVector.push_back( *iterator );
        minWeight = tempWeight;
        count = 1;
      }
    }

    // Which to delete
    int deleteNumber( rng.lrand32( count - 1 ) );

    boost::remove_edge( candidateVector.at( deleteNumber ), *boostGraph );

    calculator->SetNetwork( result );
    calculator->Update();
    notBelow = targetDensity < calculator->GetConnectionDensity();
  }

  result->UpdateIDs();
  return result;
}

mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkThresholder::ThresholdBelowDensity( mitk::ConnectomicsNetwork::Pointer input, double targetDensity )
{
  mitk::ConnectomicsNetwork::Pointer result = mitk::ConnectomicsNetwork::New();
  result->ImportNetwort( input );

  mitk::ConnectomicsStatisticsCalculator::Pointer calculator = mitk::ConnectomicsStatisticsCalculator::New();

  calculator->SetNetwork( result );
  calculator->Update();

  bool notBelow( targetDensity < calculator->GetConnectionDensity() );

  for( int loop( 1 ); notBelow; loop++ )
  {
    result = Threshold( result, loop );
    calculator->SetNetwork( result );
    calculator->Update();
    notBelow = targetDensity < calculator->GetConnectionDensity();
  }

  return result;
}

mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkThresholder::Threshold( mitk::ConnectomicsNetwork::Pointer input, double targetThreshold )
{
  mitk::ConnectomicsNetwork::Pointer result = mitk::ConnectomicsNetwork::New();
  result->ImportNetwort( input );

  NetworkType* boostGraph = result->GetBoostGraph();

  EdgeIteratorType iterator, end;

  // set to true if iterators are invalidated by deleting an edge
  bool edgeHasBeenRemoved( true );

  // if no edge has been removed in the last loop, we are done
  while( edgeHasBeenRemoved )
  {
    edgeHasBeenRemoved = false;
    // sets iterator to start and end to end
    boost::tie(iterator, end) = boost::edges( *boostGraph );

    bool endReached( false );
    while( !edgeHasBeenRemoved && !endReached )
    {
      if( iterator != end )
      {
        // If the edge is below the target threshold it is deleted
        if( (*boostGraph)[ *iterator ].weight < targetThreshold )
        {
          edgeHasBeenRemoved = true;
          // this invalidates all iterators
          boost::remove_edge( *iterator, *boostGraph );
        }
        else
        {
          ++iterator;
        }
      }
      else
      {
        endReached = true;
      }
    }
  }

  result->UpdateIDs();

  return result;
}
<commit_msg>Properly initialize variables<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkConnectomicsNetworkThresholder.h"
#include <mitkConnectomicsStatisticsCalculator.h>
#include "vnl/vnl_random.h"

mitk::ConnectomicsNetworkThresholder::ConnectomicsNetworkThresholder()
  : m_Network( 0 )
  , m_ThresholdingScheme( mitk::ConnectomicsNetworkThresholder::ThresholdBased )
  , m_TargetThreshold( 0.0 )
  , m_TargetDensity( 1.0 )
{
}

mitk::ConnectomicsNetworkThresholder::~ConnectomicsNetworkThresholder()
{
}

mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkThresholder::GetThresholdedNetwork()
{
  mitk::ConnectomicsNetwork::Pointer result;

  if( ! CheckValidity() )
  {
    MITK_ERROR << "Aborting";
    return m_Network;
  }

  switch(m_ThresholdingScheme)
  {
  case RandomRemovalOfWeakest :
    {
      result = ThresholdByRandomRemoval( m_Network, m_TargetDensity );
      break;
    }
  case LargestLowerThanDensity :
    {
      result = ThresholdBelowDensity( m_Network, m_TargetDensity );
      break;
    }
  case ThresholdBased :
    {
      result = Threshold( m_Network, m_TargetThreshold );
      break;
    }
  default :
    {
      MITK_ERROR << "Specified unknown Thresholding Scheme";
      result = m_Network;
    }
  }

  return result;
}

bool mitk::ConnectomicsNetworkThresholder::CheckValidity()
{
  bool valid(true);

  if( m_Network.IsNull() )
  {
    valid = false;
    MITK_ERROR << "Network is NULL.";
  }

  switch(m_ThresholdingScheme)
  {
  case RandomRemovalOfWeakest :
  case LargestLowerThanDensity :
    {
      if( m_TargetDensity < 0.0 )
      {
        valid = false;
        MITK_ERROR << "Target density is negative.";
      }
      if( m_TargetDensity > 1.0 )
      {
        valid = false;
        MITK_ERROR << "Target density is larger than 1.";
      }
      break;
    }
  case ThresholdBased :
    {
      if( m_TargetThreshold < 0 )
      {
        valid = false;
        MITK_ERROR << "Target threshold is negative.";
      }
      break;
    }
  default :
    {
      valid = false;
      MITK_ERROR << "Specified unknown Thresholding Scheme";
    }
  }

  return valid;
}

mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkThresholder::ThresholdByRandomRemoval( mitk::ConnectomicsNetwork::Pointer input, double targetDensity )
{
  mitk::ConnectomicsNetwork::Pointer result = mitk::ConnectomicsNetwork::New();
  result->ImportNetwort( input );

  mitk::ConnectomicsStatisticsCalculator::Pointer calculator = mitk::ConnectomicsStatisticsCalculator::New();

  calculator->SetNetwork( result );
  calculator->Update();

  //the random number generator
  vnl_random rng( (unsigned int) rand() );

  bool notBelow( targetDensity < calculator->GetConnectionDensity() );

  double minWeight( result->GetMaximumWeight() );
  int count( 0 );

  while( notBelow )
  {
 //   result = Threshold( result, loop );
    std::vector< EdgeDescriptorType > candidateVector;
    minWeight = result->GetMaximumWeight();
    count = 0;

    // determine minimum weight and number of edges having that weight
    NetworkType* boostGraph = result->GetBoostGraph();
    EdgeIteratorType iterator, end;
    // sets iterator to start end end to end
    boost::tie(iterator, end) = boost::edges( *boostGraph );

    for ( ; iterator != end; ++iterator)
    {
      double tempWeight;

      // the value of an iterator is a descriptor
      tempWeight = (*boostGraph)[ *iterator ].weight;

      if( mitk::Equal( tempWeight, minWeight ) )
      {
        candidateVector.push_back( *iterator );
        count++;
      }
      else if( tempWeight < minWeight )
      {
        candidateVector.clear();
        candidateVector.push_back( *iterator );
        minWeight = tempWeight;
        count = 1;
      }
    }

    // Which to delete
    int deleteNumber( rng.lrand32( count - 1 ) );

    boost::remove_edge( candidateVector.at( deleteNumber ), *boostGraph );

    calculator->SetNetwork( result );
    calculator->Update();
    notBelow = targetDensity < calculator->GetConnectionDensity();
  }

  result->UpdateIDs();
  return result;
}

mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkThresholder::ThresholdBelowDensity( mitk::ConnectomicsNetwork::Pointer input, double targetDensity )
{
  mitk::ConnectomicsNetwork::Pointer result = mitk::ConnectomicsNetwork::New();
  result->ImportNetwort( input );

  mitk::ConnectomicsStatisticsCalculator::Pointer calculator = mitk::ConnectomicsStatisticsCalculator::New();

  calculator->SetNetwork( result );
  calculator->Update();

  bool notBelow( targetDensity < calculator->GetConnectionDensity() );

  for( int loop( 1 ); notBelow; loop++ )
  {
    result = Threshold( result, loop );
    calculator->SetNetwork( result );
    calculator->Update();
    notBelow = targetDensity < calculator->GetConnectionDensity();
  }

  return result;
}

mitk::ConnectomicsNetwork::Pointer mitk::ConnectomicsNetworkThresholder::Threshold( mitk::ConnectomicsNetwork::Pointer input, double targetThreshold )
{
  mitk::ConnectomicsNetwork::Pointer result = mitk::ConnectomicsNetwork::New();
  result->ImportNetwort( input );

  NetworkType* boostGraph = result->GetBoostGraph();

  EdgeIteratorType iterator, end;

  // set to true if iterators are invalidated by deleting an edge
  bool edgeHasBeenRemoved( true );

  // if no edge has been removed in the last loop, we are done
  while( edgeHasBeenRemoved )
  {
    edgeHasBeenRemoved = false;
    // sets iterator to start and end to end
    boost::tie(iterator, end) = boost::edges( *boostGraph );

    bool endReached( false );
    while( !edgeHasBeenRemoved && !endReached )
    {
      if( iterator != end )
      {
        // If the edge is below the target threshold it is deleted
        if( (*boostGraph)[ *iterator ].weight < targetThreshold )
        {
          edgeHasBeenRemoved = true;
          // this invalidates all iterators
          boost::remove_edge( *iterator, *boostGraph );
        }
        else
        {
          ++iterator;
        }
      }
      else
      {
        endReached = true;
      }
    }
  }

  result->UpdateIDs();

  return result;
}
<|endoftext|>


<commit_before>#include <cstdio>
#include <cstdlib>
#include <iostream>
#define  MAXSTRLEN  255                   // 用户可在255以内定义最大串长
typedef unsigned char SString[MAXSTRLEN+1];	// 0号单元存放串的长度

void get_next(SString T,int next[]){

	int i,j;
	next[1]=0;
	j=0;

	while(i<T[0]){

		if(j == 0 || T[i]==T[j]){
			++i;
			++j;
			next[i]=j;
		}

		else{
			j=next[j];
		}

	}
}
int  main(){
	int next[MAXSTRLEN];
	SString S;
	int n,i,j;
	char ch;
	scanf("%d",&n);    // 指定要验证NEXT值的字符串个数
	ch=getchar();
	for(i=1;i<=n;i++)
	{
		ch=getchar();
		for(j=1;j<=MAXSTRLEN&&(ch!='\n');j++)    // 录入字符串
		{
			S[j]=ch;
			ch=getchar();
		}
		S[0]=j-1;
		S[j]=0;   // S[0]用于存储字符串中字符个数
		printf("%s\n",S+1);
		get_next(S,next);
		printf("%d",j);
		printf("NEXT J is:");
		for(j=1;j<=S[0];j++)
			printf("%d\n",*next[j]);
		printf("\n");
	}
}

<commit_msg>update uoj8591<commit_after>#include <cstdio>
#include <cstdlib>
#include <iostream>
#define  MAXSTRLEN  255                   // 用户可在255以内定义最大串长
typedef unsigned char SString[MAXSTRLEN+1];	// 0号单元存放串的长度

void get_next(SString T,int next[]){

	int i,j;
	next[1]=0;
	j=0;

	while(i<T[0]){

		if(j == 0 || T[i]==T[j]){
			++i;
			++j;
			next[i]=j;
		}

		else{
			j=next[j];
		}

	}
}
int  main(){
	int next[MAXSTRLEN];
	SString S;
	int n,i,j;
	char ch;
	scanf("%d",&n);    // 指定要验证NEXT值的字符串个数
	ch=getchar();
	for(i=1;i<=n;i++)
	{
		ch=getchar();
		for(j=1;j<=MAXSTRLEN&&(ch!='\n');j++)    // 录入字符串
		{
			S[j]=ch;
			ch=getchar();
		}
		S[0]=j-1;
		S[j]=0;   // S[0]用于存储字符串中字符个数
		printf("%s\n",S+1);
		get_next(S,next);
		printf("%d",j);
		printf("NEXT J is:");
		for(j=1;j<=S[0];j++)
			printf("%d\n",next[j]);
		printf("\n");
	}
}

<|endoftext|>


<commit_before>// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both bitcoind and bitcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("Satoshi");

// Client version number
#define CLIENT_VERSION_SUFFIX   "-POS-test"

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID ""
#    define GIT_COMMIT_DATE ""
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE GIT_COMMIT_DATE
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<commit_msg>Update version.cpp<commit_after>// Copyright (c) 2012 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <string>

#include "version.h"

// Name of client reported in the 'version' message. Report the same name
// for both bitcoind and bitcoin-qt, to make it harder for attackers to
// target servers or GUI users specifically.
const std::string CLIENT_NAME("Satoshi");

// Client version number
#define CLIENT_VERSION_SUFFIX   "-POS"

// The following part of the code determines the CLIENT_BUILD variable.
// Several mechanisms are used for this:
// * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
//   generated by the build environment, possibly containing the output
//   of git-describe in a macro called BUILD_DESC
// * secondly, if this is an exported version of the code, GIT_ARCHIVE will
//   be defined (automatically using the export-subst git attribute), and
//   GIT_COMMIT will contain the commit id.
// * then, three options exist for determining CLIENT_BUILD:
//   * if BUILD_DESC is defined, use that literally (output of git-describe)
//   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
//   * otherwise, use v[maj].[min].[rev].[build]-unk
// finally CLIENT_VERSION_SUFFIX is added

// First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#    include "build.h"
#endif

// git will put "#define GIT_ARCHIVE 1" on the next line inside archives.
#define GIT_ARCHIVE 1
#ifdef GIT_ARCHIVE
#    define GIT_COMMIT_ID ""
#    define GIT_COMMIT_DATE ""
#endif

#define BUILD_DESC_FROM_COMMIT(maj,min,rev,build,commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit

#define BUILD_DESC_FROM_UNKNOWN(maj,min,rev,build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#    ifdef GIT_COMMIT_ID
#        define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID)
#    else
#        define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD)
#    endif
#endif

#ifndef BUILD_DATE
#    ifdef GIT_COMMIT_DATE
#        define BUILD_DATE GIT_COMMIT_DATE
#    else
#        define BUILD_DATE __DATE__ ", " __TIME__
#    endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);
const std::string CLIENT_DATE(BUILD_DATE);
<|endoftext|>


<commit_before>//===- AliasAnalysis.cpp - Generic Alias Analysis Interface Implementation -==//
//
// This file implements the generic AliasAnalysis interface which is used as the
// common interface used by all clients and implementations of alias analysis.
//
// This file also implements the default version of the AliasAnalysis interface
// that is to be used when no other implementation is specified.  This does some
// simple tests that detect obvious cases: two different global pointers cannot
// alias, a global cannot alias a malloc, two different mallocs cannot alias,
// etc.
//
// This alias analysis implementation really isn't very good for anything, but
// it is very fast, and makes a nice clean default implementation.  Because it
// handles lots of little corner cases, other, more complex, alias analysis
// implementations may choose to rely on this pass to resolve these simple and
// easy cases.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/BasicBlock.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/iMemory.h"
#include "llvm/iOther.h"
#include "llvm/Constants.h"
#include "llvm/GlobalValue.h"
#include "llvm/DerivedTypes.h"

// Register the AliasAnalysis interface, providing a nice name to refer to.
namespace {
  RegisterAnalysisGroup<AliasAnalysis> Z("Alias Analysis");
}

// CanModify - Define a little visitor class that is used to check to see if
// arbitrary chunks of code can modify a specified pointer.
//
namespace {
  struct CanModify : public InstVisitor<CanModify, bool> {
    AliasAnalysis &AA;
    const Value *Ptr;

    CanModify(AliasAnalysis *aa, const Value *ptr)
      : AA(*aa), Ptr(ptr) {}

    bool visitInvokeInst(InvokeInst &II) {
      return AA.canInvokeModify(II, Ptr);
    }
    bool visitCallInst(CallInst &CI) {
      return AA.canCallModify(CI, Ptr);
    }
    bool visitStoreInst(StoreInst &SI) {
      return AA.alias(Ptr, SI.getOperand(1));
    }

    // Other instructions do not alias anything.
    bool visitInstruction(Instruction &I) { return false; }
  };
}

// AliasAnalysis destructor: DO NOT move this to the header file for
// AliasAnalysis or else clients of the AliasAnalysis class may not depend on
// the AliasAnalysis.o file in the current .a file, causing alias analysis
// support to not be included in the tool correctly!
//
AliasAnalysis::~AliasAnalysis() {}

/// canBasicBlockModify - Return true if it is possible for execution of the
/// specified basic block to modify the value pointed to by Ptr.
///
bool AliasAnalysis::canBasicBlockModify(const BasicBlock &bb,
                                        const Value *Ptr) {
  CanModify CM(this, Ptr);
  BasicBlock &BB = const_cast<BasicBlock&>(bb);

  for (BasicBlock::iterator I = BB.begin(), E = BB.end(); I != E; ++I)
    if (CM.visit(I))        // Check every instruction in the basic block...
      return true;

  return false;
}

/// canInstructionRangeModify - Return true if it is possible for the execution
/// of the specified instructions to modify the value pointed to by Ptr.  The
/// instructions to consider are all of the instructions in the range of [I1,I2]
/// INCLUSIVE.  I1 and I2 must be in the same basic block.
///
bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1,
                                              const Instruction &I2,
                                              const Value *Ptr) {
  assert(I1.getParent() == I2.getParent() &&
         "Instructions not in same basic block!");
  CanModify CM(this, Ptr);
  BasicBlock::iterator I = const_cast<Instruction*>(&I1);
  BasicBlock::iterator E = const_cast<Instruction*>(&I2);
  ++E;  // Convert from inclusive to exclusive range.

  for (; I != E; ++I)
    if (CM.visit(I))        // Check every instruction in the basic block...
      return true;

  return false;
}

//===----------------------------------------------------------------------===//
// BasicAliasAnalysis Pass Implementation
//===----------------------------------------------------------------------===//
//
// Because of the way .a files work, the implementation of the
// BasicAliasAnalysis class MUST be in the AliasAnalysis file itself, or else we
// run the risk of AliasAnalysis being used, but the default implementation not
// being linked into the tool that uses it.  As such, we register and implement
// the class here.
//
namespace {
  // Register this pass...
  RegisterOpt<BasicAliasAnalysis>
  X("basicaa", "Basic Alias Analysis (default AA impl)");

  // Declare that we implement the AliasAnalysis interface
  RegisterAnalysisGroup<AliasAnalysis, BasicAliasAnalysis, true> Y;
}  // End of anonymous namespace

// hasUniqueAddress - Return true if the
static inline bool hasUniqueAddress(const Value *V) {
  return isa<GlobalValue>(V) || isa<MallocInst>(V) || isa<AllocaInst>(V);
}

static const Value *getUnderlyingObject(const Value *V) {
  if (!isa<PointerType>(V->getType())) return 0;

  // If we are at some type of object... return it.
  if (hasUniqueAddress(V)) return V;

  // Traverse through different addressing mechanisms...
  if (const Instruction *I = dyn_cast<Instruction>(V)) {
    if (isa<CastInst>(I) || isa<GetElementPtrInst>(I))
      return getUnderlyingObject(I->getOperand(0));
  }
  return 0;
}

// alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such
// as array references.  Note that this function is heavily tail recursive.
// Hopefully we have a smart C++ compiler.  :)
//
AliasAnalysis::Result BasicAliasAnalysis::alias(const Value *V1,
                                                const Value *V2) {
  // Strip off constant pointer refs if they exist
  if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(V1))
    V1 = CPR->getValue();
  if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(V2))
    V2 = CPR->getValue();

  // Are we checking for alias of the same value?
  if (V1 == V2) return MustAlias;

  if ((!isa<PointerType>(V1->getType()) || !isa<PointerType>(V2->getType())) &&
      V1->getType() != Type::LongTy && V2->getType() != Type::LongTy)
    return NoAlias;  // Scalars cannot alias each other

  // Strip off cast instructions...
  if (const Instruction *I = dyn_cast<CastInst>(V1))
    return alias(I->getOperand(0), V2);
  if (const Instruction *I = dyn_cast<CastInst>(V2))
    return alias(V1, I->getOperand(0));

  // If we have two gep instructions with identical indices, return an alias
  // result equal to the alias result of the original pointer...
  //
  if (const GetElementPtrInst *GEP1 = dyn_cast<GetElementPtrInst>(V1))
    if (const GetElementPtrInst *GEP2 = dyn_cast<GetElementPtrInst>(V2))
      if (GEP1->getNumOperands() == GEP2->getNumOperands() &&
          GEP1->getOperand(0)->getType() == GEP2->getOperand(0)->getType()) {
        if (std::equal(GEP1->op_begin()+1, GEP1->op_end(), GEP2->op_begin()+1))
          return alias(GEP1->getOperand(0), GEP2->getOperand(0));

        // If all of the indexes to the getelementptr are constant, but
        // different (well we already know they are different), then we know
        // that there cannot be an alias here if the two base pointers DO alias.
        //
        bool AllConstant = true;
        for (unsigned i = 1, e = GEP1->getNumOperands(); i != e; ++i)
          if (!isa<Constant>(GEP1->getOperand(i)) ||
              !isa<Constant>(GEP2->getOperand(i))) {
            AllConstant = false;
            break;
          }

        // If we are all constant, then look at where the the base pointers
        // alias.  If they are known not to alias, then we are dealing with two
        // different arrays or something, so no alias is possible.  If they are
        // known to be the same object, then we cannot alias because we are
        // indexing into a different part of the object.  As usual, MayAlias
        // doesn't tell us anything.
        //
        if (AllConstant &&
            alias(GEP1->getOperand(0), GEP2->getOperand(0)) != MayAlias)
            return NoAlias;
      }

  // Figure out what objects these things are pointing to if we can...
  const Value *O1 = getUnderlyingObject(V1);
  const Value *O2 = getUnderlyingObject(V2);

  // Pointing at a discernable object?
  if (O1 && O2) {
    // If they are two different objects, we know that we have no alias...
    if (O1 != O2) return NoAlias;

    // If they are the same object, they we can look at the indexes.  If they
    // index off of the object is the same for both pointers, they must alias.
    // If they are provably different, they must not alias.  Otherwise, we can't
    // tell anything.
  } else if (O1 && isa<ConstantPointerNull>(V2)) {
    return NoAlias;                    // Unique values don't alias null
  } else if (O2 && isa<ConstantPointerNull>(V1)) {
    return NoAlias;                    // Unique values don't alias null
  }

  // Check to see if these two pointers are related by a getelementptr
  // instruction.  If one pointer is a GEP with a non-zero index of the other
  // pointer, we know they cannot alias.
  //
  if (isa<GetElementPtrInst>(V2))
    std::swap(V1, V2);

  if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V1))
    if (GEP->getOperand(0) == V2) {
      // If there is at least one non-zero constant index, we know they cannot
      // alias.
      for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
        if (const Constant *C = dyn_cast<Constant>(GEP->getOperand(i)))
          if (!C->isNullValue())
            return NoAlias;
    }

  return MayAlias;
}
<commit_msg>  - Checkin of the alias analysis work:     * Takes into account the size of the memory reference to determine aliasing.     * Expose mod/ref information in a more consistent way     * BasicAA can now disambiguate A[i][1] and A[j][2] for conservative request       sizes<commit_after>//===- AliasAnalysis.cpp - Generic Alias Analysis Interface Implementation -==//
//
// This file implements the generic AliasAnalysis interface which is used as the
// common interface used by all clients and implementations of alias analysis.
//
// This file also implements the default version of the AliasAnalysis interface
// that is to be used when no other implementation is specified.  This does some
// simple tests that detect obvious cases: two different global pointers cannot
// alias, a global cannot alias a malloc, two different mallocs cannot alias,
// etc.
//
// This alias analysis implementation really isn't very good for anything, but
// it is very fast, and makes a nice clean default implementation.  Because it
// handles lots of little corner cases, other, more complex, alias analysis
// implementations may choose to rely on this pass to resolve these simple and
// easy cases.
//
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/BasicAliasAnalysis.h"
#include "llvm/BasicBlock.h"
#include "llvm/iMemory.h"
#include "llvm/iOther.h"
#include "llvm/Constants.h"
#include "llvm/ConstantHandling.h"
#include "llvm/GlobalValue.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Target/TargetData.h"

// Register the AliasAnalysis interface, providing a nice name to refer to.
namespace {
  RegisterAnalysisGroup<AliasAnalysis> Z("Alias Analysis");
}

AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(LoadInst *L, Value *P, unsigned Size) {
  return alias(L->getOperand(0), TD->getTypeSize(L->getType()),
               P, Size) ? Ref : NoModRef;
}

AliasAnalysis::ModRefResult
AliasAnalysis::getModRefInfo(StoreInst *S, Value *P, unsigned Size) {
  return alias(S->getOperand(1), TD->getTypeSize(S->getOperand(0)->getType()),
               P, Size) ? Mod : NoModRef;
}

// AliasAnalysis destructor: DO NOT move this to the header file for
// AliasAnalysis or else clients of the AliasAnalysis class may not depend on
// the AliasAnalysis.o file in the current .a file, causing alias analysis
// support to not be included in the tool correctly!
//
AliasAnalysis::~AliasAnalysis() {}

/// setTargetData - Subclasses must call this method to initialize the
/// AliasAnalysis interface before any other methods are called.
///
void AliasAnalysis::InitializeAliasAnalysis(Pass *P) {
  TD = &P->getAnalysis<TargetData>();
}

// getAnalysisUsage - All alias analysis implementations should invoke this
// directly (using AliasAnalysis::getAnalysisUsage(AU)) to make sure that
// TargetData is required by the pass.
void AliasAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
  AU.addRequired<TargetData>();            // All AA's need TargetData.
}

/// canBasicBlockModify - Return true if it is possible for execution of the
/// specified basic block to modify the value pointed to by Ptr.
///
bool AliasAnalysis::canBasicBlockModify(const BasicBlock &BB,
                                        const Value *Ptr, unsigned Size) {
  return canInstructionRangeModify(BB.front(), BB.back(), Ptr, Size);
}

/// canInstructionRangeModify - Return true if it is possible for the execution
/// of the specified instructions to modify the value pointed to by Ptr.  The
/// instructions to consider are all of the instructions in the range of [I1,I2]
/// INCLUSIVE.  I1 and I2 must be in the same basic block.
///
bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1,
                                              const Instruction &I2,
                                              const Value *Ptr, unsigned Size) {
  assert(I1.getParent() == I2.getParent() &&
         "Instructions not in same basic block!");
  BasicBlock::iterator I = const_cast<Instruction*>(&I1);
  BasicBlock::iterator E = const_cast<Instruction*>(&I2);
  ++E;  // Convert from inclusive to exclusive range.

  for (; I != E; ++I) // Check every instruction in range
    if (getModRefInfo(I, const_cast<Value*>(Ptr), Size) & Mod)
      return true;
  return false;
}

//===----------------------------------------------------------------------===//
// BasicAliasAnalysis Pass Implementation
//===----------------------------------------------------------------------===//
//
// Because of the way .a files work, the implementation of the
// BasicAliasAnalysis class MUST be in the AliasAnalysis file itself, or else we
// run the risk of AliasAnalysis being used, but the default implementation not
// being linked into the tool that uses it.  As such, we register and implement
// the class here.
//
namespace {
  // Register this pass...
  RegisterOpt<BasicAliasAnalysis>
  X("basicaa", "Basic Alias Analysis (default AA impl)");

  // Declare that we implement the AliasAnalysis interface
  RegisterAnalysisGroup<AliasAnalysis, BasicAliasAnalysis, true> Y;
}  // End of anonymous namespace

void BasicAliasAnalysis::initializePass() {
  InitializeAliasAnalysis(this);
}

// hasUniqueAddress - Return true if the
static inline bool hasUniqueAddress(const Value *V) {
  return isa<GlobalValue>(V) || isa<MallocInst>(V) || isa<AllocaInst>(V);
}

static const Value *getUnderlyingObject(const Value *V) {
  if (!isa<PointerType>(V->getType())) return 0;

  // If we are at some type of object... return it.
  if (hasUniqueAddress(V)) return V;

  // Traverse through different addressing mechanisms...
  if (const Instruction *I = dyn_cast<Instruction>(V)) {
    if (isa<CastInst>(I) || isa<GetElementPtrInst>(I))
      return getUnderlyingObject(I->getOperand(0));
  }
  return 0;
}

// alias - Provide a bunch of ad-hoc rules to disambiguate in common cases, such
// as array references.  Note that this function is heavily tail recursive.
// Hopefully we have a smart C++ compiler.  :)
//
AliasAnalysis::AliasResult
BasicAliasAnalysis::alias(const Value *V1, unsigned V1Size,
                          const Value *V2, unsigned V2Size) {
  // Strip off constant pointer refs if they exist
  if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(V1))
    V1 = CPR->getValue();
  if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(V2))
    V2 = CPR->getValue();

  // Are we checking for alias of the same value?
  if (V1 == V2) return MustAlias;

  if ((!isa<PointerType>(V1->getType()) || !isa<PointerType>(V2->getType())) &&
      V1->getType() != Type::LongTy && V2->getType() != Type::LongTy)
    return NoAlias;  // Scalars cannot alias each other

  // Strip off cast instructions...
  if (const Instruction *I = dyn_cast<CastInst>(V1))
    return alias(I->getOperand(0), V1Size, V2, V2Size);
  if (const Instruction *I = dyn_cast<CastInst>(V2))
    return alias(V1, V1Size, I->getOperand(0), V2Size);

  // Figure out what objects these things are pointing to if we can...
  const Value *O1 = getUnderlyingObject(V1);
  const Value *O2 = getUnderlyingObject(V2);

  // Pointing at a discernable object?
  if (O1 && O2) {
    // If they are two different objects, we know that we have no alias...
    if (O1 != O2) return NoAlias;

    // If they are the same object, they we can look at the indexes.  If they
    // index off of the object is the same for both pointers, they must alias.
    // If they are provably different, they must not alias.  Otherwise, we can't
    // tell anything.
  } else if (O1 && isa<ConstantPointerNull>(V2)) {
    return NoAlias;                    // Unique values don't alias null
  } else if (O2 && isa<ConstantPointerNull>(V1)) {
    return NoAlias;                    // Unique values don't alias null
  }

  // If we have two gep instructions with identical indices, return an alias
  // result equal to the alias result of the original pointer...
  //
  if (const GetElementPtrInst *GEP1 = dyn_cast<GetElementPtrInst>(V1))
    if (const GetElementPtrInst *GEP2 = dyn_cast<GetElementPtrInst>(V2))
      if (GEP1->getNumOperands() == GEP2->getNumOperands() &&
          GEP1->getOperand(0)->getType() == GEP2->getOperand(0)->getType()) {
        AliasResult GAlias =
          CheckGEPInstructions((GetElementPtrInst*)GEP1, V1Size,
                               (GetElementPtrInst*)GEP2, V2Size);
        if (GAlias != MayAlias)
          return GAlias;
      }

  // Check to see if these two pointers are related by a getelementptr
  // instruction.  If one pointer is a GEP with a non-zero index of the other
  // pointer, we know they cannot alias.
  //
  if (isa<GetElementPtrInst>(V2)) {
    std::swap(V1, V2);
    std::swap(V1Size, V2Size);
  }

  if (const GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V1))
    if (GEP->getOperand(0) == V2) {
      // If there is at least one non-zero constant index, we know they cannot
      // alias.
      for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
        if (const Constant *C = dyn_cast<Constant>(GEP->getOperand(i)))
          if (!C->isNullValue())
            return NoAlias;
    }

  return MayAlias;
}

// CheckGEPInstructions - Check two GEP instructions of compatible types and
// equal number of arguments.  This checks to see if the index expressions
// preclude the pointers from aliasing...
//
AliasAnalysis::AliasResult
BasicAliasAnalysis::CheckGEPInstructions(GetElementPtrInst *GEP1, unsigned G1S,
                                         GetElementPtrInst *GEP2, unsigned G2S){
  // Do the base pointers alias?
  AliasResult BaseAlias = alias(GEP1->getOperand(0), G1S,
                                GEP2->getOperand(0), G2S);
  if (BaseAlias != MustAlias)   // No or May alias: We cannot add anything...
    return BaseAlias;

  // Find the (possibly empty) initial sequence of equal values...
  unsigned NumGEPOperands = GEP1->getNumOperands();
  unsigned UnequalOper = 1;
  while (UnequalOper != NumGEPOperands &&
         GEP1->getOperand(UnequalOper) == GEP2->getOperand(UnequalOper))
    ++UnequalOper;

  // If all operands equal each other, then the derived pointers must
  // alias each other...
  if (UnequalOper == NumGEPOperands) return MustAlias;

  // So now we know that the indexes derived from the base pointers,
  // which are known to alias, are different.  We can still determine a
  // no-alias result if there are differing constant pairs in the index
  // chain.  For example:
  //        A[i][0] != A[j][1] iff (&A[0][1]-&A[0][0] >= std::max(G1S, G2S))
  //
  unsigned SizeMax = std::max(G1S, G2S);
  if (SizeMax == ~0U) return MayAlias; // Avoid frivolous work...

  // Scan for the first operand that is constant and unequal in the
  // two getelemenptrs...
  unsigned FirstConstantOper = UnequalOper;
  for (; FirstConstantOper != NumGEPOperands; ++FirstConstantOper) {
    const Value *G1Oper = GEP1->getOperand(FirstConstantOper);
    const Value *G2Oper = GEP2->getOperand(FirstConstantOper);
    if (G1Oper != G2Oper &&   // Found non-equal constant indexes...
        isa<Constant>(G1Oper) && isa<Constant>(G2Oper)) {
      // Make sure they are comparable...  and make sure the GEP with
      // the smaller leading constant is GEP1.
      ConstantBool *Compare =
        *cast<Constant>(GEP1->getOperand(FirstConstantOper)) >
        *cast<Constant>(GEP2->getOperand(FirstConstantOper));
      if (Compare) {  // If they are comparable...
        if (Compare->getValue())
          std::swap(GEP1, GEP2);  // Make GEP1 < GEP2
        break;
      }
    }
  }

  // No constant operands, we cannot tell anything...
  if (FirstConstantOper == NumGEPOperands) return MayAlias;

  // If there are non-equal constants arguments, then we can figure
  // out a minimum known delta between the two index expressions... at
  // this point we know that the first constant index of GEP1 is less
  // than the first constant index of GEP2.
  //
  std::vector<Value*> Indices1;
  Indices1.reserve(NumGEPOperands-1);
  for (unsigned i = 1; i != FirstConstantOper; ++i)
    Indices1.push_back(Constant::getNullValue(GEP1->getOperand(i)
                                              ->getType()));
  std::vector<Value*> Indices2;
  Indices2.reserve(NumGEPOperands-1);
  Indices2 = Indices1;           // Copy the zeros prefix...

  // Add the two known constant operands...
  Indices1.push_back((Value*)GEP1->getOperand(FirstConstantOper));
  Indices2.push_back((Value*)GEP2->getOperand(FirstConstantOper));

  const Type *GEPPointerTy = GEP1->getOperand(0)->getType();

  // Loop over the rest of the operands...
  for (unsigned i = FirstConstantOper+1; i!=NumGEPOperands; ++i){
    const Value *Op1 = GEP1->getOperand(i);
    const Value *Op2 = GEP1->getOperand(i);
    if (Op1 == Op2) {   // If they are equal, use a zero index...
      Indices1.push_back(Constant::getNullValue(Op1->getType()));
      Indices2.push_back(Indices1.back());
    } else {
      if (isa<Constant>(Op1))
        Indices1.push_back((Value*)Op1);
      else {
        // GEP1 is known to produce a value less than GEP2.  To be
        // conservatively correct, we must assume the largest
        // possible constant is used in this position.  This cannot
        // be the initial index to the GEP instructions (because we
        // know we have at least one element before this one with
        // the different constant arguments), so we know that the
        // current index must be into either a struct or array.
        // Because of this, we can calculate the maximum value
        // possible.
        //
        const Type *ElTy = GEP1->getIndexedType(GEPPointerTy,
                                                Indices1, true);
        if (const StructType *STy = dyn_cast<StructType>(ElTy)) {
          Indices1.push_back(ConstantUInt::get(Type::UByteTy,
                                               STy->getNumContainedTypes()));
        } else {
          Indices1.push_back(ConstantSInt::get(Type::LongTy,
                                               cast<ArrayType>(ElTy)->getNumElements()));
        }
      }

      if (isa<Constant>(Op2))
        Indices2.push_back((Value*)Op2);
      else // Conservatively assume the minimum value for this index
        Indices2.push_back(Constant::getNullValue(Op1->getType()));
    }
  }

  unsigned Offset1 = getTargetData().getIndexedOffset(GEPPointerTy, Indices1);
  unsigned Offset2 = getTargetData().getIndexedOffset(GEPPointerTy, Indices2);
  assert(Offset1 < Offset2 &&"There is at least one different constant here!");

  if (Offset2-Offset1 >= SizeMax) {
    //std::cerr << "Determined that these two GEP's don't alias ["
    //          << SizeMax << " bytes]: \n" << *GEP1 << *GEP2;
    return NoAlias;
  }
  return MayAlias;
}

<|endoftext|>


<commit_before>#include "ExampleGame/Components/GameScripts/Units/PlayerUnit.h"
#include "ExampleGame/Components/Grid/GridCell.h"
#include "ExampleGame/Components/Grid/GridManager.h"
#include "ExampleGame/Components/Grid/GridNavigator.h"
#include "ExampleGame/GameSingletons/GameSingletons.h"
#include "ExampleGame/Messages/Declarations.h"
#include "Vajra/Engine/Components/DerivedComponents/Transform/Transform.h"
#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Engine/Input/Input.h"

PlayerUnit::PlayerUnit() : BaseUnit() {
	this->init();
}

PlayerUnit::PlayerUnit(Object* object_) : BaseUnit(object_) {
	this->init();
}

PlayerUnit::~PlayerUnit() {
	this->destroy();
}

void PlayerUnit::init() {
	this->unitType = UnitType::UNIT_TYPE_ASSASSIN;
	this->inputState = InputState::INPUT_STATE_WAIT;
	this->touchNearUnit = false;
	this->performingSpecial = false;

	this->moveSpeed = 2.5f;
	this->turnSpeedDegrees = 360.0f;
	this->gridNavRef->SetMovementSpeed(this->moveSpeed);
	this->gridNavRef->SetTurnSpeedDegrees(this->turnSpeedDegrees);

	this->addSubscriptionToMessageType(MESSAGE_TYPE_NAVIGATION_REACHED_DESTINATION, this->GetTypeId(), false);
}

void PlayerUnit::destroy() {
	this->removeSubscriptionToAllMessageTypes(this->GetTypeId());
}

void PlayerUnit::HandleMessage(MessageChunk messageChunk) {
	BaseUnit::HandleMessage(messageChunk);
	switch(messageChunk->GetMessageType()) {
		case MESSAGE_TYPE_NAVIGATION_REACHED_DESTINATION:
			if(this->performingSpecial) {
				onSpecialEnd();
			}
			break;
		default:
			break;
	}
}

void PlayerUnit::OnTouch(int touchId, GridCell* touchedCell) {

	if(ENGINE->GetInput()->GetTouch(touchId).phase == TouchPhase::Began) {
		this->touchStartPos = ENGINE->GetInput()->GetTouch(touchId).pos;
		this->setTouchNearUnit();
	}

	if(this->performingSpecial) {
		return;
	}

	switch(this->inputState) {
		case InputState::INPUT_STATE_WAIT:
			this->onSelectedTouch();
			break;
		case InputState::INPUT_STATE_NAV:
			this->onNavTouch(touchId, touchedCell);
			break;
		case InputState::INPUT_STATE_SPECIAL:
			this->onSpecialTouch(touchId);
			break;
		default:
			break;
	}
}

void PlayerUnit::OnDeselect() {
	this->inputState = InputState::INPUT_STATE_WAIT;
}
void PlayerUnit::onSelectedTouch() {
	this->inputState = InputState::INPUT_STATE_NAV;
}

void PlayerUnit::startSpecial() {
	this->performingSpecial = true;
	this->gridNavRef->SetDestination(this->gameObjectRef->GetTransform()->GetPosition());
}

void PlayerUnit::onSpecialEnd() {
	this->performingSpecial = false;
	this->inputState = InputState::INPUT_STATE_NAV;
}
void PlayerUnit::onNavTouch(int touchId, GridCell* touchedCell) {
	if(this->isSpecialTouch(touchId)) {
		this->inputState = InputState::INPUT_STATE_SPECIAL;
	}
	else {
		if(ENGINE->GetInput()->GetTouch(touchId).phase == TouchPhase::Ended) {
			this->gridNavRef->SetDestination(touchedCell->x, touchedCell->z);
		}
	}

}

void PlayerUnit::setTouchNearUnit() {
	glm::vec3 gridPos = SINGLETONS->GetGridManager()->TouchPositionToGridPosition(touchStartPos);
	if(glm::distance(gridPos, this->gameObjectRef->GetTransform()->GetPosition()) < 1.5f) {
		this->touchNearUnit = true;
	} else {
		this->touchNearUnit = false;
	}
}
<commit_msg>Added gridNav stop to specials to fix rotation bug<commit_after>#include "ExampleGame/Components/GameScripts/Units/PlayerUnit.h"
#include "ExampleGame/Components/Grid/GridCell.h"
#include "ExampleGame/Components/Grid/GridManager.h"
#include "ExampleGame/Components/Grid/GridNavigator.h"
#include "ExampleGame/GameSingletons/GameSingletons.h"
#include "ExampleGame/Messages/Declarations.h"
#include "Vajra/Engine/Components/DerivedComponents/Transform/Transform.h"
#include "Vajra/Engine/Core/Engine.h"
#include "Vajra/Engine/Input/Input.h"

PlayerUnit::PlayerUnit() : BaseUnit() {
	this->init();
}

PlayerUnit::PlayerUnit(Object* object_) : BaseUnit(object_) {
	this->init();
}

PlayerUnit::~PlayerUnit() {
	this->destroy();
}

void PlayerUnit::init() {
	this->unitType = UnitType::UNIT_TYPE_ASSASSIN;
	this->inputState = InputState::INPUT_STATE_WAIT;
	this->touchNearUnit = false;
	this->performingSpecial = false;

	this->moveSpeed = 2.5f;
	this->turnSpeedDegrees = 360.0f;
	this->gridNavRef->SetMovementSpeed(this->moveSpeed);
	this->gridNavRef->SetTurnSpeedDegrees(this->turnSpeedDegrees);

	this->addSubscriptionToMessageType(MESSAGE_TYPE_NAVIGATION_REACHED_DESTINATION, this->GetTypeId(), false);
}

void PlayerUnit::destroy() {
	this->removeSubscriptionToAllMessageTypes(this->GetTypeId());
}

void PlayerUnit::HandleMessage(MessageChunk messageChunk) {
	BaseUnit::HandleMessage(messageChunk);
	switch(messageChunk->GetMessageType()) {
		case MESSAGE_TYPE_NAVIGATION_REACHED_DESTINATION:
			if(this->performingSpecial) {
				onSpecialEnd();
			}
			break;
		default:
			break;
	}
}

void PlayerUnit::OnTouch(int touchId, GridCell* touchedCell) {

	if(ENGINE->GetInput()->GetTouch(touchId).phase == TouchPhase::Began) {
		this->touchStartPos = ENGINE->GetInput()->GetTouch(touchId).pos;
		this->setTouchNearUnit();
	}

	if(this->performingSpecial) {
		return;
	}

	switch(this->inputState) {
		case InputState::INPUT_STATE_WAIT:
			this->onSelectedTouch();
			break;
		case InputState::INPUT_STATE_NAV:
			this->onNavTouch(touchId, touchedCell);
			break;
		case InputState::INPUT_STATE_SPECIAL:
			this->onSpecialTouch(touchId);
			break;
		default:
			break;
	}
}

void PlayerUnit::OnDeselect() {
	this->inputState = InputState::INPUT_STATE_WAIT;
}
void PlayerUnit::onSelectedTouch() {
	this->inputState = InputState::INPUT_STATE_NAV;
}

void PlayerUnit::startSpecial() {
	this->performingSpecial = true;
}

void PlayerUnit::onSpecialEnd() {
	this->performingSpecial = false;
	this->inputState = InputState::INPUT_STATE_NAV;
}
void PlayerUnit::onNavTouch(int touchId, GridCell* touchedCell) {
	if(this->isSpecialTouch(touchId)) {
		this->inputState = InputState::INPUT_STATE_SPECIAL;
		this->gridNavRef->StopNavigation();

	}
	else {
		if(ENGINE->GetInput()->GetTouch(touchId).phase == TouchPhase::Ended) {
			this->gridNavRef->SetDestination(touchedCell->x, touchedCell->z);
		}
	}

}

void PlayerUnit::setTouchNearUnit() {
	glm::vec3 gridPos = SINGLETONS->GetGridManager()->TouchPositionToGridPosition(touchStartPos);
	if(glm::distance(gridPos, this->gameObjectRef->GetTransform()->GetPosition()) < 1.5f) {
		this->touchNearUnit = true;
	} else {
		this->touchNearUnit = false;
	}
}
<|endoftext|>


<commit_before>//===--- lib/CodeGen/DIE.cpp - DWARF Info Entries -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Data structures for DWARF info entries.
//
//===----------------------------------------------------------------------===//

#include "DIE.h"
#include "DwarfPrinter.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
using namespace llvm;

//===----------------------------------------------------------------------===//
// DIEAbbrevData Implementation
//===----------------------------------------------------------------------===//

/// Profile - Used to gather unique data for the abbreviation folding set.
///
void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
  ID.AddInteger(Attribute);
  ID.AddInteger(Form);
}

//===----------------------------------------------------------------------===//
// DIEAbbrev Implementation
//===----------------------------------------------------------------------===//

/// Profile - Used to gather unique data for the abbreviation folding set.
///
void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
  ID.AddInteger(Tag);
  ID.AddInteger(ChildrenFlag);

  // For each attribute description.
  for (unsigned i = 0, N = Data.size(); i < N; ++i)
    Data[i].Profile(ID);
}

/// Emit - Print the abbreviation using the specified asm printer.
///
void DIEAbbrev::Emit(const AsmPrinter *Asm) const {
  // Emit its Dwarf tag type.
  Asm->EmitULEB128Bytes(Tag);
  Asm->EOL(dwarf::TagString(Tag));

  // Emit whether it has children DIEs.
  Asm->EmitULEB128Bytes(ChildrenFlag);
  Asm->EOL(dwarf::ChildrenString(ChildrenFlag));

  // For each attribute description.
  for (unsigned i = 0, N = Data.size(); i < N; ++i) {
    const DIEAbbrevData &AttrData = Data[i];

    // Emit attribute type.
    Asm->EmitULEB128Bytes(AttrData.getAttribute());
    Asm->EOL(dwarf::AttributeString(AttrData.getAttribute()));

    // Emit form type.
    Asm->EmitULEB128Bytes(AttrData.getForm());
    Asm->EOL(dwarf::FormEncodingString(AttrData.getForm()));
  }

  // Mark end of abbreviation.
  Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(1)");
  Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(2)");
}

#ifndef NDEBUG
void DIEAbbrev::print(raw_ostream &O) {
  O << "Abbreviation @"
    << format("0x%lx", (long)(intptr_t)this)
    << "  "
    << dwarf::TagString(Tag)
    << " "
    << dwarf::ChildrenString(ChildrenFlag)
    << '\n';

  for (unsigned i = 0, N = Data.size(); i < N; ++i) {
    O << "  "
      << dwarf::AttributeString(Data[i].getAttribute())
      << "  "
      << dwarf::FormEncodingString(Data[i].getForm())
      << '\n';
  }
}
void DIEAbbrev::dump() { print(errs()); }
#endif

//===----------------------------------------------------------------------===//
// DIE Implementation
//===----------------------------------------------------------------------===//

DIE::~DIE() {
  for (unsigned i = 0, N = Children.size(); i < N; ++i)
    delete Children[i];
}

/// addSiblingOffset - Add a sibling offset field to the front of the DIE.
///
void DIE::addSiblingOffset() {
  DIEInteger *DI = new DIEInteger(0);
  Values.insert(Values.begin(), DI);
  Abbrev.AddFirstAttribute(dwarf::DW_AT_sibling, dwarf::DW_FORM_ref4);
}

#ifndef NDEBUG
void DIE::print(raw_ostream &O, unsigned IncIndent) {
  IndentCount += IncIndent;
  const std::string Indent(IndentCount, ' ');
  bool isBlock = Abbrev.getTag() == 0;

  if (!isBlock) {
    O << Indent
      << "Die: "
      << format("0x%lx", (long)(intptr_t)this)
      << ", Offset: " << Offset
      << ", Size: " << Size
      << "\n";

    O << Indent
      << dwarf::TagString(Abbrev.getTag())
      << " "
      << dwarf::ChildrenString(Abbrev.getChildrenFlag());
  } else {
    O << "Size: " << Size;
  }
  O << "\n";

  const SmallVector<DIEAbbrevData, 8> &Data = Abbrev.getData();

  IndentCount += 2;
  for (unsigned i = 0, N = Data.size(); i < N; ++i) {
    O << Indent;

    if (!isBlock)
      O << dwarf::AttributeString(Data[i].getAttribute());
    else
      O << "Blk[" << i << "]";

    O <<  "  "
      << dwarf::FormEncodingString(Data[i].getForm())
      << " ";
    Values[i]->print(O);
    O << "\n";
  }
  IndentCount -= 2;

  for (unsigned j = 0, M = Children.size(); j < M; ++j) {
    Children[j]->print(O, 4);
  }

  if (!isBlock) O << "\n";
  IndentCount -= IncIndent;
}

void DIE::dump() {
  print(errs());
}
#endif

#ifndef NDEBUG
void DIEValue::dump() {
  print(errs());
}
#endif

//===----------------------------------------------------------------------===//
// DIEInteger Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit integer of appropriate size.
///
void DIEInteger::EmitValue(Dwarf *D, unsigned Form) const {
  const AsmPrinter *Asm = D->getAsm();
  switch (Form) {
  case dwarf::DW_FORM_flag:  // Fall thru
  case dwarf::DW_FORM_ref1:  // Fall thru
  case dwarf::DW_FORM_data1: Asm->EmitInt8(Integer);         break;
  case dwarf::DW_FORM_ref2:  // Fall thru
  case dwarf::DW_FORM_data2: Asm->EmitInt16(Integer);        break;
  case dwarf::DW_FORM_ref4:  // Fall thru
  case dwarf::DW_FORM_data4: Asm->EmitInt32(Integer);        break;
  case dwarf::DW_FORM_ref8:  // Fall thru
  case dwarf::DW_FORM_data8: Asm->EmitInt64(Integer);        break;
  case dwarf::DW_FORM_udata: Asm->EmitULEB128Bytes(Integer); break;
  case dwarf::DW_FORM_sdata: Asm->EmitSLEB128Bytes(Integer); break;
  default: llvm_unreachable("DIE Value form not supported yet");
  }
}

/// SizeOf - Determine size of integer value in bytes.
///
unsigned DIEInteger::SizeOf(const TargetData *TD, unsigned Form) const {
  switch (Form) {
  case dwarf::DW_FORM_flag:  // Fall thru
  case dwarf::DW_FORM_ref1:  // Fall thru
  case dwarf::DW_FORM_data1: return sizeof(int8_t);
  case dwarf::DW_FORM_ref2:  // Fall thru
  case dwarf::DW_FORM_data2: return sizeof(int16_t);
  case dwarf::DW_FORM_ref4:  // Fall thru
  case dwarf::DW_FORM_data4: return sizeof(int32_t);
  case dwarf::DW_FORM_ref8:  // Fall thru
  case dwarf::DW_FORM_data8: return sizeof(int64_t);
  case dwarf::DW_FORM_udata: return MCAsmInfo::getULEB128Size(Integer);
  case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer);
  default: llvm_unreachable("DIE Value form not supported yet"); break;
  }
  return 0;
}

#ifndef NDEBUG
void DIEInteger::print(raw_ostream &O) {
  O << "Int: " << (int64_t)Integer
    << format("  0x%llx", (unsigned long long)Integer);
}
#endif

//===----------------------------------------------------------------------===//
// DIEString Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit string value.
///
void DIEString::EmitValue(Dwarf *D, unsigned Form) const {
  D->getAsm()->EmitString(Str);
}

#ifndef NDEBUG
void DIEString::print(raw_ostream &O) {
  O << "Str: \"" << Str << "\"";
}
#endif

//===----------------------------------------------------------------------===//
// DIEDwarfLabel Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit label value.
///
void DIEDwarfLabel::EmitValue(Dwarf *D, unsigned Form) const {
  bool IsSmall = Form == dwarf::DW_FORM_data4;
  D->EmitReference(Label, false, IsSmall);
}

/// SizeOf - Determine size of label value in bytes.
///
unsigned DIEDwarfLabel::SizeOf(const TargetData *TD, unsigned Form) const {
  if (Form == dwarf::DW_FORM_data4) return 4;
  return TD->getPointerSize();
}

#ifndef NDEBUG
void DIEDwarfLabel::print(raw_ostream &O) {
  O << "Lbl: ";
  Label.print(O);
}
#endif

//===----------------------------------------------------------------------===//
// DIEObjectLabel Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit label value.
///
void DIEObjectLabel::EmitValue(Dwarf *D, unsigned Form) const {
  bool IsSmall = Form == dwarf::DW_FORM_data4;
  D->EmitReference(Label, false, IsSmall);
}

/// SizeOf - Determine size of label value in bytes.
///
unsigned DIEObjectLabel::SizeOf(const TargetData *TD, unsigned Form) const {
  if (Form == dwarf::DW_FORM_data4) return 4;
  return TD->getPointerSize();
}

#ifndef NDEBUG
void DIEObjectLabel::print(raw_ostream &O) {
  O << "Obj: " << Label;
}
#endif

//===----------------------------------------------------------------------===//
// DIESectionOffset Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit delta value.
///
void DIESectionOffset::EmitValue(Dwarf *D, unsigned Form) const {
  bool IsSmall = Form == dwarf::DW_FORM_data4;
  D->EmitSectionOffset(Label.getTag(), Section.getTag(),
                       Label.getNumber(), Section.getNumber(),
                       IsSmall, IsEH, UseSet);
}

/// SizeOf - Determine size of delta value in bytes.
///
unsigned DIESectionOffset::SizeOf(const TargetData *TD, unsigned Form) const {
  if (Form == dwarf::DW_FORM_data4) return 4;
  return TD->getPointerSize();
}

#ifndef NDEBUG
void DIESectionOffset::print(raw_ostream &O) {
  O << "Off: ";
  Label.print(O);
  O << "-";
  Section.print(O);
  O << "-" << IsEH << "-" << UseSet;
}
#endif

//===----------------------------------------------------------------------===//
// DIEDelta Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit delta value.
///
void DIEDelta::EmitValue(Dwarf *D, unsigned Form) const {
  bool IsSmall = Form == dwarf::DW_FORM_data4;
  D->EmitDifference(LabelHi, LabelLo, IsSmall);
}

/// SizeOf - Determine size of delta value in bytes.
///
unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const {
  if (Form == dwarf::DW_FORM_data4) return 4;
  return TD->getPointerSize();
}

#ifndef NDEBUG
void DIEDelta::print(raw_ostream &O) {
  O << "Del: ";
  LabelHi.print(O);
  O << "-";
  LabelLo.print(O);
}
#endif

//===----------------------------------------------------------------------===//
// DIEEntry Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit debug information entry offset.
///
void DIEEntry::EmitValue(Dwarf *D, unsigned Form) const {
  D->getAsm()->EmitInt32(Entry->getOffset());
}

#ifndef NDEBUG
void DIEEntry::print(raw_ostream &O) {
  O << format("Die: 0x%lx", (long)(intptr_t)Entry);
}
#endif

//===----------------------------------------------------------------------===//
// DIEBlock Implementation
//===----------------------------------------------------------------------===//

/// ComputeSize - calculate the size of the block.
///
unsigned DIEBlock::ComputeSize(const TargetData *TD) {
  if (!Size) {
    const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
    for (unsigned i = 0, N = Values.size(); i < N; ++i)
      Size += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
  }

  return Size;
}

/// EmitValue - Emit block data.
///
void DIEBlock::EmitValue(Dwarf *D, unsigned Form) const {
  const AsmPrinter *Asm = D->getAsm();
  switch (Form) {
  case dwarf::DW_FORM_block1: Asm->EmitInt8(Size);         break;
  case dwarf::DW_FORM_block2: Asm->EmitInt16(Size);        break;
  case dwarf::DW_FORM_block4: Asm->EmitInt32(Size);        break;
  case dwarf::DW_FORM_block:  Asm->EmitULEB128Bytes(Size); break;
  default: llvm_unreachable("Improper form for block");         break;
  }

  const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
  for (unsigned i = 0, N = Values.size(); i < N; ++i) {
    Asm->EOL();
    Values[i]->EmitValue(D, AbbrevData[i].getForm());
  }
}

/// SizeOf - Determine size of block data in bytes.
///
unsigned DIEBlock::SizeOf(const TargetData *TD, unsigned Form) const {
  switch (Form) {
  case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
  case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
  case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
  case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size);
  default: llvm_unreachable("Improper form for block"); break;
  }
  return 0;
}

#ifndef NDEBUG
void DIEBlock::print(raw_ostream &O) {
  O << "Blk: ";
  DIE::print(O, 5);
}
#endif
<commit_msg><commit_after>//===--- lib/CodeGen/DIE.cpp - DWARF Info Entries -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Data structures for DWARF info entries.
//
//===----------------------------------------------------------------------===//

#include "DIE.h"
#include "DwarfPrinter.h"
#include "llvm/CodeGen/AsmPrinter.h"
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
using namespace llvm;

//===----------------------------------------------------------------------===//
// DIEAbbrevData Implementation
//===----------------------------------------------------------------------===//

/// Profile - Used to gather unique data for the abbreviation folding set.
///
void DIEAbbrevData::Profile(FoldingSetNodeID &ID) const {
  ID.AddInteger(Attribute);
  ID.AddInteger(Form);
}

//===----------------------------------------------------------------------===//
// DIEAbbrev Implementation
//===----------------------------------------------------------------------===//

/// Profile - Used to gather unique data for the abbreviation folding set.
///
void DIEAbbrev::Profile(FoldingSetNodeID &ID) const {
  ID.AddInteger(Tag);
  ID.AddInteger(ChildrenFlag);

  // For each attribute description.
  for (unsigned i = 0, N = Data.size(); i < N; ++i)
    Data[i].Profile(ID);
}

/// Emit - Print the abbreviation using the specified asm printer.
///
void DIEAbbrev::Emit(const AsmPrinter *Asm) const {
  // Emit its Dwarf tag type.
  Asm->EmitULEB128Bytes(Tag);
  Asm->EOL(dwarf::TagString(Tag));

  // Emit whether it has children DIEs.
  Asm->EmitULEB128Bytes(ChildrenFlag);
  Asm->EOL(dwarf::ChildrenString(ChildrenFlag));

  // For each attribute description.
  for (unsigned i = 0, N = Data.size(); i < N; ++i) {
    const DIEAbbrevData &AttrData = Data[i];

    // Emit attribute type.
    Asm->EmitULEB128Bytes(AttrData.getAttribute());
    Asm->EOL(dwarf::AttributeString(AttrData.getAttribute()));

    // Emit form type.
    Asm->EmitULEB128Bytes(AttrData.getForm());
    Asm->EOL(dwarf::FormEncodingString(AttrData.getForm()));
  }

  // Mark end of abbreviation.
  Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(1)");
  Asm->EmitULEB128Bytes(0); Asm->EOL("EOM(2)");
}

#ifndef NDEBUG
void DIEAbbrev::print(raw_ostream &O) {
  O << "Abbreviation @"
    << format("0x%lx", (long)(intptr_t)this)
    << "  "
    << dwarf::TagString(Tag)
    << " "
    << dwarf::ChildrenString(ChildrenFlag)
    << '\n';

  for (unsigned i = 0, N = Data.size(); i < N; ++i) {
    O << "  "
      << dwarf::AttributeString(Data[i].getAttribute())
      << "  "
      << dwarf::FormEncodingString(Data[i].getForm())
      << '\n';
  }
}
void DIEAbbrev::dump() { print(dbgs()); }
#endif

//===----------------------------------------------------------------------===//
// DIE Implementation
//===----------------------------------------------------------------------===//

DIE::~DIE() {
  for (unsigned i = 0, N = Children.size(); i < N; ++i)
    delete Children[i];
}

/// addSiblingOffset - Add a sibling offset field to the front of the DIE.
///
void DIE::addSiblingOffset() {
  DIEInteger *DI = new DIEInteger(0);
  Values.insert(Values.begin(), DI);
  Abbrev.AddFirstAttribute(dwarf::DW_AT_sibling, dwarf::DW_FORM_ref4);
}

#ifndef NDEBUG
void DIE::print(raw_ostream &O, unsigned IncIndent) {
  IndentCount += IncIndent;
  const std::string Indent(IndentCount, ' ');
  bool isBlock = Abbrev.getTag() == 0;

  if (!isBlock) {
    O << Indent
      << "Die: "
      << format("0x%lx", (long)(intptr_t)this)
      << ", Offset: " << Offset
      << ", Size: " << Size
      << "\n";

    O << Indent
      << dwarf::TagString(Abbrev.getTag())
      << " "
      << dwarf::ChildrenString(Abbrev.getChildrenFlag());
  } else {
    O << "Size: " << Size;
  }
  O << "\n";

  const SmallVector<DIEAbbrevData, 8> &Data = Abbrev.getData();

  IndentCount += 2;
  for (unsigned i = 0, N = Data.size(); i < N; ++i) {
    O << Indent;

    if (!isBlock)
      O << dwarf::AttributeString(Data[i].getAttribute());
    else
      O << "Blk[" << i << "]";

    O <<  "  "
      << dwarf::FormEncodingString(Data[i].getForm())
      << " ";
    Values[i]->print(O);
    O << "\n";
  }
  IndentCount -= 2;

  for (unsigned j = 0, M = Children.size(); j < M; ++j) {
    Children[j]->print(O, 4);
  }

  if (!isBlock) O << "\n";
  IndentCount -= IncIndent;
}

void DIE::dump() {
  print(dbgs());
}
#endif

#ifndef NDEBUG
void DIEValue::dump() {
  print(dbgs());
}
#endif

//===----------------------------------------------------------------------===//
// DIEInteger Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit integer of appropriate size.
///
void DIEInteger::EmitValue(Dwarf *D, unsigned Form) const {
  const AsmPrinter *Asm = D->getAsm();
  switch (Form) {
  case dwarf::DW_FORM_flag:  // Fall thru
  case dwarf::DW_FORM_ref1:  // Fall thru
  case dwarf::DW_FORM_data1: Asm->EmitInt8(Integer);         break;
  case dwarf::DW_FORM_ref2:  // Fall thru
  case dwarf::DW_FORM_data2: Asm->EmitInt16(Integer);        break;
  case dwarf::DW_FORM_ref4:  // Fall thru
  case dwarf::DW_FORM_data4: Asm->EmitInt32(Integer);        break;
  case dwarf::DW_FORM_ref8:  // Fall thru
  case dwarf::DW_FORM_data8: Asm->EmitInt64(Integer);        break;
  case dwarf::DW_FORM_udata: Asm->EmitULEB128Bytes(Integer); break;
  case dwarf::DW_FORM_sdata: Asm->EmitSLEB128Bytes(Integer); break;
  default: llvm_unreachable("DIE Value form not supported yet");
  }
}

/// SizeOf - Determine size of integer value in bytes.
///
unsigned DIEInteger::SizeOf(const TargetData *TD, unsigned Form) const {
  switch (Form) {
  case dwarf::DW_FORM_flag:  // Fall thru
  case dwarf::DW_FORM_ref1:  // Fall thru
  case dwarf::DW_FORM_data1: return sizeof(int8_t);
  case dwarf::DW_FORM_ref2:  // Fall thru
  case dwarf::DW_FORM_data2: return sizeof(int16_t);
  case dwarf::DW_FORM_ref4:  // Fall thru
  case dwarf::DW_FORM_data4: return sizeof(int32_t);
  case dwarf::DW_FORM_ref8:  // Fall thru
  case dwarf::DW_FORM_data8: return sizeof(int64_t);
  case dwarf::DW_FORM_udata: return MCAsmInfo::getULEB128Size(Integer);
  case dwarf::DW_FORM_sdata: return MCAsmInfo::getSLEB128Size(Integer);
  default: llvm_unreachable("DIE Value form not supported yet"); break;
  }
  return 0;
}

#ifndef NDEBUG
void DIEInteger::print(raw_ostream &O) {
  O << "Int: " << (int64_t)Integer
    << format("  0x%llx", (unsigned long long)Integer);
}
#endif

//===----------------------------------------------------------------------===//
// DIEString Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit string value.
///
void DIEString::EmitValue(Dwarf *D, unsigned Form) const {
  D->getAsm()->EmitString(Str);
}

#ifndef NDEBUG
void DIEString::print(raw_ostream &O) {
  O << "Str: \"" << Str << "\"";
}
#endif

//===----------------------------------------------------------------------===//
// DIEDwarfLabel Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit label value.
///
void DIEDwarfLabel::EmitValue(Dwarf *D, unsigned Form) const {
  bool IsSmall = Form == dwarf::DW_FORM_data4;
  D->EmitReference(Label, false, IsSmall);
}

/// SizeOf - Determine size of label value in bytes.
///
unsigned DIEDwarfLabel::SizeOf(const TargetData *TD, unsigned Form) const {
  if (Form == dwarf::DW_FORM_data4) return 4;
  return TD->getPointerSize();
}

#ifndef NDEBUG
void DIEDwarfLabel::print(raw_ostream &O) {
  O << "Lbl: ";
  Label.print(O);
}
#endif

//===----------------------------------------------------------------------===//
// DIEObjectLabel Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit label value.
///
void DIEObjectLabel::EmitValue(Dwarf *D, unsigned Form) const {
  bool IsSmall = Form == dwarf::DW_FORM_data4;
  D->EmitReference(Label, false, IsSmall);
}

/// SizeOf - Determine size of label value in bytes.
///
unsigned DIEObjectLabel::SizeOf(const TargetData *TD, unsigned Form) const {
  if (Form == dwarf::DW_FORM_data4) return 4;
  return TD->getPointerSize();
}

#ifndef NDEBUG
void DIEObjectLabel::print(raw_ostream &O) {
  O << "Obj: " << Label;
}
#endif

//===----------------------------------------------------------------------===//
// DIESectionOffset Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit delta value.
///
void DIESectionOffset::EmitValue(Dwarf *D, unsigned Form) const {
  bool IsSmall = Form == dwarf::DW_FORM_data4;
  D->EmitSectionOffset(Label.getTag(), Section.getTag(),
                       Label.getNumber(), Section.getNumber(),
                       IsSmall, IsEH, UseSet);
}

/// SizeOf - Determine size of delta value in bytes.
///
unsigned DIESectionOffset::SizeOf(const TargetData *TD, unsigned Form) const {
  if (Form == dwarf::DW_FORM_data4) return 4;
  return TD->getPointerSize();
}

#ifndef NDEBUG
void DIESectionOffset::print(raw_ostream &O) {
  O << "Off: ";
  Label.print(O);
  O << "-";
  Section.print(O);
  O << "-" << IsEH << "-" << UseSet;
}
#endif

//===----------------------------------------------------------------------===//
// DIEDelta Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit delta value.
///
void DIEDelta::EmitValue(Dwarf *D, unsigned Form) const {
  bool IsSmall = Form == dwarf::DW_FORM_data4;
  D->EmitDifference(LabelHi, LabelLo, IsSmall);
}

/// SizeOf - Determine size of delta value in bytes.
///
unsigned DIEDelta::SizeOf(const TargetData *TD, unsigned Form) const {
  if (Form == dwarf::DW_FORM_data4) return 4;
  return TD->getPointerSize();
}

#ifndef NDEBUG
void DIEDelta::print(raw_ostream &O) {
  O << "Del: ";
  LabelHi.print(O);
  O << "-";
  LabelLo.print(O);
}
#endif

//===----------------------------------------------------------------------===//
// DIEEntry Implementation
//===----------------------------------------------------------------------===//

/// EmitValue - Emit debug information entry offset.
///
void DIEEntry::EmitValue(Dwarf *D, unsigned Form) const {
  D->getAsm()->EmitInt32(Entry->getOffset());
}

#ifndef NDEBUG
void DIEEntry::print(raw_ostream &O) {
  O << format("Die: 0x%lx", (long)(intptr_t)Entry);
}
#endif

//===----------------------------------------------------------------------===//
// DIEBlock Implementation
//===----------------------------------------------------------------------===//

/// ComputeSize - calculate the size of the block.
///
unsigned DIEBlock::ComputeSize(const TargetData *TD) {
  if (!Size) {
    const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
    for (unsigned i = 0, N = Values.size(); i < N; ++i)
      Size += Values[i]->SizeOf(TD, AbbrevData[i].getForm());
  }

  return Size;
}

/// EmitValue - Emit block data.
///
void DIEBlock::EmitValue(Dwarf *D, unsigned Form) const {
  const AsmPrinter *Asm = D->getAsm();
  switch (Form) {
  case dwarf::DW_FORM_block1: Asm->EmitInt8(Size);         break;
  case dwarf::DW_FORM_block2: Asm->EmitInt16(Size);        break;
  case dwarf::DW_FORM_block4: Asm->EmitInt32(Size);        break;
  case dwarf::DW_FORM_block:  Asm->EmitULEB128Bytes(Size); break;
  default: llvm_unreachable("Improper form for block");         break;
  }

  const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev.getData();
  for (unsigned i = 0, N = Values.size(); i < N; ++i) {
    Asm->EOL();
    Values[i]->EmitValue(D, AbbrevData[i].getForm());
  }
}

/// SizeOf - Determine size of block data in bytes.
///
unsigned DIEBlock::SizeOf(const TargetData *TD, unsigned Form) const {
  switch (Form) {
  case dwarf::DW_FORM_block1: return Size + sizeof(int8_t);
  case dwarf::DW_FORM_block2: return Size + sizeof(int16_t);
  case dwarf::DW_FORM_block4: return Size + sizeof(int32_t);
  case dwarf::DW_FORM_block: return Size + MCAsmInfo::getULEB128Size(Size);
  default: llvm_unreachable("Improper form for block"); break;
  }
  return 0;
}

#ifndef NDEBUG
void DIEBlock::print(raw_ostream &O) {
  O << "Blk: ";
  DIE::print(O, 5);
}
#endif
<|endoftext|>