<commit_before>////////////////////////////////////////////
///
/// WraithOne
/// www.Dark-Abyss.net
///
/// ZFX Action 2014
///
/// Theme: Career, Cell
///
////////////////////////////////////////////

#include <Capp.h>

bool Capp::InitPrisoner()
{
	// Load Prisoner Image
	m_Prisoner = LoadImage(m_Renderer, "Data/GFX/Prisoner.png");
	if (m_Prisoner == nullptr)
	{
		Shutdown();

		return false;
	}

	return true;
}

void Capp::UpdatePrisoner(unsigned int elapsedTime)
{

}

void Capp::RenderPrisoner(unsigned int elapsedTime)
{

}<commit_msg>Added Prisoners<commit_after>////////////////////////////////////////////
///
/// WraithOne
/// www.Dark-Abyss.net
///
/// ZFX Action 2014
///
/// Theme: Career, Cell
///
////////////////////////////////////////////

#include <Capp.h>

bool Capp::InitPrisoner()
{
	// Load Prisoner Image
	m_Prisoner = LoadImage(m_Renderer, "Data/GFX/Prisoner.png");
	if (m_Prisoner == nullptr)
	{
		Shutdown();

		return false;
	}
	Prisoner temp;

	// Prisoner 1
	temp.BBrect = { 22, 11, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 61, 30 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Cigaretts;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 0;
	m_PrisonerList.push_back(temp);

	// Prisoner 2
	temp.BBrect = { 18, 158, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 61, 133 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Nothing;
	temp.Walkposition = { 72, 127 };
	temp.walkrotation = 0;
	m_PrisonerList.push_back(temp);

	// Prisoner 3
	temp.BBrect = { 68, 232, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 64, 231 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Nothing;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 0;
	m_PrisonerList.push_back(temp);

	// Prisoner 4
	temp.BBrect = { 16, 363, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 65, 334 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Cigaretts;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 0;
	m_PrisonerList.push_back(temp);

	// Prisoner 5
	temp.BBrect = { 14, 411, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 65, 431 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Nothing;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 90;
	m_PrisonerList.push_back(temp);

	// Prisoner 6
	temp.BBrect = { 70, 534, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 65, 534 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Nothing;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 0;
	m_PrisonerList.push_back(temp);

	// Prisoner 7
	temp.BBrect = { 307, 49, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 256, 32 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Nothing;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 90;
	m_PrisonerList.push_back(temp);

	// Prisoner 8
	temp.BBrect = { 253, 137, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 254, 137 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Cigaretts;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 90;
	m_PrisonerList.push_back(temp);

	// Prisoner 9
	temp.BBrect = { 381, 261, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = {384, 265 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Nothing;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 90;
	m_PrisonerList.push_back(temp);

	// Prisoner 10
	temp.BBrect = { 482, 208, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 483, 265 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Cigaretts;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 0;
	m_PrisonerList.push_back(temp);

	// Prisoner 11
	temp.BBrect = { 281, 461, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 283, 451 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Nothing;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 0;
	m_PrisonerList.push_back(temp);

	// Prisoner 12
	temp.BBrect = { 358, 481, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 385, 452 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Nothing;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 0;
	m_PrisonerList.push_back(temp);

	// Prisoner 13
	temp.BBrect = { 480, 466, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 481, 455 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Nothing;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 0;
	m_PrisonerList.push_back(temp);

	// Prisoner 14
	temp.BBrect = { 570, 495, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 582, 453 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Nothing;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 90;
	m_PrisonerList.push_back(temp);

	// Prisoner 15
	temp.BBrect = { 702, 497, 32, 32 };
	temp.srcRect = { 0, 0, 32, 32 };
	temp.Behave = Standing;
	temp.lastDecisiontime = 0;
	temp.Buyposition = { 679, 453 };
	temp.Buyrotation = 90;
	temp.BuyGoods = Cigaretts;
	temp.Walkposition = { 62, 65 };
	temp.walkrotation = 0;
	m_PrisonerList.push_back(temp);

	return true;
}

void Capp::UpdatePrisoner(unsigned int elapsedTime)
{
	std::vector<Prisoner>::iterator it;
	for (it = m_PrisonerList.begin(); it < m_PrisonerList.end(); it++)
	{
		if (it->Behave == Standing)
		{
			it->srcRect.x = 0;
		}
		if (it->Behave == WalkingVertical)
		{
			it->srcRect.x = 32;
			it->walkrotation = 90;
		}
		if (it->Behave == WalkingHorizontal)
		{
			it->srcRect.x = 64;
			it->walkrotation = 0;
		}
		if (it->Behave == Buying)
		{
			it->walkrotation = it->Buyrotation;
		}
	}
}

void Capp::RenderPrisoner(unsigned int elapsedTime)
{
	std::vector<Prisoner>::iterator it;
	for (it = m_PrisonerList.begin(); it < m_PrisonerList.end(); it++)
	{
		SDL_RenderCopyEx(m_Renderer, m_Prisoner, &it->srcRect, &it->BBrect, it->walkrotation, NULL, SDL_FLIP_NONE);
	}
}<|endoftext|>


<commit_before>#define _WINSOCKAPI_
#include <windows.h>

#include "qpop_app.h"
#include "qpop_frame.h"

#include <stdio.h>
#include <string>
#include <settings_class.h>
#include <iostream>
#include <qpop_server.h>
#include <gdiplus.h>
#include <img_processing.h>
#include <screen_capturer.h>
#include <ancillary_functions.h>
#include <shared_access.h>
#include <mutex>

namespace boost
{
	#ifdef BOOST_NO_EXCEPTIONS
	void throw_exception( std::exception const & e ){
	    throw e;
	};
	#endif
}

// TODO: check why connections are dropping randomly - reenable authentication

using namespace Ancillary_Function;
using namespace Qpop::gui;
void MonitorCondition(Qpop_Server* s, int x, int y, std::string exe_name);
void StartQpopBackend(QpopFrame* frame);

bool QpopApp::OnInit(){
	QpopFrame* frame = new QpopFrame("Qpop", wxDefaultPosition, wxSize(250, 200));
	frame->Show(true);
	this->qpop_scanner = new std::thread(StartQpopBackend, frame);
	return true;
}

/**
* Monitors the condition of whether or not
* @param s        pointer to a running Qpop_server
* @param x        x coordinate
* @param y        y coordinate
* @param exe_name name of process
*/

void MonitorCondition(Qpop_Server* s, int x, int y, std::string exe_name) {
	// Set up port and start server to interact
	// with mobile app
	s->set_port(8000);
	s->start_server();
	while (_close_qpop == 0) {
		std::unique_lock<std::mutex> lock(_monitor_pause);
		condition.wait(lock);
		if (s->conditionSatisfied()) {
			SetDelayCount(4);
			ExhaustiveClick(x, y, exe_name);
			s->setCondition(false);
		}
	}
}

void StartQpopBackend(QpopFrame* frame){
	srand(time(NULL));
	wxString auth_num, wxdifference;
	Qpop_Server main_server;
	std::cout << "Starting Main Program" << std::endl;
	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
   	ULONG_PTR gdiplusToken;
   	Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
   	bool image_match = false;
	std::string exe_name;
	Gdiplus::Bitmap* snapshot = NULL;
	Gdiplus::Bitmap* bmp_from_file = NULL;
	int result = 0;

	wxStaticText* connect_status_text = (wxStaticText*) (frame->FindWindowById(wxSTATUS_TEXT));
	wxStaticText* diff_text = (wxStaticText*) (frame->FindWindowById(wxDIFF_TEXT));
   	// Create settings profile for league of legends
   	Settings_Profile cur_prof("lol.txt");

   	// TODO: put into subclass
   	connect_status_text->SetForegroundColour(wxColour(wxT("RED")));
   	frame->Refresh();

   	// Create scaling info struct. Keeps default  x and y for when window is resized. The resize it then applied
   	// To the location of the buttons
	loadBitmapFromFile(&bmp_from_file, cur_prof.getImgName(0));
	float difference = 0;
	tagSIZE* img_dimensions = (tagSIZE*) calloc(sizeof(tagSIZE), cur_prof.getImgCount());
	exe_name = cur_prof.getProcessName();

	// Create thread to manage asynchronous requests. The numbers passed in are the coordinates for the
	// ExhaustiveClick call. When conditions for the server are true - it recieves a signal from a phone -
	// it will call this exhaustive click
    std::thread monitor_thread(MonitorCondition, &main_server, cur_prof.getX(0) + (int) (bmp_from_file->GetWidth() / 2), cur_prof.getY(0) + (int) (bmp_from_file->GetHeight() / 2), exe_name);

   	// set text for ip and authnum
   	auth_num << main_server.getAuthNum();
   	((wxStaticText*) (frame->FindWindowById(wxAUTH_TEXT)))->SetLabelText(auth_num);

	while(_close_qpop == 0){
		result = Screen_Capturer::takeSnapshot(&snapshot, exe_name);
		if(main_server.is_Connected()) connect_status_text->SetForegroundColour(wxColour(wxT("GREEN")));
		else connect_status_text->SetForegroundColour(wxColour(wxT("RED")));
		frame->Refresh();

		if(result == 0)
		{

			// Crop snapshot with the given profile coordinate and the width and height of the loaded file
			// This will keep the resolutions the same and attempt to match it with the appropriate picture
			Img_Processing::cropBitmap(&snapshot, cur_prof.getX(0), cur_prof.getY(0), (int) bmp_from_file->GetWidth(), (int) bmp_from_file->GetHeight());
			// mulitiply by 100 since the percentage wil come back <= 1
			difference = Img_Processing::compareMemoryImg(snapshot, bmp_from_file) * 100;

			// Display Difference
			wxdifference.Clear();
			wxdifference << difference;
			diff_text->SetLabelText(wxdifference);

			if(0 < cur_prof.getThresholdAt(0)) image_match = difference > cur_prof.getThresholdAt(0);
			// if the threshold is negative in the settings profile it means compare the difference for less than that threshold amount
			else image_match = difference < (cur_prof.getThresholdAt(0) * -1);

			// send message to mobile according to if the image matched
			if(image_match){

				condition.notify_one();
				if(delay_count <= 0){
					main_server.send("popped");
					// If server is connected, set a 20 loop delay. This prevents a click being sent, the button transition
					// not completing and retriggering the threshold, resulting in a short false positive
					if(main_server.is_Connected()){
						SetDelayCount(20);
					}
				}
			}
			else{
				main_server.send("queued");
				main_server.setCondition(false);
			}
			// deduct from delay count every iteration
			if(delay_count > 0){
				DecDelayCount();
			}
		}
		// Prevent from websocket closing if league isn't running
		else{
			main_server.send("queued");
			main_server.setCondition(false);
		}

		Sleep(500);
	}

	DeleteObject(bmp_from_file);
	DeleteObject(snapshot);
	free(img_dimensions);
	Gdiplus::GdiplusShutdown(gdiplusToken);
}<commit_msg>added process not found message<commit_after>#define _WINSOCKAPI_
#include <windows.h>

#include "qpop_app.h"
#include "qpop_frame.h"

#include <stdio.h>
#include <string>
#include <settings_class.h>
#include <iostream>
#include <qpop_server.h>
#include <gdiplus.h>
#include <img_processing.h>
#include <screen_capturer.h>
#include <ancillary_functions.h>
#include <shared_access.h>
#include <mutex>

namespace boost
{
	#ifdef BOOST_NO_EXCEPTIONS
	void throw_exception( std::exception const & e ){
	    throw e;
	};
	#endif
}

// TODO: check why connections are dropping randomly - reenable authentication

using namespace Ancillary_Function;
using namespace Qpop::gui;
void MonitorCondition(Qpop_Server* s, int x, int y, std::string exe_name);
void StartQpopBackend(QpopFrame* frame);

bool QpopApp::OnInit(){
	QpopFrame* frame = new QpopFrame("Qpop", wxDefaultPosition, wxSize(250, 200));
	frame->Show(true);
	this->qpop_scanner = new std::thread(StartQpopBackend, frame);
	return true;
}

/**
* Monitors the condition of whether or not
* @param s        pointer to a running Qpop_server
* @param x        x coordinate
* @param y        y coordinate
* @param exe_name name of process
*/

void MonitorCondition(Qpop_Server* s, int x, int y, std::string exe_name) {
	// Set up port and start server to interact
	// with mobile app
	s->set_port(8000);
	s->start_server();
	while (_close_qpop == 0) {
		std::unique_lock<std::mutex> lock(_monitor_pause);
		condition.wait(lock);
		if (s->conditionSatisfied()) {
			SetDelayCount(4);
			ExhaustiveClick(x, y, exe_name);
			s->setCondition(false);
		}
	}
}

void StartQpopBackend(QpopFrame* frame){
	srand(time(NULL));
	wxString auth_num, wxdifference;
	Qpop_Server main_server;
	std::cout << "Starting Main Program" << std::endl;
	Gdiplus::GdiplusStartupInput gdiplusStartupInput;
   	ULONG_PTR gdiplusToken;
   	Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
   	bool image_match = false;
	std::string exe_name;
	Gdiplus::Bitmap* snapshot = NULL;
	Gdiplus::Bitmap* bmp_from_file = NULL;
	int result = 0;

	wxStaticText* connect_status_text = (wxStaticText*) (frame->FindWindowById(wxSTATUS_TEXT));
	wxStaticText* diff_text = (wxStaticText*) (frame->FindWindowById(wxDIFF_TEXT));
   	// Create settings profile for league of legends
   	Settings_Profile cur_prof("lol.txt");

   	// TODO: put into subclass
   	connect_status_text->SetForegroundColour(wxColour(wxT("RED")));
   	frame->Refresh();

   	// Create scaling info struct. Keeps default  x and y for when window is resized. The resize it then applied
   	// To the location of the buttons
	loadBitmapFromFile(&bmp_from_file, cur_prof.getImgName(0));
	float difference = 0;
	tagSIZE* img_dimensions = (tagSIZE*) calloc(sizeof(tagSIZE), cur_prof.getImgCount());
	exe_name = cur_prof.getProcessName();

	// Create thread to manage asynchronous requests. The numbers passed in are the coordinates for the
	// ExhaustiveClick call. When conditions for the server are true - it recieves a signal from a phone -
	// it will call this exhaustive click
    std::thread monitor_thread(MonitorCondition, &main_server, cur_prof.getX(0) + (int) (bmp_from_file->GetWidth() / 2), cur_prof.getY(0) + (int) (bmp_from_file->GetHeight() / 2), exe_name);

   	// set text for ip and authnum
   	auth_num << main_server.getAuthNum();
   	((wxStaticText*) (frame->FindWindowById(wxAUTH_TEXT)))->SetLabelText(auth_num);

	while(_close_qpop == 0){
		result = Screen_Capturer::takeSnapshot(&snapshot, exe_name);
		if(main_server.is_Connected()) connect_status_text->SetForegroundColour(wxColour(wxT("GREEN")));
		else connect_status_text->SetForegroundColour(wxColour(wxT("RED")));
		frame->Refresh();

		if(result == -1) diff_text->SetLabelText("process not found");
		else if(result == 0)
		{

			// Crop snapshot with the given profile coordinate and the width and height of the loaded file
			// This will keep the resolutions the same and attempt to match it with the appropriate picture
			Img_Processing::cropBitmap(&snapshot, cur_prof.getX(0), cur_prof.getY(0), (int) bmp_from_file->GetWidth(), (int) bmp_from_file->GetHeight());
			// mulitiply by 100 since the percentage wil come back <= 1
			difference = Img_Processing::compareMemoryImg(snapshot, bmp_from_file) * 100;

			// Display Difference
			wxdifference.Clear();
			wxdifference << difference;
			diff_text->SetLabelText(wxdifference);

			if(0 < cur_prof.getThresholdAt(0)) image_match = difference > cur_prof.getThresholdAt(0);
			// if the threshold is negative in the settings profile it means compare the difference for less than that threshold amount
			else image_match = difference < (cur_prof.getThresholdAt(0) * -1);

			// send message to mobile according to if the image matched
			if(image_match){

				condition.notify_one();
				if(delay_count <= 0){
					main_server.send("popped");
					// If server is connected, set a 20 loop delay. This prevents a click being sent, the button transition
					// not completing and retriggering the threshold, resulting in a short false positive
					if(main_server.is_Connected()){
						SetDelayCount(20);
					}
				}
			}
			else{
				main_server.send("queued");
				main_server.setCondition(false);
			}
			// deduct from delay count every iteration
			if(delay_count > 0){
				DecDelayCount();
			}
		}
		// Prevent from websocket closing if league isn't running
		else{
			main_server.send("queued");
			main_server.setCondition(false);
			diff_text->SetLabelText("-1");
		}

		Sleep(500);
	}

	DeleteObject(bmp_from_file);
	DeleteObject(snapshot);
	free(img_dimensions);
	Gdiplus::GdiplusShutdown(gdiplusToken);
}<|endoftext|>


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

#include <bench/bench.h>
#include <policy/policy.h>
#include <txmempool.h>

#include <vector>

static void AddTx(const CTransactionRef& tx, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
{
    int64_t nTime = 0;
    unsigned int nHeight = 1;
    bool spendsCoinbase = false;
    unsigned int sigOpCost = 4;
    LockPoints lp;
    pool.addUnchecked(CTxMemPoolEntry(tx, 1000, nTime, nHeight, spendsCoinbase, sigOpCost, lp));
}

struct Available {
    CTransactionRef ref;
    size_t vin_left{0};
    size_t tx_count;
    Available(CTransactionRef& ref, size_t tx_count) : ref(ref), tx_count(tx_count){}
    Available& operator=(Available other) {
        ref = other.ref;
        vin_left = other.vin_left;
        tx_count = other.tx_count;
        return *this;
    }
};

static void ComplexMemPool(benchmark::State& state)
{
    FastRandomContext det_rand{true};
    std::vector<Available> available_coins;
    std::vector<CTransactionRef> ordered_coins;
    // Create some base transactions
    size_t tx_counter = 1;
    for (auto x = 0; x < 100; ++x) {
        CMutableTransaction tx = CMutableTransaction();
        tx.vin.resize(1);
        tx.vin[0].scriptSig = CScript() << CScriptNum(tx_counter);
        tx.vin[0].scriptWitness.stack.push_back(CScriptNum(x).getvch());
        tx.vout.resize(det_rand.randrange(10)+2);
        for (auto& out : tx.vout) {
            out.scriptPubKey = CScript() << CScriptNum(tx_counter) << OP_EQUAL;
            out.nValue = 10 * COIN;
        }
        ordered_coins.emplace_back(MakeTransactionRef(tx));
        available_coins.emplace_back(ordered_coins.back(), tx_counter++);
    }
    for (auto x = 0; x < 800 && !available_coins.empty(); ++x) {
        CMutableTransaction tx = CMutableTransaction();
        size_t n_ancestors = det_rand.randrange(10)+1;
        for (size_t ancestor = 0; ancestor < n_ancestors && !available_coins.empty(); ++ancestor){
            size_t idx = det_rand.randrange(available_coins.size());
            Available coin = available_coins[idx];
            uint256 hash = coin.ref->GetHash();
            // biased towards taking just one ancestor, but maybe more
            size_t n_to_take = det_rand.randrange(2) == 0 ? 1 : 1+det_rand.randrange(coin.ref->vout.size() - coin.vin_left);
            for (size_t i = 0; i < n_to_take; ++i) {
                tx.vin.emplace_back();
                tx.vin.back().prevout = COutPoint(hash, coin.vin_left++);
                tx.vin.back().scriptSig = CScript() << coin.tx_count;
                tx.vin.back().scriptWitness.stack.push_back(CScriptNum(coin.tx_count).getvch());
            }
            if  (coin.vin_left == coin.ref->vin.size()) {
                coin = available_coins.back();
                available_coins.pop_back();
            }
            tx.vout.resize(det_rand.randrange(10)+2);
            for (auto& out : tx.vout) {
                out.scriptPubKey = CScript() << CScriptNum(tx_counter) << OP_EQUAL;
                out.nValue = 10 * COIN;
            }
        }
        ordered_coins.emplace_back(MakeTransactionRef(tx));
        available_coins.emplace_back(ordered_coins.back(), tx_counter++);
    }
    CTxMemPool pool;
    LOCK2(cs_main, pool.cs);
    while (state.KeepRunning()) {
        for (auto& tx : ordered_coins) {
            AddTx(tx, pool);
        }
        pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4);
        pool.TrimToSize(GetVirtualTransactionSize(*ordered_coins.front()));
    }
}

BENCHMARK(ComplexMemPool, 1);
<commit_msg>bench: Remove redundant copy constructor in mempool_stress<commit_after>// Copyright (c) 2011-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <bench/bench.h>
#include <policy/policy.h>
#include <txmempool.h>

#include <vector>

static void AddTx(const CTransactionRef& tx, CTxMemPool& pool) EXCLUSIVE_LOCKS_REQUIRED(cs_main, pool.cs)
{
    int64_t nTime = 0;
    unsigned int nHeight = 1;
    bool spendsCoinbase = false;
    unsigned int sigOpCost = 4;
    LockPoints lp;
    pool.addUnchecked(CTxMemPoolEntry(tx, 1000, nTime, nHeight, spendsCoinbase, sigOpCost, lp));
}

struct Available {
    CTransactionRef ref;
    size_t vin_left{0};
    size_t tx_count;
    Available(CTransactionRef& ref, size_t tx_count) : ref(ref), tx_count(tx_count){}
};

static void ComplexMemPool(benchmark::State& state)
{
    FastRandomContext det_rand{true};
    std::vector<Available> available_coins;
    std::vector<CTransactionRef> ordered_coins;
    // Create some base transactions
    size_t tx_counter = 1;
    for (auto x = 0; x < 100; ++x) {
        CMutableTransaction tx = CMutableTransaction();
        tx.vin.resize(1);
        tx.vin[0].scriptSig = CScript() << CScriptNum(tx_counter);
        tx.vin[0].scriptWitness.stack.push_back(CScriptNum(x).getvch());
        tx.vout.resize(det_rand.randrange(10)+2);
        for (auto& out : tx.vout) {
            out.scriptPubKey = CScript() << CScriptNum(tx_counter) << OP_EQUAL;
            out.nValue = 10 * COIN;
        }
        ordered_coins.emplace_back(MakeTransactionRef(tx));
        available_coins.emplace_back(ordered_coins.back(), tx_counter++);
    }
    for (auto x = 0; x < 800 && !available_coins.empty(); ++x) {
        CMutableTransaction tx = CMutableTransaction();
        size_t n_ancestors = det_rand.randrange(10)+1;
        for (size_t ancestor = 0; ancestor < n_ancestors && !available_coins.empty(); ++ancestor){
            size_t idx = det_rand.randrange(available_coins.size());
            Available coin = available_coins[idx];
            uint256 hash = coin.ref->GetHash();
            // biased towards taking just one ancestor, but maybe more
            size_t n_to_take = det_rand.randrange(2) == 0 ? 1 : 1+det_rand.randrange(coin.ref->vout.size() - coin.vin_left);
            for (size_t i = 0; i < n_to_take; ++i) {
                tx.vin.emplace_back();
                tx.vin.back().prevout = COutPoint(hash, coin.vin_left++);
                tx.vin.back().scriptSig = CScript() << coin.tx_count;
                tx.vin.back().scriptWitness.stack.push_back(CScriptNum(coin.tx_count).getvch());
            }
            if (coin.vin_left == coin.ref->vin.size()) {
                coin = available_coins.back();
                available_coins.pop_back();
            }
            tx.vout.resize(det_rand.randrange(10)+2);
            for (auto& out : tx.vout) {
                out.scriptPubKey = CScript() << CScriptNum(tx_counter) << OP_EQUAL;
                out.nValue = 10 * COIN;
            }
        }
        ordered_coins.emplace_back(MakeTransactionRef(tx));
        available_coins.emplace_back(ordered_coins.back(), tx_counter++);
    }
    CTxMemPool pool;
    LOCK2(cs_main, pool.cs);
    while (state.KeepRunning()) {
        for (auto& tx : ordered_coins) {
            AddTx(tx, pool);
        }
        pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4);
        pool.TrimToSize(GetVirtualTransactionSize(*ordered_coins.front()));
    }
}

BENCHMARK(ComplexMemPool, 1);
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: accessiblekeybindinghelper.hxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: tbe $ $Date: 2002-12-10 17:18:32 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef COMPHELPER_ACCESSIBLE_KEYBINDING_HELPER_HXX
#define COMPHELPER_ACCESSIBLE_KEYBINDING_HELPER_HXX

#ifndef _DRAFTS_COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEKEYBINDING_HPP_
#include <drafts/com/sun/star/accessibility/XAccessibleKeyBinding.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

#include <vector>

//..............................................................................
namespace comphelper
{
//..............................................................................

    //==============================================================================
    // OAccessibleKeyBindingHelper
    //==============================================================================

    typedef ::cppu::WeakImplHelper1 <   ::drafts::com::sun::star::accessibility::XAccessibleKeyBinding
                                    >   OAccessibleKeyBindingHelper_Base;

    /** a helper class for implementing an accessible keybinding
     */
    class OAccessibleKeyBindingHelper : public OAccessibleKeyBindingHelper_Base
    {
    private:
        typedef ::std::vector< ::com::sun::star::uno::Sequence< ::drafts::com::sun::star::awt::KeyStroke > > KeyBindings;

        KeyBindings     m_aKeyBindings;

    protected:
        ::osl::Mutex    m_aMutex;

        virtual ~OAccessibleKeyBindingHelper();

    public:
        OAccessibleKeyBindingHelper();
        OAccessibleKeyBindingHelper( const OAccessibleKeyBindingHelper& rHelper );

        void AddKeyBinding( const ::com::sun::star::uno::Sequence< ::drafts::com::sun::star::awt::KeyStroke >& rKeyBinding ) throw (::com::sun::star::uno::RuntimeException);
        void AddKeyBinding( const ::drafts::com::sun::star::awt::KeyStroke& rKeyStroke ) throw (::com::sun::star::uno::RuntimeException);

        // XAccessibleKeyBinding
        virtual sal_Int32 SAL_CALL getAccessibleKeyBindingCount() throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::drafts::com::sun::star::awt::KeyStroke > SAL_CALL getAccessibleKeyBinding( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
    };

//..............................................................................
}   // namespace comphelper
//..............................................................................

#endif // COMPHELPER_ACCESSIBLE_KEYBINDING_HELPER_HXX
<commit_msg>INTEGRATION: CWS uaa02 (1.1.40); FILE MERGED 2003/04/10 11:56:57 mt 1.1.40.1: #108656# Moved Accessibility module from drafts to final<commit_after>/*************************************************************************
 *
 *  $RCSfile: accessiblekeybindinghelper.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2003-04-24 17:25:46 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef COMPHELPER_ACCESSIBLE_KEYBINDING_HELPER_HXX
#define COMPHELPER_ACCESSIBLE_KEYBINDING_HELPER_HXX

#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEKEYBINDING_HPP_
#include <com/sun/star/accessibility/XAccessibleKeyBinding.hpp>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif
#ifndef _OSL_MUTEX_HXX_
#include <osl/mutex.hxx>
#endif

#include <vector>

//..............................................................................
namespace comphelper
{
//..............................................................................

    //==============================================================================
    // OAccessibleKeyBindingHelper
    //==============================================================================

    typedef ::cppu::WeakImplHelper1 <   ::com::sun::star::accessibility::XAccessibleKeyBinding
                                    >   OAccessibleKeyBindingHelper_Base;

    /** a helper class for implementing an accessible keybinding
     */
    class OAccessibleKeyBindingHelper : public OAccessibleKeyBindingHelper_Base
    {
    private:
        typedef ::std::vector< ::com::sun::star::uno::Sequence< ::com::sun::star::awt::KeyStroke > > KeyBindings;

        KeyBindings     m_aKeyBindings;

    protected:
        ::osl::Mutex    m_aMutex;

        virtual ~OAccessibleKeyBindingHelper();

    public:
        OAccessibleKeyBindingHelper();
        OAccessibleKeyBindingHelper( const OAccessibleKeyBindingHelper& rHelper );

        void AddKeyBinding( const ::com::sun::star::uno::Sequence< ::com::sun::star::awt::KeyStroke >& rKeyBinding ) throw (::com::sun::star::uno::RuntimeException);
        void AddKeyBinding( const ::com::sun::star::awt::KeyStroke& rKeyStroke ) throw (::com::sun::star::uno::RuntimeException);

        // XAccessibleKeyBinding
        virtual sal_Int32 SAL_CALL getAccessibleKeyBindingCount() throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Sequence< ::com::sun::star::awt::KeyStroke > SAL_CALL getAccessibleKeyBinding( sal_Int32 nIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
    };

//..............................................................................
}   // namespace comphelper
//..............................................................................

#endif // COMPHELPER_ACCESSIBLE_KEYBINDING_HELPER_HXX
<|endoftext|>


<commit_before>//===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements LexicalScopes analysis.
//
// This pass collects lexical scope information and maps machine instructions
// to respective lexical scopes.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "lexicalscopes"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/DebugInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;

LexicalScopes::~LexicalScopes() {
  releaseMemory();
}

/// releaseMemory - release memory.
void LexicalScopes::releaseMemory() {
  MF = NULL;
  CurrentFnLexicalScope = NULL;
  DeleteContainerSeconds(LexicalScopeMap);
  DeleteContainerSeconds(AbstractScopeMap);
  InlinedLexicalScopeMap.clear();
  AbstractScopesList.clear();
}

/// initialize - Scan machine function and constuct lexical scope nest.
void LexicalScopes::initialize(const MachineFunction &Fn) {
  releaseMemory();
  MF = &Fn;
  SmallVector<InsnRange, 4> MIRanges;
  DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap;
  extractLexicalScopes(MIRanges, MI2ScopeMap);
  if (CurrentFnLexicalScope) {
    constructScopeNest(CurrentFnLexicalScope);
    assignInstructionRanges(MIRanges, MI2ScopeMap);
  }
}

/// extractLexicalScopes - Extract instruction ranges for each lexical scopes
/// for the given machine function.
void LexicalScopes::
extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges,
                  DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {

  // Scan each instruction and create scopes. First build working set of scopes.
  for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
       I != E; ++I) {
    const MachineInstr *RangeBeginMI = NULL;
    const MachineInstr *PrevMI = NULL;
    DebugLoc PrevDL;
    for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
         II != IE; ++II) {
      const MachineInstr *MInsn = II;

      // Check if instruction has valid location information.
      const DebugLoc MIDL = MInsn->getDebugLoc();
      if (MIDL.isUnknown()) {
        PrevMI = MInsn;
        continue;
      }

      // If scope has not changed then skip this instruction.
      if (MIDL == PrevDL) {
        PrevMI = MInsn;
        continue;
      }

      // Ignore DBG_VALUE. It does not contribute to any instruction in output.
      if (MInsn->isDebugValue())
        continue;

      if (RangeBeginMI) {
        // If we have already seen a beginning of an instruction range and
        // current instruction scope does not match scope of first instruction
        // in this range then create a new instruction range.
        InsnRange R(RangeBeginMI, PrevMI);
        MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
        MIRanges.push_back(R);
      }

      // This is a beginning of a new instruction range.
      RangeBeginMI = MInsn;

      // Reset previous markers.
      PrevMI = MInsn;
      PrevDL = MIDL;
    }

    // Create last instruction range.
    if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) {
      InsnRange R(RangeBeginMI, PrevMI);
      MIRanges.push_back(R);
      MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
    }
  }
}

/// findLexicalScope - Find lexical scope, either regular or inlined, for the
/// given DebugLoc. Return NULL if not found.
LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) {
  MDNode *Scope = NULL;
  MDNode *IA = NULL;
  DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext());
  if (!Scope) return NULL;

  // The scope that we were created with could have an extra file - which
  // isn't what we care about in this case.
  DIDescriptor D = DIDescriptor(Scope);
  if (D.isLexicalBlockFile())
    Scope = DILexicalBlockFile(Scope).getScope();

  if (IA)
    return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA));
  return LexicalScopeMap.lookup(Scope);
}

/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
/// not available then create new lexical scope.
LexicalScope *LexicalScopes::getOrCreateLexicalScope(DebugLoc DL) {
  MDNode *Scope = NULL;
  MDNode *InlinedAt = NULL;
  DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext());

  if (InlinedAt) {
    // Create an abstract scope for inlined function.
    getOrCreateAbstractScope(Scope);
    // Create an inlined scope for inlined function.
    return getOrCreateInlinedScope(Scope, InlinedAt);
  }

  return getOrCreateRegularScope(Scope);
}

/// getOrCreateRegularScope - Find or create a regular lexical scope.
LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
  DIDescriptor D = DIDescriptor(Scope);
  if (D.isLexicalBlockFile()) {
    Scope = DILexicalBlockFile(Scope).getScope();
    D = DIDescriptor(Scope);
  }

  LexicalScope *WScope = LexicalScopeMap.lookup(Scope);
  if (WScope)
    return WScope;

  LexicalScope *Parent = NULL;
  if (D.isLexicalBlock())
    Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope));
  WScope = new LexicalScope(Parent, DIDescriptor(Scope), NULL, false);
  LexicalScopeMap.insert(std::make_pair(Scope, WScope));
  if (!Parent && DIDescriptor(Scope).isSubprogram()
      && DISubprogram(Scope).describes(MF->getFunction()))
    CurrentFnLexicalScope = WScope;

  return WScope;
}

/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope,
                                                     MDNode *InlinedAt) {
  LexicalScope *InlinedScope = LexicalScopeMap.lookup(InlinedAt);
  if (InlinedScope)
    return InlinedScope;

  DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt);
  InlinedScope = new LexicalScope(getOrCreateLexicalScope(InlinedLoc),
                                  DIDescriptor(Scope), InlinedAt, false);
  InlinedLexicalScopeMap[InlinedLoc] = InlinedScope;
  LexicalScopeMap[InlinedAt] = InlinedScope;
  return InlinedScope;
}

/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) {
  assert(N && "Invalid Scope encoding!");

  DIDescriptor Scope(N);
  if (Scope.isLexicalBlockFile())
    Scope = DILexicalBlockFile(Scope).getScope();
  LexicalScope *AScope = AbstractScopeMap.lookup(N);
  if (AScope)
    return AScope;

  LexicalScope *Parent = NULL;
  if (Scope.isLexicalBlock()) {
    DILexicalBlock DB(N);
    DIDescriptor ParentDesc = DB.getContext();
    Parent = getOrCreateAbstractScope(ParentDesc);
  }
  AScope = new LexicalScope(Parent, DIDescriptor(N), NULL, true);
  AbstractScopeMap[N] = AScope;
  if (DIDescriptor(N).isSubprogram())
    AbstractScopesList.push_back(AScope);
  return AScope;
}

/// constructScopeNest
void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
  assert (Scope && "Unable to calculate scop edominance graph!");
  SmallVector<LexicalScope *, 4> WorkStack;
  WorkStack.push_back(Scope);
  unsigned Counter = 0;
  while (!WorkStack.empty()) {
    LexicalScope *WS = WorkStack.back();
    const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
    bool visitedChildren = false;
    for (SmallVector<LexicalScope *, 4>::const_iterator SI = Children.begin(),
           SE = Children.end(); SI != SE; ++SI) {
      LexicalScope *ChildScope = *SI;
      if (!ChildScope->getDFSOut()) {
        WorkStack.push_back(ChildScope);
        visitedChildren = true;
        ChildScope->setDFSIn(++Counter);
        break;
      }
    }
    if (!visitedChildren) {
      WorkStack.pop_back();
      WS->setDFSOut(++Counter);
    }
  }
}

/// assignInstructionRanges - Find ranges of instructions covered by each
/// lexical scope.
void LexicalScopes::
assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
                    DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap)
{

  LexicalScope *PrevLexicalScope = NULL;
  for (SmallVectorImpl<InsnRange>::const_iterator RI = MIRanges.begin(),
         RE = MIRanges.end(); RI != RE; ++RI) {
    const InsnRange &R = *RI;
    LexicalScope *S = MI2ScopeMap.lookup(R.first);
    assert (S && "Lost LexicalScope for a machine instruction!");
    if (PrevLexicalScope && !PrevLexicalScope->dominates(S))
      PrevLexicalScope->closeInsnRange(S);
    S->openInsnRange(R.first);
    S->extendInsnRange(R.second);
    PrevLexicalScope = S;
  }

  if (PrevLexicalScope)
    PrevLexicalScope->closeInsnRange();
}

/// getMachineBasicBlocks - Populate given set using machine basic blocks which
/// have machine instructions that belong to lexical scope identified by
/// DebugLoc.
void LexicalScopes::
getMachineBasicBlocks(DebugLoc DL,
                      SmallPtrSet<const MachineBasicBlock*, 4> &MBBs) {
  MBBs.clear();
  LexicalScope *Scope = getOrCreateLexicalScope(DL);
  if (!Scope)
    return;

  if (Scope == CurrentFnLexicalScope) {
    for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
         I != E; ++I)
      MBBs.insert(I);
    return;
  }

  SmallVectorImpl<InsnRange> &InsnRanges = Scope->getRanges();
  for (SmallVector<InsnRange, 4>::iterator I = InsnRanges.begin(),
         E = InsnRanges.end(); I != E; ++I) {
    InsnRange &R = *I;
    MBBs.insert(R.first->getParent());
  }
}

/// dominates - Return true if DebugLoc's lexical scope dominates at least one
/// machine instruction's lexical scope in a given machine basic block.
bool LexicalScopes::dominates(DebugLoc DL, MachineBasicBlock *MBB) {
  LexicalScope *Scope = getOrCreateLexicalScope(DL);
  if (!Scope)
    return false;

  // Current function scope covers all basic blocks in the function.
  if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF)
    return true;

  bool Result = false;
  for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
       I != E; ++I) {
    DebugLoc IDL = I->getDebugLoc();
    if (IDL.isUnknown())
      continue;
    if (LexicalScope *IScope = getOrCreateLexicalScope(IDL))
      if (Scope->dominates(IScope))
        return true;
  }
  return Result;
}

void LexicalScope::anchor() { }

/// dump - Print data structures.
void LexicalScope::dump(unsigned Indent) const {
#ifndef NDEBUG
  raw_ostream &err = dbgs();
  err.indent(Indent);
  err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
  const MDNode *N = Desc;
  err.indent(Indent);
  N->dump();
  if (AbstractScope)
    err << std::string(Indent, ' ') << "Abstract Scope\n";

  if (!Children.empty())
    err << std::string(Indent + 2, ' ') << "Children ...\n";
  for (unsigned i = 0, e = Children.size(); i != e; ++i)
    if (Children[i] != this)
      Children[i]->dump(Indent + 2);
#endif
}

<commit_msg>Use SmallVectorImpl::iterator/const_iterator instead of SmallVector to avoid specifying the vector size.<commit_after>//===- LexicalScopes.cpp - Collecting lexical scope info ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements LexicalScopes analysis.
//
// This pass collects lexical scope information and maps machine instructions
// to respective lexical scopes.
//
//===----------------------------------------------------------------------===//

#define DEBUG_TYPE "lexicalscopes"
#include "llvm/CodeGen/LexicalScopes.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/DebugInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FormattedStream.h"
using namespace llvm;

LexicalScopes::~LexicalScopes() {
  releaseMemory();
}

/// releaseMemory - release memory.
void LexicalScopes::releaseMemory() {
  MF = NULL;
  CurrentFnLexicalScope = NULL;
  DeleteContainerSeconds(LexicalScopeMap);
  DeleteContainerSeconds(AbstractScopeMap);
  InlinedLexicalScopeMap.clear();
  AbstractScopesList.clear();
}

/// initialize - Scan machine function and constuct lexical scope nest.
void LexicalScopes::initialize(const MachineFunction &Fn) {
  releaseMemory();
  MF = &Fn;
  SmallVector<InsnRange, 4> MIRanges;
  DenseMap<const MachineInstr *, LexicalScope *> MI2ScopeMap;
  extractLexicalScopes(MIRanges, MI2ScopeMap);
  if (CurrentFnLexicalScope) {
    constructScopeNest(CurrentFnLexicalScope);
    assignInstructionRanges(MIRanges, MI2ScopeMap);
  }
}

/// extractLexicalScopes - Extract instruction ranges for each lexical scopes
/// for the given machine function.
void LexicalScopes::
extractLexicalScopes(SmallVectorImpl<InsnRange> &MIRanges,
                  DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap) {

  // Scan each instruction and create scopes. First build working set of scopes.
  for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
       I != E; ++I) {
    const MachineInstr *RangeBeginMI = NULL;
    const MachineInstr *PrevMI = NULL;
    DebugLoc PrevDL;
    for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
         II != IE; ++II) {
      const MachineInstr *MInsn = II;

      // Check if instruction has valid location information.
      const DebugLoc MIDL = MInsn->getDebugLoc();
      if (MIDL.isUnknown()) {
        PrevMI = MInsn;
        continue;
      }

      // If scope has not changed then skip this instruction.
      if (MIDL == PrevDL) {
        PrevMI = MInsn;
        continue;
      }

      // Ignore DBG_VALUE. It does not contribute to any instruction in output.
      if (MInsn->isDebugValue())
        continue;

      if (RangeBeginMI) {
        // If we have already seen a beginning of an instruction range and
        // current instruction scope does not match scope of first instruction
        // in this range then create a new instruction range.
        InsnRange R(RangeBeginMI, PrevMI);
        MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
        MIRanges.push_back(R);
      }

      // This is a beginning of a new instruction range.
      RangeBeginMI = MInsn;

      // Reset previous markers.
      PrevMI = MInsn;
      PrevDL = MIDL;
    }

    // Create last instruction range.
    if (RangeBeginMI && PrevMI && !PrevDL.isUnknown()) {
      InsnRange R(RangeBeginMI, PrevMI);
      MIRanges.push_back(R);
      MI2ScopeMap[RangeBeginMI] = getOrCreateLexicalScope(PrevDL);
    }
  }
}

/// findLexicalScope - Find lexical scope, either regular or inlined, for the
/// given DebugLoc. Return NULL if not found.
LexicalScope *LexicalScopes::findLexicalScope(DebugLoc DL) {
  MDNode *Scope = NULL;
  MDNode *IA = NULL;
  DL.getScopeAndInlinedAt(Scope, IA, MF->getFunction()->getContext());
  if (!Scope) return NULL;

  // The scope that we were created with could have an extra file - which
  // isn't what we care about in this case.
  DIDescriptor D = DIDescriptor(Scope);
  if (D.isLexicalBlockFile())
    Scope = DILexicalBlockFile(Scope).getScope();

  if (IA)
    return InlinedLexicalScopeMap.lookup(DebugLoc::getFromDILocation(IA));
  return LexicalScopeMap.lookup(Scope);
}

/// getOrCreateLexicalScope - Find lexical scope for the given DebugLoc. If
/// not available then create new lexical scope.
LexicalScope *LexicalScopes::getOrCreateLexicalScope(DebugLoc DL) {
  MDNode *Scope = NULL;
  MDNode *InlinedAt = NULL;
  DL.getScopeAndInlinedAt(Scope, InlinedAt, MF->getFunction()->getContext());

  if (InlinedAt) {
    // Create an abstract scope for inlined function.
    getOrCreateAbstractScope(Scope);
    // Create an inlined scope for inlined function.
    return getOrCreateInlinedScope(Scope, InlinedAt);
  }

  return getOrCreateRegularScope(Scope);
}

/// getOrCreateRegularScope - Find or create a regular lexical scope.
LexicalScope *LexicalScopes::getOrCreateRegularScope(MDNode *Scope) {
  DIDescriptor D = DIDescriptor(Scope);
  if (D.isLexicalBlockFile()) {
    Scope = DILexicalBlockFile(Scope).getScope();
    D = DIDescriptor(Scope);
  }

  LexicalScope *WScope = LexicalScopeMap.lookup(Scope);
  if (WScope)
    return WScope;

  LexicalScope *Parent = NULL;
  if (D.isLexicalBlock())
    Parent = getOrCreateLexicalScope(DebugLoc::getFromDILexicalBlock(Scope));
  WScope = new LexicalScope(Parent, DIDescriptor(Scope), NULL, false);
  LexicalScopeMap.insert(std::make_pair(Scope, WScope));
  if (!Parent && DIDescriptor(Scope).isSubprogram()
      && DISubprogram(Scope).describes(MF->getFunction()))
    CurrentFnLexicalScope = WScope;

  return WScope;
}

/// getOrCreateInlinedScope - Find or create an inlined lexical scope.
LexicalScope *LexicalScopes::getOrCreateInlinedScope(MDNode *Scope,
                                                     MDNode *InlinedAt) {
  LexicalScope *InlinedScope = LexicalScopeMap.lookup(InlinedAt);
  if (InlinedScope)
    return InlinedScope;

  DebugLoc InlinedLoc = DebugLoc::getFromDILocation(InlinedAt);
  InlinedScope = new LexicalScope(getOrCreateLexicalScope(InlinedLoc),
                                  DIDescriptor(Scope), InlinedAt, false);
  InlinedLexicalScopeMap[InlinedLoc] = InlinedScope;
  LexicalScopeMap[InlinedAt] = InlinedScope;
  return InlinedScope;
}

/// getOrCreateAbstractScope - Find or create an abstract lexical scope.
LexicalScope *LexicalScopes::getOrCreateAbstractScope(const MDNode *N) {
  assert(N && "Invalid Scope encoding!");

  DIDescriptor Scope(N);
  if (Scope.isLexicalBlockFile())
    Scope = DILexicalBlockFile(Scope).getScope();
  LexicalScope *AScope = AbstractScopeMap.lookup(N);
  if (AScope)
    return AScope;

  LexicalScope *Parent = NULL;
  if (Scope.isLexicalBlock()) {
    DILexicalBlock DB(N);
    DIDescriptor ParentDesc = DB.getContext();
    Parent = getOrCreateAbstractScope(ParentDesc);
  }
  AScope = new LexicalScope(Parent, DIDescriptor(N), NULL, true);
  AbstractScopeMap[N] = AScope;
  if (DIDescriptor(N).isSubprogram())
    AbstractScopesList.push_back(AScope);
  return AScope;
}

/// constructScopeNest
void LexicalScopes::constructScopeNest(LexicalScope *Scope) {
  assert (Scope && "Unable to calculate scop edominance graph!");
  SmallVector<LexicalScope *, 4> WorkStack;
  WorkStack.push_back(Scope);
  unsigned Counter = 0;
  while (!WorkStack.empty()) {
    LexicalScope *WS = WorkStack.back();
    const SmallVectorImpl<LexicalScope *> &Children = WS->getChildren();
    bool visitedChildren = false;
    for (SmallVectorImpl<LexicalScope *>::const_iterator SI = Children.begin(),
           SE = Children.end(); SI != SE; ++SI) {
      LexicalScope *ChildScope = *SI;
      if (!ChildScope->getDFSOut()) {
        WorkStack.push_back(ChildScope);
        visitedChildren = true;
        ChildScope->setDFSIn(++Counter);
        break;
      }
    }
    if (!visitedChildren) {
      WorkStack.pop_back();
      WS->setDFSOut(++Counter);
    }
  }
}

/// assignInstructionRanges - Find ranges of instructions covered by each
/// lexical scope.
void LexicalScopes::
assignInstructionRanges(SmallVectorImpl<InsnRange> &MIRanges,
                    DenseMap<const MachineInstr *, LexicalScope *> &MI2ScopeMap)
{

  LexicalScope *PrevLexicalScope = NULL;
  for (SmallVectorImpl<InsnRange>::const_iterator RI = MIRanges.begin(),
         RE = MIRanges.end(); RI != RE; ++RI) {
    const InsnRange &R = *RI;
    LexicalScope *S = MI2ScopeMap.lookup(R.first);
    assert (S && "Lost LexicalScope for a machine instruction!");
    if (PrevLexicalScope && !PrevLexicalScope->dominates(S))
      PrevLexicalScope->closeInsnRange(S);
    S->openInsnRange(R.first);
    S->extendInsnRange(R.second);
    PrevLexicalScope = S;
  }

  if (PrevLexicalScope)
    PrevLexicalScope->closeInsnRange();
}

/// getMachineBasicBlocks - Populate given set using machine basic blocks which
/// have machine instructions that belong to lexical scope identified by
/// DebugLoc.
void LexicalScopes::
getMachineBasicBlocks(DebugLoc DL,
                      SmallPtrSet<const MachineBasicBlock*, 4> &MBBs) {
  MBBs.clear();
  LexicalScope *Scope = getOrCreateLexicalScope(DL);
  if (!Scope)
    return;

  if (Scope == CurrentFnLexicalScope) {
    for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
         I != E; ++I)
      MBBs.insert(I);
    return;
  }

  SmallVectorImpl<InsnRange> &InsnRanges = Scope->getRanges();
  for (SmallVectorImpl<InsnRange>::iterator I = InsnRanges.begin(),
         E = InsnRanges.end(); I != E; ++I) {
    InsnRange &R = *I;
    MBBs.insert(R.first->getParent());
  }
}

/// dominates - Return true if DebugLoc's lexical scope dominates at least one
/// machine instruction's lexical scope in a given machine basic block.
bool LexicalScopes::dominates(DebugLoc DL, MachineBasicBlock *MBB) {
  LexicalScope *Scope = getOrCreateLexicalScope(DL);
  if (!Scope)
    return false;

  // Current function scope covers all basic blocks in the function.
  if (Scope == CurrentFnLexicalScope && MBB->getParent() == MF)
    return true;

  bool Result = false;
  for (MachineBasicBlock::iterator I = MBB->begin(), E = MBB->end();
       I != E; ++I) {
    DebugLoc IDL = I->getDebugLoc();
    if (IDL.isUnknown())
      continue;
    if (LexicalScope *IScope = getOrCreateLexicalScope(IDL))
      if (Scope->dominates(IScope))
        return true;
  }
  return Result;
}

void LexicalScope::anchor() { }

/// dump - Print data structures.
void LexicalScope::dump(unsigned Indent) const {
#ifndef NDEBUG
  raw_ostream &err = dbgs();
  err.indent(Indent);
  err << "DFSIn: " << DFSIn << " DFSOut: " << DFSOut << "\n";
  const MDNode *N = Desc;
  err.indent(Indent);
  N->dump();
  if (AbstractScope)
    err << std::string(Indent, ' ') << "Abstract Scope\n";

  if (!Children.empty())
    err << std::string(Indent + 2, ' ') << "Children ...\n";
  for (unsigned i = 0, e = Children.size(); i != e; ++i)
    if (Children[i] != this)
      Children[i]->dump(Indent + 2);
#endif
}

<|endoftext|>


<commit_before>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include "cling/Interpreter/CIFactory.h"

#include "DeclCollector.h"

#include "clang/AST/ASTContext.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Job.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Preprocessor.h"

#include "llvm/IR/LLVMContext.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"

#include <ctime>

using namespace clang;

namespace cling {
  //
  //  Dummy function so we can use dladdr to find the executable path.
  //
  void locate_cling_executable()
  {
  }

  /// \brief Retrieves the clang CC1 specific flags out of the compilation's
  /// jobs. Returns NULL on error.
  static const clang::driver::ArgStringList
  *GetCC1Arguments(clang::DiagnosticsEngine *Diagnostics,
                   clang::driver::Compilation *Compilation) {
    // We expect to get back exactly one Command job, if we didn't something
    // failed. Extract that job from the Compilation.
    const clang::driver::JobList &Jobs = Compilation->getJobs();
    if (!Jobs.size() || !isa<clang::driver::Command>(*Jobs.begin())) {
      // diagnose this...
      return NULL;
    }

    // The one job we find should be to invoke clang again.
    const clang::driver::Command *Cmd
      = cast<clang::driver::Command>(*Jobs.begin());
    if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
      // diagnose this...
      return NULL;
    }

    return &Cmd->getArguments();
  }

  CompilerInstance* CIFactory::createCI(llvm::StringRef code,
                                        int argc,
                                        const char* const *argv,
                                        const char* llvmdir) {
    return createCI(llvm::MemoryBuffer::getMemBuffer(code), argc, argv,
                    llvmdir);
  }

  CompilerInstance* CIFactory::createCI(llvm::MemoryBuffer* buffer,
                                        int argc,
                                        const char* const *argv,
                                        const char* llvmdir) {
    // Create an instance builder, passing the llvmdir and arguments.
    //
    //  Initialize the llvm library.
    llvm::InitializeNativeTarget();
    llvm::InitializeAllAsmPrinters();
    llvm::sys::Path resource_path;
    if (llvmdir) {
      resource_path = llvmdir;
      resource_path.appendComponent("lib");
      resource_path.appendComponent("clang");
      resource_path.appendComponent(CLANG_VERSION_STRING);
    } else {
      // FIXME: The first arg really does need to be argv[0] on FreeBSD.
      //
      // Note: The second arg is not used for Apple, FreeBSD, Linux,
      //       or cygwin, and can only be used on systems which support
      //       the use of dladdr().
      //
      // Note: On linux and cygwin this uses /proc/self/exe to find the path.
      //
      // Note: On Apple it uses _NSGetExecutablePath().
      //
      // Note: On FreeBSD it uses getprogpath().
      //
      // Note: Otherwise it uses dladdr().
      //
      resource_path
        = CompilerInvocation::GetResourcesPath("cling",
                                       (void*)(intptr_t) locate_cling_executable
                                               );
    }
    if (!resource_path.canRead()) {
      llvm::errs()
        << "ERROR in cling::CIFactory::createCI():\n  resource directory "
        << resource_path.str() << " not found!\n";
      resource_path = "";
    }

    //______________________________________
    DiagnosticOptions* DefaultDiagnosticOptions = new DiagnosticOptions();
    DefaultDiagnosticOptions->ShowColors = llvm::sys::Process::StandardErrHasColors() ? 1 : 0;
    TextDiagnosticPrinter* DiagnosticPrinter
      = new TextDiagnosticPrinter(llvm::errs(), DefaultDiagnosticOptions);
    llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(new DiagnosticIDs());
    DiagnosticsEngine* Diagnostics
      = new DiagnosticsEngine(DiagIDs, DefaultDiagnosticOptions,
                              DiagnosticPrinter, /*Owns it*/ true); // LEAKS!

    std::vector<const char*> argvCompile(argv, argv + argc);
    // We do C++ by default; append right after argv[0] name
    // Only insert it if there is no other "-x":
    bool haveMinusX = false;
    for (const char* const* iarg = argv; !haveMinusX && iarg < argv + argc;
         ++iarg) {
      haveMinusX = !strcmp(*iarg, "-x");
    }
    if (!haveMinusX) {
      argvCompile.insert(argvCompile.begin() + 1,"-x");
      argvCompile.insert(argvCompile.begin() + 2, "c++");
    }
    argvCompile.push_back("-c");
    argvCompile.push_back("-");

    clang::driver::Driver Driver(argv[0], llvm::sys::getDefaultTargetTriple(),
                                 "cling.out",
                                 *Diagnostics);
    //Driver.setWarnMissingInput(false);
    Driver.setCheckInputsExist(false); // think foo.C(12)
    llvm::ArrayRef<const char*>RF(&(argvCompile[0]), argvCompile.size());
    llvm::OwningPtr<clang::driver::Compilation>
      Compilation(Driver.BuildCompilation(RF));
    const clang::driver::ArgStringList* CC1Args
      = GetCC1Arguments(Diagnostics, Compilation.get());
    if (CC1Args == NULL) {
      return 0;
    }
    clang::CompilerInvocation*
      Invocation = new clang::CompilerInvocation;
    clang::CompilerInvocation::CreateFromArgs(*Invocation, CC1Args->data() + 1,
                                              CC1Args->data() + CC1Args->size(),
                                              *Diagnostics);
    Invocation->getFrontendOpts().DisableFree = true;

    if (Invocation->getHeaderSearchOpts().UseBuiltinIncludes &&
        !resource_path.empty()) {
      // Update ResourceDir
      // header search opts' entry for resource_path/include isn't
      // updated by providing a new resource path; update it manually.
      clang::HeaderSearchOptions& Opts = Invocation->getHeaderSearchOpts();
      llvm::sys::Path oldResInc(Opts.ResourceDir);
      oldResInc.appendComponent("include");
      llvm::sys::Path newResInc(resource_path);
      newResInc.appendComponent("include");
      bool foundOldResInc = false;
      for (unsigned i = 0, e = Opts.UserEntries.size();
           !foundOldResInc && i != e; ++i) {
        HeaderSearchOptions::Entry &E = Opts.UserEntries[i];
        if (!E.IsFramework && E.Group == clang::frontend::System
            && E.IgnoreSysRoot && oldResInc.str() == E.Path) {
          E.Path = newResInc.str();
          foundOldResInc = true;
        }
      }

      Opts.ResourceDir = resource_path.str();
    }

    // Create and setup a compiler instance.
    CompilerInstance* CI = new CompilerInstance();
    CI->setInvocation(Invocation);

    CI->createDiagnostics(DiagnosticPrinter, /*ShouldOwnClient=*/ false,
                          /*ShouldCloneClient=*/ false);
    {
      //
      //  Buffer the error messages while we process
      //  the compiler options.
      //

      // Set the language options, which cling needs
      SetClingCustomLangOpts(CI->getLangOpts());

      CI->getInvocation().getPreprocessorOpts().addMacroDef("__CLING__");
      if (CI->getLangOpts().CPlusPlus11 == 1) {
        // http://llvm.org/bugs/show_bug.cgi?id=13530
        CI->getInvocation().getPreprocessorOpts()
          .addMacroDef("__CLING__CXX11");
      }

      if (CI->getDiagnostics().hasErrorOccurred()) {
        delete CI;
        CI = 0;
        return 0;
      }
    }
    CI->setTarget(TargetInfo::CreateTargetInfo(CI->getDiagnostics(),
                                               &Invocation->getTargetOpts()));
    if (!CI->hasTarget()) {
      delete CI;
      CI = 0;
      return 0;
    }
    CI->getTarget().setForcedLangOptions(CI->getLangOpts());
    SetClingTargetLangOpts(CI->getLangOpts(), CI->getTarget());
    if (CI->getTarget().getTriple().getOS() == llvm::Triple::Cygwin) {
      // clang "forgets" the basic arch part needed by winnt.h:
      if (CI->getTarget().getTriple().getArch() == llvm::Triple::x86) {
        CI->getInvocation().getPreprocessorOpts().addMacroDef("_X86_=1");
      } else if (CI->getTarget().getTriple().getArch()
                 == llvm::Triple::x86_64) {
        CI->getInvocation().getPreprocessorOpts().addMacroDef("__x86_64=1");
      } else {
        llvm::errs() << "Warning: unhandled target architecture "
                     << CI->getTarget().getTriple().getArchName() << '\n';
      }
    }

    // Set up source and file managers
    CI->createFileManager();
    CI->createSourceManager(CI->getFileManager());

    // Set up the memory buffer
    if (buffer)
      CI->getSourceManager().createMainFileIDForMemBuffer(buffer);
    else {
      // As main file we want
      // * a virtual file that is claiming to be huge
      // * with an empty memory buffer attached (to bring the content)
      SourceManager& SM = CI->getSourceManager();
      FileManager& FM = SM.getFileManager();
      // Build the virtual file
      const char* Filename = "InteractiveInputLineIncluder.h";
      const std::string& CGOptsMainFileName
        = CI->getInvocation().getCodeGenOpts().MainFileName;
      if (!CGOptsMainFileName.empty())
        Filename = CGOptsMainFileName.c_str();
      const FileEntry* FE
        = FM.getVirtualFile(Filename, 1U << 15U, time(0));
      FileID MainFileID = SM.createMainFileID(FE, SrcMgr::C_User);
      const SrcMgr::SLocEntry& MainFileSLocE = SM.getSLocEntry(MainFileID);
      const SrcMgr::ContentCache* MainFileCC
        = MainFileSLocE.getFile().getContentCache();
      llvm::MemoryBuffer* MainFileMB
        = llvm::MemoryBuffer::getMemBuffer("/*CLING MAIN FILE*/\n");
      const_cast<SrcMgr::ContentCache*>(MainFileCC)->setBuffer(MainFileMB);
    }

    // Set up the preprocessor
    CI->createPreprocessor();
    Preprocessor& PP = CI->getPreprocessor();
    PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                           PP.getLangOpts());

    // Set up the ASTContext
    ASTContext *Ctx = new ASTContext(CI->getLangOpts(),
                                     PP.getSourceManager(), &CI->getTarget(),
                                     PP.getIdentifierTable(),
                                     PP.getSelectorTable(), PP.getBuiltinInfo(),
                                     /*size_reserve*/0, /*DelayInit*/false);
    CI->setASTContext(Ctx);

    // Set up the ASTConsumers
    CI->setASTConsumer(new DeclCollector());

    // Set up Sema
    CodeCompleteConsumer* CCC = 0;
    CI->createSema(TU_Complete, CCC);

    // Set CodeGen options
    // CI->getCodeGenOpts().DebugInfo = 1; // want debug info
    // CI->getCodeGenOpts().EmitDeclMetadata = 1; // For unloading, for later
    CI->getCodeGenOpts().OptimizationLevel = 0; // see pure SSA, that comes out
    CI->getCodeGenOpts().CXXCtorDtorAliases = 0; // aliasing the complete
                                                 // ctor to the base ctor causes
                                                 // the JIT to crash
    // When asserts are on, TURN ON not compare the VerifyModule
    assert(CI->getCodeGenOpts().VerifyModule = 1);

    return CI;
  }

  void CIFactory::SetClingCustomLangOpts(LangOptions& Opts) {
    Opts.EmitAllDecls = 0;
    Opts.Exceptions = 1;
    Opts.CXXExceptions = 1;
    Opts.Deprecated = 1;
    //Opts.Modules = 1;

    // C++11 is turned on if cling is built with C++11: it's an interperter;
    // cross-language compilation doesn't make sense.
    // Extracted from Boost/config/compiler.
    // SunProCC has no C++11.
    // VisualC's support is not obvious to extract from Boost...
#if /*GCC*/ (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__))   \
  || /*clang*/ (defined(__has_feature) && __has_feature(cxx_decltype))   \
  || /*ICC*/ ((!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && defined(__INTEL_COMPILER) && (__STDC_HOSTED__ && (__INTEL_COMPILER <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__))
    Opts.CPlusPlus11 = 1;
#endif

  }

  void CIFactory::SetClingTargetLangOpts(LangOptions& Opts,
                                         const TargetInfo& Target) {
    if (Target.getTriple().getOS() == llvm::Triple::Win32) {
      Opts.MicrosoftExt = 1;
      Opts.MSCVersion = 1300;
      // Should fix http://llvm.org/bugs/show_bug.cgi?id=10528
      Opts.DelayedTemplateParsing = 1;
    } else {
      Opts.MicrosoftExt = 0;
    }
  }
} // end namespace
<commit_msg>Add clarification comment.<commit_after>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include "cling/Interpreter/CIFactory.h"

#include "DeclCollector.h"

#include "clang/AST/ASTContext.h"
#include "clang/Basic/TargetInfo.h"
#include "clang/Basic/Version.h"
#include "clang/Driver/ArgList.h"
#include "clang/Driver/Compilation.h"
#include "clang/Driver/Driver.h"
#include "clang/Driver/Job.h"
#include "clang/Driver/Tool.h"
#include "clang/Frontend/TextDiagnosticPrinter.h"
#include "clang/Lex/Preprocessor.h"

#include "llvm/IR/LLVMContext.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Support/Host.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"

#include <ctime>

using namespace clang;

namespace cling {
  //
  //  Dummy function so we can use dladdr to find the executable path.
  //
  void locate_cling_executable()
  {
  }

  /// \brief Retrieves the clang CC1 specific flags out of the compilation's
  /// jobs. Returns NULL on error.
  static const clang::driver::ArgStringList
  *GetCC1Arguments(clang::DiagnosticsEngine *Diagnostics,
                   clang::driver::Compilation *Compilation) {
    // We expect to get back exactly one Command job, if we didn't something
    // failed. Extract that job from the Compilation.
    const clang::driver::JobList &Jobs = Compilation->getJobs();
    if (!Jobs.size() || !isa<clang::driver::Command>(*Jobs.begin())) {
      // diagnose this...
      return NULL;
    }

    // The one job we find should be to invoke clang again.
    const clang::driver::Command *Cmd
      = cast<clang::driver::Command>(*Jobs.begin());
    if (llvm::StringRef(Cmd->getCreator().getName()) != "clang") {
      // diagnose this...
      return NULL;
    }

    return &Cmd->getArguments();
  }

  CompilerInstance* CIFactory::createCI(llvm::StringRef code,
                                        int argc,
                                        const char* const *argv,
                                        const char* llvmdir) {
    return createCI(llvm::MemoryBuffer::getMemBuffer(code), argc, argv,
                    llvmdir);
  }

  CompilerInstance* CIFactory::createCI(llvm::MemoryBuffer* buffer,
                                        int argc,
                                        const char* const *argv,
                                        const char* llvmdir) {
    // Create an instance builder, passing the llvmdir and arguments.
    //
    //  Initialize the llvm library.
    llvm::InitializeNativeTarget();
    llvm::InitializeAllAsmPrinters();
    llvm::sys::Path resource_path;
    if (llvmdir) {
      resource_path = llvmdir;
      resource_path.appendComponent("lib");
      resource_path.appendComponent("clang");
      resource_path.appendComponent(CLANG_VERSION_STRING);
    } else {
      // FIXME: The first arg really does need to be argv[0] on FreeBSD.
      //
      // Note: The second arg is not used for Apple, FreeBSD, Linux,
      //       or cygwin, and can only be used on systems which support
      //       the use of dladdr().
      //
      // Note: On linux and cygwin this uses /proc/self/exe to find the path.
      //
      // Note: On Apple it uses _NSGetExecutablePath().
      //
      // Note: On FreeBSD it uses getprogpath().
      //
      // Note: Otherwise it uses dladdr().
      //
      resource_path
        = CompilerInvocation::GetResourcesPath("cling",
                                       (void*)(intptr_t) locate_cling_executable
                                               );
    }
    if (!resource_path.canRead()) {
      llvm::errs()
        << "ERROR in cling::CIFactory::createCI():\n  resource directory "
        << resource_path.str() << " not found!\n";
      resource_path = "";
    }

    //______________________________________
    DiagnosticOptions* DefaultDiagnosticOptions = new DiagnosticOptions();
    DefaultDiagnosticOptions->ShowColors = llvm::sys::Process::StandardErrHasColors() ? 1 : 0;
    TextDiagnosticPrinter* DiagnosticPrinter
      = new TextDiagnosticPrinter(llvm::errs(), DefaultDiagnosticOptions);
    llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagIDs(new DiagnosticIDs());
    DiagnosticsEngine* Diagnostics
      = new DiagnosticsEngine(DiagIDs, DefaultDiagnosticOptions,
                              DiagnosticPrinter, /*Owns it*/ true); // LEAKS!

    std::vector<const char*> argvCompile(argv, argv + argc);
    // We do C++ by default; append right after argv[0] name
    // Only insert it if there is no other "-x":
    bool haveMinusX = false;
    for (const char* const* iarg = argv; !haveMinusX && iarg < argv + argc;
         ++iarg) {
      haveMinusX = !strcmp(*iarg, "-x");
    }
    if (!haveMinusX) {
      argvCompile.insert(argvCompile.begin() + 1,"-x");
      argvCompile.insert(argvCompile.begin() + 2, "c++");
    }
    argvCompile.push_back("-c");
    argvCompile.push_back("-");

    clang::driver::Driver Driver(argv[0], llvm::sys::getDefaultTargetTriple(),
                                 "cling.out",
                                 *Diagnostics);
    //Driver.setWarnMissingInput(false);
    Driver.setCheckInputsExist(false); // think foo.C(12)
    llvm::ArrayRef<const char*>RF(&(argvCompile[0]), argvCompile.size());
    llvm::OwningPtr<clang::driver::Compilation>
      Compilation(Driver.BuildCompilation(RF));
    const clang::driver::ArgStringList* CC1Args
      = GetCC1Arguments(Diagnostics, Compilation.get());
    if (CC1Args == NULL) {
      return 0;
    }
    clang::CompilerInvocation*
      Invocation = new clang::CompilerInvocation;
    clang::CompilerInvocation::CreateFromArgs(*Invocation, CC1Args->data() + 1,
                                              CC1Args->data() + CC1Args->size(),
                                              *Diagnostics);
    Invocation->getFrontendOpts().DisableFree = true;

    if (Invocation->getHeaderSearchOpts().UseBuiltinIncludes &&
        !resource_path.empty()) {
      // Update ResourceDir
      // header search opts' entry for resource_path/include isn't
      // updated by providing a new resource path; update it manually.
      clang::HeaderSearchOptions& Opts = Invocation->getHeaderSearchOpts();
      llvm::sys::Path oldResInc(Opts.ResourceDir);
      oldResInc.appendComponent("include");
      llvm::sys::Path newResInc(resource_path);
      newResInc.appendComponent("include");
      bool foundOldResInc = false;
      for (unsigned i = 0, e = Opts.UserEntries.size();
           !foundOldResInc && i != e; ++i) {
        HeaderSearchOptions::Entry &E = Opts.UserEntries[i];
        if (!E.IsFramework && E.Group == clang::frontend::System
            && E.IgnoreSysRoot && oldResInc.str() == E.Path) {
          E.Path = newResInc.str();
          foundOldResInc = true;
        }
      }

      Opts.ResourceDir = resource_path.str();
    }

    // Create and setup a compiler instance.
    CompilerInstance* CI = new CompilerInstance();
    CI->setInvocation(Invocation);

    CI->createDiagnostics(DiagnosticPrinter, /*ShouldOwnClient=*/ false,
                          /*ShouldCloneClient=*/ false);
    {
      //
      //  Buffer the error messages while we process
      //  the compiler options.
      //

      // Set the language options, which cling needs
      SetClingCustomLangOpts(CI->getLangOpts());

      CI->getInvocation().getPreprocessorOpts().addMacroDef("__CLING__");
      if (CI->getLangOpts().CPlusPlus11 == 1) {
        // http://llvm.org/bugs/show_bug.cgi?id=13530
        CI->getInvocation().getPreprocessorOpts()
          .addMacroDef("__CLING__CXX11");
      }

      if (CI->getDiagnostics().hasErrorOccurred()) {
        delete CI;
        CI = 0;
        return 0;
      }
    }
    CI->setTarget(TargetInfo::CreateTargetInfo(CI->getDiagnostics(),
                                               &Invocation->getTargetOpts()));
    if (!CI->hasTarget()) {
      delete CI;
      CI = 0;
      return 0;
    }
    CI->getTarget().setForcedLangOptions(CI->getLangOpts());
    SetClingTargetLangOpts(CI->getLangOpts(), CI->getTarget());
    if (CI->getTarget().getTriple().getOS() == llvm::Triple::Cygwin) {
      // clang "forgets" the basic arch part needed by winnt.h:
      if (CI->getTarget().getTriple().getArch() == llvm::Triple::x86) {
        CI->getInvocation().getPreprocessorOpts().addMacroDef("_X86_=1");
      } else if (CI->getTarget().getTriple().getArch()
                 == llvm::Triple::x86_64) {
        CI->getInvocation().getPreprocessorOpts().addMacroDef("__x86_64=1");
      } else {
        llvm::errs() << "Warning: unhandled target architecture "
                     << CI->getTarget().getTriple().getArchName() << '\n';
      }
    }

    // Set up source and file managers
    CI->createFileManager();
    CI->createSourceManager(CI->getFileManager());

    // Set up the memory buffer
    if (buffer)
      CI->getSourceManager().createMainFileIDForMemBuffer(buffer);
    else {
      // As main file we want
      // * a virtual file that is claiming to be huge
      // * with an empty memory buffer attached (to bring the content)
      SourceManager& SM = CI->getSourceManager();
      FileManager& FM = SM.getFileManager();
      // Build the virtual file
      const char* Filename = "InteractiveInputLineIncluder.h";
      const std::string& CGOptsMainFileName
        = CI->getInvocation().getCodeGenOpts().MainFileName;
      if (!CGOptsMainFileName.empty())
        Filename = CGOptsMainFileName.c_str();
      const FileEntry* FE
        = FM.getVirtualFile(Filename, 1U << 15U, time(0));
      FileID MainFileID = SM.createMainFileID(FE, SrcMgr::C_User);
      const SrcMgr::SLocEntry& MainFileSLocE = SM.getSLocEntry(MainFileID);
      const SrcMgr::ContentCache* MainFileCC
        = MainFileSLocE.getFile().getContentCache();
      llvm::MemoryBuffer* MainFileMB
        = llvm::MemoryBuffer::getMemBuffer("/*CLING MAIN FILE*/\n");
      const_cast<SrcMgr::ContentCache*>(MainFileCC)->setBuffer(MainFileMB);
    }

    // Set up the preprocessor
    CI->createPreprocessor();
    Preprocessor& PP = CI->getPreprocessor();
    PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(),
                                           PP.getLangOpts());

    // Set up the ASTContext
    ASTContext *Ctx = new ASTContext(CI->getLangOpts(),
                                     PP.getSourceManager(), &CI->getTarget(),
                                     PP.getIdentifierTable(),
                                     PP.getSelectorTable(), PP.getBuiltinInfo(),
                                     /*size_reserve*/0, /*DelayInit*/false);
    CI->setASTContext(Ctx);

    // Set up the ASTConsumers
    CI->setASTConsumer(new DeclCollector());

    // Set up Sema
    CodeCompleteConsumer* CCC = 0;
    CI->createSema(TU_Complete, CCC);

    // Set CodeGen options
    // CI->getCodeGenOpts().DebugInfo = 1; // want debug info
    // CI->getCodeGenOpts().EmitDeclMetadata = 1; // For unloading, for later
    CI->getCodeGenOpts().OptimizationLevel = 0; // see pure SSA, that comes out
    CI->getCodeGenOpts().CXXCtorDtorAliases = 0; // aliasing the complete
                                                 // ctor to the base ctor causes
                                                 // the JIT to crash
    // When asserts are on, TURN ON not compare the VerifyModule
    assert(CI->getCodeGenOpts().VerifyModule = 1);

    return CI;
  }

  void CIFactory::SetClingCustomLangOpts(LangOptions& Opts) {
    Opts.EmitAllDecls = 0; // Otherwise if PCH attached will codegen all decls.
    Opts.Exceptions = 1;
    Opts.CXXExceptions = 1;
    Opts.Deprecated = 1;
    //Opts.Modules = 1;

    // C++11 is turned on if cling is built with C++11: it's an interperter;
    // cross-language compilation doesn't make sense.
    // Extracted from Boost/config/compiler.
    // SunProCC has no C++11.
    // VisualC's support is not obvious to extract from Boost...
#if /*GCC*/ (defined(__GNUC__) && defined(__GXX_EXPERIMENTAL_CXX0X__))   \
  || /*clang*/ (defined(__has_feature) && __has_feature(cxx_decltype))   \
  || /*ICC*/ ((!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && defined(__INTEL_COMPILER) && (__STDC_HOSTED__ && (__INTEL_COMPILER <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__))
    Opts.CPlusPlus11 = 1;
#endif

  }

  void CIFactory::SetClingTargetLangOpts(LangOptions& Opts,
                                         const TargetInfo& Target) {
    if (Target.getTriple().getOS() == llvm::Triple::Win32) {
      Opts.MicrosoftExt = 1;
      Opts.MSCVersion = 1300;
      // Should fix http://llvm.org/bugs/show_bug.cgi?id=10528
      Opts.DelayedTemplateParsing = 1;
    } else {
      Opts.MicrosoftExt = 0;
    }
  }
} // end namespace
<|endoftext|>


<commit_before>/*
 NUI3 - C++ cross-platform GUI framework for OpenGL based applications
 Copyright (C) 2002-2003 Sebastien Metrot

 licence: see nui3/LICENCE.TXT
 */

#include "nui.h"
#include "nuiMemorySound.h"
#include "nuiWaveReader.h"
#include "nuiAiffReader.h"
#include "nuiAudioDecoder.h"

#include "nuiMemoryVoice.h"

nuiMemorySound::nuiMemorySound(const nglPath& rPath)
: mLength(0),
  mPath(rPath)
{
  mType = eMemory;
  LoadSamples();
  mID = nuiSound::GetStringID(rPath, mType);
}

nuiMemorySound::nuiMemorySound(const nglString& rSoundID, nglIStream* pStream)
: mLength(0)
{
  mType = eMemory;
  LoadSamples(pStream);
  mID = rSoundID;
}

nuiMemorySound::~nuiMemorySound()
{
  for (int32 c = 0; c < mSamples.size(); c++)
    delete[] mSamples[c];
}

bool nuiMemorySound::LoadSamples(nglIStream* pSStream)
{
  nglIStream* pStream = pSStream;

  if (!mPath.Exists() && !pStream)
  {
    NGL_OUT("nuiMemorySound: file '%ls' does not exist\n", mPath.GetPathName().GetChars());
    return false;
  }

  if (!pStream)
  {
    pStream = mPath.OpenRead();
  }

  if (!pStream)
  {
    NGL_OUT("nuiMemorySound: stream '%s' can't be open\n", mPath.GetPathName().GetChars());
    return false;
  }

  nuiSampleReader* pReader = NULL;
  nuiSampleInfo info;

  pReader = new nuiWaveReader(*pStream);
  if (!pReader->GetInfo(info))
  {
    delete pReader;
    pReader = new nuiAiffReader(*pStream);
    if (!pReader->GetInfo(info))
    {
      delete pReader;
      pReader = new nuiAudioDecoder(*pStream);
      if (!pReader->GetInfo(info))
      {
        NGL_OUT(_T("Can't load this audio file: %s (reader can't be created)\n"), mPath.GetNodeName().GetChars());
        delete pReader;
        if (!pSStream)
          delete pStream;
        return false;
      }
    }
  }

  int32 length = info.GetSampleFrames();
  int32 channels = info.GetChannels();
  std::vector<void*> temp;
  for (int32 c = 0; c < channels; c++)
  {
    float* pBuffer = new float[length];
    mSamples.push_back(pBuffer);

    temp.push_back((void*)mSamples[c]);
  }

  mLength = pReader->ReadDE(temp, length, eSampleFloat32);
  delete pReader;
  if (!pSStream)
    delete pStream;
}

nuiVoice* nuiMemorySound::GetVoiceInternal()
{
  nuiVoice* pVoice = new nuiMemoryVoice(this);
  return pVoice;
}

int32 nuiMemorySound::ReadSamples(const std::vector<float*>& rBuffers, int64 position, int32 SampleFrames)
{
  if (position >= mLength)
    return 0;

  int32 todo = MIN(SampleFrames, mLength - position);
  for (int32 c = 0; c < rBuffers.size(); c++)
  {
    int32 inChannel = c < mSamples.size() ? c : (mSamples.size() - 1);
    memcpy(rBuffers[c], mSamples[inChannel] + position, todo * sizeof(float));
  }

  return todo;
}

int32 nuiMemorySound::GetSampleFrames() const
{
  return mLength;
}

int32 nuiMemorySound::GetChannels()const
{
  return mSamples.size();
}

<commit_msg>fixed %ls...<commit_after>/*
 NUI3 - C++ cross-platform GUI framework for OpenGL based applications
 Copyright (C) 2002-2003 Sebastien Metrot

 licence: see nui3/LICENCE.TXT
 */

#include "nui.h"
#include "nuiMemorySound.h"
#include "nuiWaveReader.h"
#include "nuiAiffReader.h"
#include "nuiAudioDecoder.h"

#include "nuiMemoryVoice.h"

nuiMemorySound::nuiMemorySound(const nglPath& rPath)
: mLength(0),
  mPath(rPath)
{
  mType = eMemory;
  LoadSamples();
  mID = nuiSound::GetStringID(rPath, mType);
}

nuiMemorySound::nuiMemorySound(const nglString& rSoundID, nglIStream* pStream)
: mLength(0)
{
  mType = eMemory;
  LoadSamples(pStream);
  mID = rSoundID;
}

nuiMemorySound::~nuiMemorySound()
{
  for (int32 c = 0; c < mSamples.size(); c++)
    delete[] mSamples[c];
}

bool nuiMemorySound::LoadSamples(nglIStream* pSStream)
{
  nglIStream* pStream = pSStream;

  if (!mPath.Exists() && !pStream)
  {
    NGL_OUT("nuiMemorySound: file '%s' does not exist\n", mPath.GetPathName().GetChars());
    return false;
  }

  if (!pStream)
  {
    pStream = mPath.OpenRead();
  }

  if (!pStream)
  {
    NGL_OUT("nuiMemorySound: stream '%s' can't be open\n", mPath.GetPathName().GetChars());
    return false;
  }

  nuiSampleReader* pReader = NULL;
  nuiSampleInfo info;

  pReader = new nuiWaveReader(*pStream);
  if (!pReader->GetInfo(info))
  {
    delete pReader;
    pReader = new nuiAiffReader(*pStream);
    if (!pReader->GetInfo(info))
    {
      delete pReader;
      pReader = new nuiAudioDecoder(*pStream);
      if (!pReader->GetInfo(info))
      {
        NGL_OUT(_T("Can't load this audio file: %s (reader can't be created)\n"), mPath.GetNodeName().GetChars());
        delete pReader;
        if (!pSStream)
          delete pStream;
        return false;
      }
    }
  }

  int32 length = info.GetSampleFrames();
  int32 channels = info.GetChannels();
  std::vector<void*> temp;
  for (int32 c = 0; c < channels; c++)
  {
    float* pBuffer = new float[length];
    mSamples.push_back(pBuffer);

    temp.push_back((void*)mSamples[c]);
  }

  mLength = pReader->ReadDE(temp, length, eSampleFloat32);
  delete pReader;
  if (!pSStream)
    delete pStream;
}

nuiVoice* nuiMemorySound::GetVoiceInternal()
{
  nuiVoice* pVoice = new nuiMemoryVoice(this);
  return pVoice;
}

int32 nuiMemorySound::ReadSamples(const std::vector<float*>& rBuffers, int64 position, int32 SampleFrames)
{
  if (position >= mLength)
    return 0;

  int32 todo = MIN(SampleFrames, mLength - position);
  for (int32 c = 0; c < rBuffers.size(); c++)
  {
    int32 inChannel = c < mSamples.size() ? c : (mSamples.size() - 1);
    memcpy(rBuffers[c], mSamples[inChannel] + position, todo * sizeof(float));
  }

  return todo;
}

int32 nuiMemorySound::GetSampleFrames() const
{
  return mLength;
}

int32 nuiMemorySound::GetChannels()const
{
  return mSamples.size();
}

<|endoftext|>