<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: hierarchyuri.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: kz $ $Date: 2007-05-10 13:05:09 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 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
 *
 ************************************************************************/

#ifndef _HIERARCHYURI_HXX
#define _HIERARCHYURI_HXX

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

namespace hierarchy_ucp {

//=========================================================================

#define HIERARCHY_URL_SCHEME          "vnd.sun.star.hier"
#define HIERARCHY_URL_SCHEME_LENGTH   17

//=========================================================================

class HierarchyUri
{
    mutable ::rtl::OUString m_aUri;
    mutable ::rtl::OUString m_aParentUri;
    mutable ::rtl::OUString m_aService;
    mutable ::rtl::OUString m_aPath;
    mutable ::rtl::OUString m_aName;
    mutable bool            m_bValid;

private:
    void init() const;

public:
    HierarchyUri() : m_bValid( false ) {}
    HierarchyUri( const ::rtl::OUString & rUri )
    : m_aUri( rUri ), m_bValid( false ) {}

    sal_Bool isValid() const
    { init(); return m_bValid; }

    const ::rtl::OUString & getUri() const
    { init(); return m_aUri; }

    void setUri( const ::rtl::OUString & rUri )
    { m_aPath = ::rtl::OUString(); m_aUri = rUri; m_bValid = false; }

    const ::rtl::OUString & getParentUri() const
    { init(); return m_aParentUri; }

    const ::rtl::OUString & getService() const
    { init(); return m_aService; }

    const ::rtl::OUString & getPath() const
    { init(); return m_aPath; }

    const ::rtl::OUString & getName() const
    { init(); return m_aName; }

    inline sal_Bool isRootFolder() const;
};

inline sal_Bool HierarchyUri::isRootFolder() const
{
    init();
    return ( ( m_aPath.getLength() == 1 ) &&
             ( m_aPath.getStr()[ 0 ] == sal_Unicode( '/' ) ) );
}
}

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.4.76); FILE MERGED 2008/04/01 16:02:20 thb 1.4.76.2: #i85898# Stripping all external header guards 2008/03/31 15:30:24 rt 1.4.76.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: hierarchyuri.hxx,v $
 * $Revision: 1.5 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _HIERARCHYURI_HXX
#define _HIERARCHYURI_HXX

#include <rtl/ustring.hxx>

namespace hierarchy_ucp {

//=========================================================================

#define HIERARCHY_URL_SCHEME          "vnd.sun.star.hier"
#define HIERARCHY_URL_SCHEME_LENGTH   17

//=========================================================================

class HierarchyUri
{
    mutable ::rtl::OUString m_aUri;
    mutable ::rtl::OUString m_aParentUri;
    mutable ::rtl::OUString m_aService;
    mutable ::rtl::OUString m_aPath;
    mutable ::rtl::OUString m_aName;
    mutable bool            m_bValid;

private:
    void init() const;

public:
    HierarchyUri() : m_bValid( false ) {}
    HierarchyUri( const ::rtl::OUString & rUri )
    : m_aUri( rUri ), m_bValid( false ) {}

    sal_Bool isValid() const
    { init(); return m_bValid; }

    const ::rtl::OUString & getUri() const
    { init(); return m_aUri; }

    void setUri( const ::rtl::OUString & rUri )
    { m_aPath = ::rtl::OUString(); m_aUri = rUri; m_bValid = false; }

    const ::rtl::OUString & getParentUri() const
    { init(); return m_aParentUri; }

    const ::rtl::OUString & getService() const
    { init(); return m_aService; }

    const ::rtl::OUString & getPath() const
    { init(); return m_aPath; }

    const ::rtl::OUString & getName() const
    { init(); return m_aName; }

    inline sal_Bool isRootFolder() const;
};

inline sal_Bool HierarchyUri::isRootFolder() const
{
    init();
    return ( ( m_aPath.getLength() == 1 ) &&
             ( m_aPath.getStr()[ 0 ] == sal_Unicode( '/' ) ) );
}
}

#endif
<|endoftext|>


<commit_before>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "kernel/celltypes.h"
#include "kernel/utils.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct CheckPass : public Pass {
	CheckPass() : Pass("check", "check for obvious problems in the design") { }
	virtual void help()
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    check [selection]\n");
		log("\n");
		log("This pass identifies the following problems in the current design:\n");
		log("\n");
		log(" - combinatorical loops\n");
		log("\n");
		log(" - two or more conflicting drivers for one wire\n");
		log("\n");
		log(" - used wires that do not have a driver\n");
		log("\n");
	}
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
	{
		int counter = 0;

		log_header("Executing CHECK pass (checking for obvious problems).\n");

		extra_args(args, 1, design);

		for (auto module : design->selected_whole_modules_warn())
		{
			if (module->has_processes_warn())
				continue;

			log("checking module %s..\n", log_id(module));

			SigMap sigmap(module);
			dict<SigBit, vector<string>> wire_drivers;
			pool<SigBit> used_wires;
			TopoSort<string> topo;

			for (auto cell : module->cells())
			for (auto &conn : cell->connections()) {
				SigSpec sig = sigmap(conn.second);
				bool logic_cell = yosys_celltypes.cell_evaluable(cell->type);
				if (cell->input(conn.first))
					for (auto bit : sig)
						if (bit.wire) {
							if (logic_cell)
								topo.edge(stringf("wire %s", log_signal(bit)),
										stringf("cell %s (%s)", log_id(cell), log_id(cell->type)));
							used_wires.insert(bit);
						}
				if (cell->output(conn.first))
					for (int i = 0; i < GetSize(sig); i++) {
						if (logic_cell)
							topo.edge(stringf("cell %s (%s)", log_id(cell), log_id(cell->type)),
									stringf("wire %s", log_signal(sig[i])));
						wire_drivers[sig[i]].push_back(stringf("port %s[%d] of cell %s (%s)",
								log_id(conn.first), i, log_id(cell), log_id(cell->type)));
					}
			}

			for (auto wire : module->wires()) {
				if (wire->port_input) {
					SigSpec sig = sigmap(wire);
					for (int i = 0; i < GetSize(sig); i++)
						wire_drivers[sig[i]].push_back(stringf("module input %s[%d]", log_id(wire), i));
				}
				if (wire->port_output)
					for (auto bit : sigmap(wire))
						if (bit.wire) used_wires.insert(bit);
			}

			for (auto it : wire_drivers)
				if (GetSize(it.second) > 1) {
					string message = stringf("multiple conflicting drivers for %s.%s:\n", log_id(module), log_signal(it.first));
					for (auto str : it.second)
						message += stringf("    %s\n", str.c_str());
					log_warning("%s", message.c_str());
					counter++;
				}

			for (auto bit : used_wires)
				if (!wire_drivers.count(bit)) {
					log_warning("Wire %s.%s is used but has no driver.\n", log_id(module), log_signal(bit));
					counter++;
				}

			topo.sort();
			for (auto &loop : topo.loops) {
				string message = stringf("found logic loop in module %s:\n", log_id(module));
				for (auto &str : loop)
					message += stringf("    %s\n", str.c_str());
				log_warning("%s", message.c_str());
				counter++;
			}
		}

		log("found and reported %d problems.\n", counter);
	}
} CheckPass;

PRIVATE_NAMESPACE_END
<commit_msg>Added "check -noinit"<commit_after>/*
 *  yosys -- Yosys Open SYnthesis Suite
 *
 *  Copyright (C) 2012  Clifford Wolf <clifford@clifford.at>
 *
 *  Permission to use, copy, modify, and/or distribute this software for any
 *  purpose with or without fee is hereby granted, provided that the above
 *  copyright notice and this permission notice appear in all copies.
 *
 *  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 *  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 *  ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 *  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 *  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 *  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 *
 */

#include "kernel/yosys.h"
#include "kernel/sigtools.h"
#include "kernel/celltypes.h"
#include "kernel/utils.h"

USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN

struct CheckPass : public Pass {
	CheckPass() : Pass("check", "check for obvious problems in the design") { }
	virtual void help()
	{
		//   |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
		log("\n");
		log("    check [options] [selection]\n");
		log("\n");
		log("This pass identifies the following problems in the current design:\n");
		log("\n");
		log(" - combinatorical loops\n");
		log("\n");
		log(" - two or more conflicting drivers for one wire\n");
		log("\n");
		log(" - used wires that do not have a driver\n");
		log("\n");
		log("When called with -noinit then this command also checks for wires which have\n");
		log("the 'init' attribute set.\n");
		log("\n");
	}
	virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
	{
		int counter = 0;
		bool noinit = false;

		size_t argidx;
		for (argidx = 1; argidx < args.size(); argidx++) {
			if (args[argidx] == "-noinit") {
				noinit = true;
				continue;
			}
			break;
		}
		extra_args(args, argidx, design);

		log_header("Executing CHECK pass (checking for obvious problems).\n");

		for (auto module : design->selected_whole_modules_warn())
		{
			if (module->has_processes_warn())
				continue;

			log("checking module %s..\n", log_id(module));

			SigMap sigmap(module);
			dict<SigBit, vector<string>> wire_drivers;
			pool<SigBit> used_wires;
			TopoSort<string> topo;

			for (auto cell : module->cells())
			for (auto &conn : cell->connections()) {
				SigSpec sig = sigmap(conn.second);
				bool logic_cell = yosys_celltypes.cell_evaluable(cell->type);
				if (cell->input(conn.first))
					for (auto bit : sig)
						if (bit.wire) {
							if (logic_cell)
								topo.edge(stringf("wire %s", log_signal(bit)),
										stringf("cell %s (%s)", log_id(cell), log_id(cell->type)));
							used_wires.insert(bit);
						}
				if (cell->output(conn.first))
					for (int i = 0; i < GetSize(sig); i++) {
						if (logic_cell)
							topo.edge(stringf("cell %s (%s)", log_id(cell), log_id(cell->type)),
									stringf("wire %s", log_signal(sig[i])));
						wire_drivers[sig[i]].push_back(stringf("port %s[%d] of cell %s (%s)",
								log_id(conn.first), i, log_id(cell), log_id(cell->type)));
					}
			}

			for (auto wire : module->wires()) {
				if (wire->port_input) {
					SigSpec sig = sigmap(wire);
					for (int i = 0; i < GetSize(sig); i++)
						wire_drivers[sig[i]].push_back(stringf("module input %s[%d]", log_id(wire), i));
				}
				if (wire->port_output)
					for (auto bit : sigmap(wire))
						if (bit.wire) used_wires.insert(bit);
				if (noinit && wire->attributes.count("\\init")) {
					log_warning("Wire %s.%s has an unprocessed 'init' attribute.\n", log_id(module), log_id(wire));
					counter++;
				}
			}

			for (auto it : wire_drivers)
				if (GetSize(it.second) > 1) {
					string message = stringf("multiple conflicting drivers for %s.%s:\n", log_id(module), log_signal(it.first));
					for (auto str : it.second)
						message += stringf("    %s\n", str.c_str());
					log_warning("%s", message.c_str());
					counter++;
				}

			for (auto bit : used_wires)
				if (!wire_drivers.count(bit)) {
					log_warning("Wire %s.%s is used but has no driver.\n", log_id(module), log_signal(bit));
					counter++;
				}

			topo.sort();
			for (auto &loop : topo.loops) {
				string message = stringf("found logic loop in module %s:\n", log_id(module));
				for (auto &str : loop)
					message += stringf("    %s\n", str.c_str());
				log_warning("%s", message.c_str());
				counter++;
			}
		}

		log("found and reported %d problems.\n", counter);
	}
} CheckPass;

PRIVATE_NAMESPACE_END
<|endoftext|>


<commit_before>

/**
 * This file is part of Slideshow.
 * Copyright (C) 2008 David Sveningsson <ext@sidvind.com>
 *
 * Slideshow is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * Slideshow 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Slideshow.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "Kernel.h"
#include "Graphics.h"
#include "OS.h"
#include "Log.h"
#include "Exceptions.h"
#include "transitions/dummy.h"
#include "transitions/fade.h"
#include "browsers/mysqlbrowser.h"
#include "IPC/dbus.h"
#include "argument_parser.h"
#include "state/State.h"
#include "state/InitialState.h"
#include "state/SwitchState.h"
#include "state/TransitionState.h"
#include "state/ViewState.h"
#include <portable/Time.h>
#include <portable/Process.h>

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <ctype.h>

//#include <syscall.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <X11/Xlib.h>

#ifdef LINUX
#include <sys/time.h>
#endif

#ifdef WIN32
#include <windows.h>
#endif

#ifndef NULL
#define NULL 0
#endif

bool* daemon_running = NULL;
const char* application_name = "slideshow";

void quit_signal(int){
	Log::message(Log::Verbose, "Caught SIGQUIT\n");
	signal(SIGQUIT, quit_signal);
	*daemon_running = false;
}

Kernel::Kernel(int argc, const char* argv[]):
	_width(800),
	_height(600),
	_frames(0),
	_bin_id(1),
	_fullscreen(0),
	_daemon(0),
	_verbose(1),
	_stdin(0),
	_transition_time(3.0f),
	_switch_time(5.0f),
	_graphics(NULL),
	_browser(NULL),
	_ipc(NULL),
	_db_username(NULL),
	_db_password(NULL),
	_db_name(NULL),
	_db_host(NULL),
	_logfile("slideshow.log"){

	initTime();
	Log::initialize(_logfile, "slideshow.debug.log");

	if ( !parse_argv(argc, argv) ){
		exit(4);
	}

	Log::set_level( (Log::Severity)_verbose );

	fflush(stdout);

	///@todo HACK! Attempt to connect to an xserver.
	Display* dpy = XOpenDisplay(NULL);
	if( !dpy ) {
		throw NoXConnection("Could not connect to an X server\n");
	}
	XCloseDisplay(dpy);

	if ( _daemon ){
		Log::message(Log::Info, "Kernel: Starting slideshow daemon\n");

		Portable::daemonize(application_name);

		if ( signal(SIGQUIT, quit_signal) == SIG_ERR ){
			Log::message(Log::Fatal, "Kernel: Could not initialize signal handler!\n");
			exit(3);
		}

		///@ hack
		daemon_running = &_running;
	} else {
		Log::message(Log::Info, "Kernel: Starting slideshow\n");
		print_licence_statement();
       	}

	_graphics = new Graphics(_width, _height, _fullscreen);
	_graphics->set_transition(new FadeTransition);

	_ipc = new DBus(this, 50);

	if ( !_db_password ){
		if ( !_stdin ){
			printf("Database password: \n");
		}
		_db_password = (char*)malloc(256);
		scanf("%256s", _db_password);
	}

	if ( _db_host ){
		_browser = new MySQLBrowser(_db_username, _db_password, _db_name, _db_host);
	} else {
		_browser = new MySQLBrowser(_db_username, _db_password, _db_name);
	}

	_browser->change_bin(_bin_id);
	_browser->reload();

	TransitionState::set_transition_time(_transition_time);
	_state = new InitialState(_browser, _graphics, _ipc);
}

Kernel::~Kernel(){
	if ( _daemon ){
		Portable::daemon_stop(application_name);
	}

	delete _browser;
	delete _graphics;
	delete _ipc;

	free( _db_username );
	free( _db_password );
	free( _db_name );
	free( _db_host );

	_browser = NULL;
	_graphics = NULL;
	_ipc = NULL;

	Log::deinitialize();
}

void Kernel::print_licence_statement(){
	printf("Slideshow  Copyright (C) 2008 David Sveningsson <ext@sidvind.com>\n");
	printf("This program comes with ABSOLUTELY NO WARRANTY.\n");
	printf("This is free software, and you are welcome to redistribute it\n");
	printf("under certain conditions; see COPYING or <http://www.gnu.org/licenses/>\n");
	printf("for details.\n");
}

void Kernel::run(){
	_running = true;

	_last_switch = getTime();
	_transition_start = 0.0f;

	while ( _running ){
		OS::poll_events(_running);
		_state = _state->action();
	}
}

bool Kernel::parse_argv(int argc, const char* argv[]){
	printf("Starting with \"");
	for ( int i = 1; i < argc; i++ ){
		if ( i > 1 ){
			putchar(' ');
		}
		printf("%s", argv[i]);
	}
	printf("\"\n");

	option_set_t options;
	option_initialize(&options, argc, argv);

	option_set_description(&options, "Slideshow is an application for showing text and images in a loop on monitors and projectors.");

	option_add_flag(&options, "verbose", 'v', "Explain what is being done", &_verbose, 0);
	option_add_flag(&options, "quiet", 'q', "Explain what is being done", &_verbose, 2);
	option_add_flag(&options, "fullscreen", 'f', "Start in fullscreen mode", &_fullscreen, 1);
	option_add_flag(&options, "daemon", 'd', "Run in background", &_daemon, 1);
	option_add_flag(&options, "stdin", 0, "Except the input (e.g database password) to come from stdin", &_stdin, 1);
	option_add_string(&options, "db_user", 0, "Database username", &_db_username);
	option_add_string(&options, "db_pass", 0, "Database password", &_db_password);
	option_add_string(&options, "db_name", 0, "Database name", &_db_name);
	option_add_string(&options, "db_host", 0, "Database host [localhost]", &_db_host);
	option_add_int(&options, "collection-id", 'c', "ID of the collection to display", &_bin_id);
	option_add_format(&options, "resolution", 'r', "Resolution", "WIDTHxHEIGHT", "%dx%d", &_width, &_height);

	int n = option_parse(&options);
	option_finalize(&options);

	if ( n < 0 ){
		return false;
	}

	if ( n != argc ){
		printf("%d %d\n", n, argc);
		printf("%s: unrecognized option '%s'\n", argv[0], argv[n+1]);
		printf("Try `%s --help' for more information.\n", argv[0]);
		return false;
	}

	return true;
}

void Kernel::play_video(const char* fullpath){
	Log::message(Log::Info, "Kernel: Playing video \"%s\"\n", fullpath);

	int status;

	if ( fork() == 0 ){
		execlp("mplayer", "", "-fs", "-really-quiet", fullpath, NULL);
		exit(0);
	}

	::wait(&status);
}

void Kernel::quit(){
	_running = false;
}

void Kernel::reload_browser(){
	_browser->reload();
}

void Kernel::change_bin(unsigned int id){
	Log::message(Log::Verbose, "Kernel: Switching to collection %d\n", id);
	_browser->change_bin(id);
	_browser->reload();
}

void Kernel::ipc_quit(){
	delete _ipc;
	_ipc = NULL;
}

void Kernel::debug_dumpqueue(){
	_browser->dump_queue();
}
<commit_msg>Setting transitional- and viewtime<commit_after>

/**
 * This file is part of Slideshow.
 * Copyright (C) 2008 David Sveningsson <ext@sidvind.com>
 *
 * Slideshow is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 *
 * Slideshow 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with Slideshow.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "Kernel.h"
#include "Graphics.h"
#include "OS.h"
#include "Log.h"
#include "Exceptions.h"
#include "transitions/dummy.h"
#include "transitions/fade.h"
#include "browsers/mysqlbrowser.h"
#include "IPC/dbus.h"
#include "argument_parser.h"
#include "state/State.h"
#include "state/InitialState.h"
#include "state/SwitchState.h"
#include "state/TransitionState.h"
#include "state/ViewState.h"
#include <portable/Time.h>
#include <portable/Process.h>

#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <ctype.h>

//#include <syscall.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <X11/Xlib.h>

#ifdef LINUX
#include <sys/time.h>
#endif

#ifdef WIN32
#include <windows.h>
#endif

#ifndef NULL
#define NULL 0
#endif

bool* daemon_running = NULL;
const char* application_name = "slideshow";

void quit_signal(int){
	Log::message(Log::Verbose, "Caught SIGQUIT\n");
	signal(SIGQUIT, quit_signal);
	*daemon_running = false;
}

Kernel::Kernel(int argc, const char* argv[]):
	_width(800),
	_height(600),
	_frames(0),
	_bin_id(1),
	_fullscreen(0),
	_daemon(0),
	_verbose(1),
	_stdin(0),
	_transition_time(3.0f),
	_switch_time(5.0f),
	_graphics(NULL),
	_browser(NULL),
	_ipc(NULL),
	_db_username(NULL),
	_db_password(NULL),
	_db_name(NULL),
	_db_host(NULL),
	_logfile("slideshow.log"){

	initTime();
	Log::initialize(_logfile, "slideshow.debug.log");

	if ( !parse_argv(argc, argv) ){
		exit(4);
	}

	Log::set_level( (Log::Severity)_verbose );

	fflush(stdout);

	///@todo HACK! Attempt to connect to an xserver.
	Display* dpy = XOpenDisplay(NULL);
	if( !dpy ) {
		throw NoXConnection("Could not connect to an X server\n");
	}
	XCloseDisplay(dpy);

	if ( _daemon ){
		Log::message(Log::Info, "Kernel: Starting slideshow daemon\n");

		Portable::daemonize(application_name);

		if ( signal(SIGQUIT, quit_signal) == SIG_ERR ){
			Log::message(Log::Fatal, "Kernel: Could not initialize signal handler!\n");
			exit(3);
		}

		///@ hack
		daemon_running = &_running;
	} else {
		Log::message(Log::Info, "Kernel: Starting slideshow\n");
		print_licence_statement();
       	}

	_graphics = new Graphics(_width, _height, _fullscreen);
	_graphics->set_transition(new FadeTransition);

	_ipc = new DBus(this, 50);

	if ( !_db_password ){
		if ( !_stdin ){
			printf("Database password: \n");
		}
		_db_password = (char*)malloc(256);
		scanf("%256s", _db_password);
	}

	if ( _db_host ){
		_browser = new MySQLBrowser(_db_username, _db_password, _db_name, _db_host);
	} else {
		_browser = new MySQLBrowser(_db_username, _db_password, _db_name);
	}

	_browser->change_bin(_bin_id);
	_browser->reload();

	TransitionState::set_transition_time(_transition_time);
	ViewState::set_view_time(_switch_time);
	_state = new InitialState(_browser, _graphics, _ipc);
}

Kernel::~Kernel(){
	if ( _daemon ){
		Portable::daemon_stop(application_name);
	}

	delete _browser;
	delete _graphics;
	delete _ipc;

	free( _db_username );
	free( _db_password );
	free( _db_name );
	free( _db_host );

	_browser = NULL;
	_graphics = NULL;
	_ipc = NULL;

	Log::deinitialize();
}

void Kernel::print_licence_statement(){
	printf("Slideshow  Copyright (C) 2008 David Sveningsson <ext@sidvind.com>\n");
	printf("This program comes with ABSOLUTELY NO WARRANTY.\n");
	printf("This is free software, and you are welcome to redistribute it\n");
	printf("under certain conditions; see COPYING or <http://www.gnu.org/licenses/>\n");
	printf("for details.\n");
}

void Kernel::run(){
	_running = true;

	_last_switch = getTime();
	_transition_start = 0.0f;

	while ( _running ){
		OS::poll_events(_running);
		_state = _state->action();
	}
}

bool Kernel::parse_argv(int argc, const char* argv[]){
	printf("Starting with \"");
	for ( int i = 1; i < argc; i++ ){
		if ( i > 1 ){
			putchar(' ');
		}
		printf("%s", argv[i]);
	}
	printf("\"\n");

	option_set_t options;
	option_initialize(&options, argc, argv);

	option_set_description(&options, "Slideshow is an application for showing text and images in a loop on monitors and projectors.");

	option_add_flag(&options, "verbose", 'v', "Explain what is being done", &_verbose, 0);
	option_add_flag(&options, "quiet", 'q', "Explain what is being done", &_verbose, 2);
	option_add_flag(&options, "fullscreen", 'f', "Start in fullscreen mode", &_fullscreen, 1);
	option_add_flag(&options, "daemon", 'd', "Run in background", &_daemon, 1);
	option_add_flag(&options, "stdin", 0, "Except the input (e.g database password) to come from stdin", &_stdin, 1);
	option_add_string(&options, "db_user", 0, "Database username", &_db_username);
	option_add_string(&options, "db_pass", 0, "Database password", &_db_password);
	option_add_string(&options, "db_name", 0, "Database name", &_db_name);
	option_add_string(&options, "db_host", 0, "Database host [localhost]", &_db_host);
	option_add_int(&options, "collection-id", 'c', "ID of the collection to display", &_bin_id);
	option_add_format(&options, "resolution", 'r', "Resolution", "WIDTHxHEIGHT", "%dx%d", &_width, &_height);

	int n = option_parse(&options);
	option_finalize(&options);

	if ( n < 0 ){
		return false;
	}

	if ( n != argc ){
		printf("%d %d\n", n, argc);
		printf("%s: unrecognized option '%s'\n", argv[0], argv[n+1]);
		printf("Try `%s --help' for more information.\n", argv[0]);
		return false;
	}

	return true;
}

void Kernel::play_video(const char* fullpath){
	Log::message(Log::Info, "Kernel: Playing video \"%s\"\n", fullpath);

	int status;

	if ( fork() == 0 ){
		execlp("mplayer", "", "-fs", "-really-quiet", fullpath, NULL);
		exit(0);
	}

	::wait(&status);
}

void Kernel::quit(){
	_running = false;
}

void Kernel::reload_browser(){
	_browser->reload();
}

void Kernel::change_bin(unsigned int id){
	Log::message(Log::Verbose, "Kernel: Switching to collection %d\n", id);
	_browser->change_bin(id);
	_browser->reload();
}

void Kernel::ipc_quit(){
	delete _ipc;
	_ipc = NULL;
}

void Kernel::debug_dumpqueue(){
	_browser->dump_queue();
}
<|endoftext|>


<commit_before>#ifndef _SDD_MEM_LINEAR_ALLOC_HH_
#define _SDD_MEM_LINEAR_ALLOC_HH_

#include <cassert>
#include <cstddef>
#include <memory> // unique_ptr

namespace sdd { namespace mem {

/*------------------------------------------------------------------------------------------------*/

namespace /* anonymous */ {

/// @internal
/// @brief A memory arena for linear_alloc.
class arena
{
  // Can't copy an arena.
  arena(const arena&) = delete;
  arena& operator=(const arena&) = delete;

public:

  /// @brief The type of position in the memory buffer.
  using position_type = char*;

private:

  /// @brief The size of this memory arena.
  const std::size_t size_;

  /// @brief The underlying memory buffer.
  std::unique_ptr<char[]> buffer_;

  /// @brief The beginning of the free memory.
  position_type position_;

#ifndef NDEBUG
  /// @brief The number of time this arena has been used with a rewinder.
  unsigned int active_;

  /// @brief The number of allocated bytes when this arena wasn't referenced by any rewinder.
  std::size_t unactive_allocated_;
#endif

public:

  /// @brief Construct an arena with a given size.
  arena(std::size_t size)
  noexcept
    : size_(size)
    , buffer_(new char[size_])
    , position_(buffer_.get())
#ifndef NDEBUG
    , active_(0)
    , unactive_allocated_(0)
#endif
  {}

#ifndef NDEBUG
  ~arena()
  {
    // We admit that some bytes can never be deallocated. As a matter of fact, it would be very
    // complex to keep track of the memory allocated when no rewinder is used. For instance,
    // when the user creates a sum, the underlying container uses the linear allocator, but without
    // a rewinder. This is why we keep a trace of the number of rewinders with active_.
    assert(used() == unactive_allocated_ && "Memory arena not rewound.");
  }
#endif

  char*
  allocate(std::size_t n)
  {
    assert(pointer_in_buffer(position_) && "linear_alloc has outlived arena");
    if (buffer_.get() + size_ - position_ >= n)
    {
#ifndef NDEBUG
      if (active_ == 0)
      {
        unactive_allocated_ += n;
      }
#endif
      char* r = position_;
      position_ += n;
      return r;
    }
    // Not enough room in the buffer, fallback to the default allocator.
    return static_cast<char*>(::operator new(n));
  }

  void
  deallocate(char* p, std::size_t n)
  noexcept
  {
    assert(pointer_in_buffer(position_) && "linear_alloc has outlived arena");
    if (pointer_in_buffer(p))
    {
      if (p + n == position_) // The memory pointed by p was the last allocated one.
      {
#ifndef NDEBUG
        if (active_ == 0)
        {
          unactive_allocated_ -= n;
        }
#endif
        position_ = p;
      }
    }
    else
    {
      // The memory pointed by p was no allocated in this arena.
      ::operator delete(p);
    }
  }

  void
  rewind(position_type pos)
  noexcept
  {
    assert(pointer_in_buffer(pos));
    position_ = pos;
  }

  position_type
  position()
  const noexcept
  {
    return position_;
  }

#ifndef NDEBUG
  std::size_t
  used()
  const noexcept
  {
    return static_cast<std::size_t>(position_ - buffer_.get());
  }

  void
  activate()
  noexcept
  {
    active_ += 1;
  }

  void
  deactivate()
  noexcept
  {
    active_ -= 1;
  }
#endif

private:

  bool
  pointer_in_buffer(char* p)
  const noexcept
  {
    return buffer_.get() <= p and p <= buffer_.get() + size_;
    }
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Rewind an arena to its initial position.
///
/// Use RAII to ensure that the arena is always rewound to its initial position .
class rewinder
{
  // Can't copy a rewinder.
  rewinder(const rewinder&) = delete;
  rewinder& operator=(const rewinder&) = delete;

  // Can't move a rewinder.
  rewinder(rewinder&&) = delete;
  rewinder& operator=(rewinder&&) = delete;

private:

  /// @brief The associated memory arena.
  arena& a_;

  /// @brief The position where to rewind the associated arena.
  const arena::position_type pos_;

public:

  /// @brief Constructor.
  ///
  /// Initialize the position to the current position of the arena.
  rewinder(arena& a)
  noexcept
    : a_(a), pos_(a.position())
  {
#ifndef NDEBUG
    a_.activate();
#endif
  }

  /// @brief Destructor.
  ///
  /// Rewind the arena to its position when this object was constructed;
  ~rewinder()
  {
    a_.rewind(pos_);
#ifndef NDEBUG
    a_.deactivate();
#endif
  }
};

/*------------------------------------------------------------------------------------------------*/

} // namespace anonymous

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Allocate memory contiguously in a preallocated buffer.
///
/// Memory is allocated by moving a pointer in the buffer. Only the memory which was the last
/// one thas was allocated can be deallocated. Thus, this allocator would mostly benefit to
/// recursive algorithms which need a stack.
/// It's an adaptation of http://home.roadrunner.com/~hinnant/stack_alloc.html .
template <typename T>
class linear_alloc
{
public:

  using value_type = T;

private:
  arena& a_;

public:

  template <typename _Up>
  struct rebind
  {
    using other = linear_alloc<_Up>;
  };

  linear_alloc(arena& a)
  noexcept
    : a_(a)
  {}

  template <typename U>
  linear_alloc(const linear_alloc<U>& other)
  noexcept
    : a_(other.a_)
  {}

  linear_alloc(const linear_alloc&) = default;
  linear_alloc& operator=(const linear_alloc&) = delete;

  T*
  allocate(std::size_t n)
  const
  {
    return reinterpret_cast<T*>(a_.allocate(n*sizeof(T)));
  }

  void
  deallocate(T* p, std::size_t n)
  const noexcept
  {
    a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T));
  }

  template <typename U, typename V>
  friend
  bool
  operator==(const linear_alloc<U>&, const linear_alloc<V>&) noexcept;

  template <typename U> friend class linear_alloc;
};

/*------------------------------------------------------------------------------------------------*/

template <typename U, typename V>
bool
operator==(const linear_alloc<U>& lhs, const linear_alloc<V>& rhs)
noexcept
{
  return &lhs.a_ == &rhs.a_;
}

template <typename U, typename V>
bool
operator!=(const linear_alloc<U>& lhs, const linear_alloc<V>& rhs)
noexcept
{
  return not(lhs == rhs);
}

/*------------------------------------------------------------------------------------------------*/

}} // namespace sdd::mem

#endif // _SDD_MEM_LINEAR_ALLOC_HH_
<commit_msg>Avoid a warning about signed/unsigned comparison.<commit_after>#ifndef _SDD_MEM_LINEAR_ALLOC_HH_
#define _SDD_MEM_LINEAR_ALLOC_HH_

#include <cassert>
#include <cstddef>
#include <memory> // unique_ptr

namespace sdd { namespace mem {

/*------------------------------------------------------------------------------------------------*/

namespace /* anonymous */ {

/// @internal
/// @brief A memory arena for linear_alloc.
class arena
{
  // Can't copy an arena.
  arena(const arena&) = delete;
  arena& operator=(const arena&) = delete;

public:

  /// @brief The type of position in the memory buffer.
  using position_type = char*;

private:

  /// @brief The size of this memory arena.
  const std::size_t size_;

  /// @brief The underlying memory buffer.
  std::unique_ptr<char[]> buffer_;

  /// @brief The beginning of the free memory.
  position_type position_;

#ifndef NDEBUG
  /// @brief The number of time this arena has been used with a rewinder.
  unsigned int active_;

  /// @brief The number of allocated bytes when this arena wasn't referenced by any rewinder.
  std::size_t unactive_allocated_;
#endif

public:

  /// @brief Construct an arena with a given size.
  arena(std::size_t size)
  noexcept
    : size_(size)
    , buffer_(new char[size_])
    , position_(buffer_.get())
#ifndef NDEBUG
    , active_(0)
    , unactive_allocated_(0)
#endif
  {}

#ifndef NDEBUG
  ~arena()
  {
    // We admit that some bytes can never be deallocated. As a matter of fact, it would be very
    // complex to keep track of the memory allocated when no rewinder is used. For instance,
    // when the user creates a sum, the underlying container uses the linear allocator, but without
    // a rewinder. This is why we keep a trace of the number of rewinders with active_.
    assert(used() == unactive_allocated_ && "Memory arena not rewound.");
  }
#endif

  char*
  allocate(std::size_t n)
  {
    assert(pointer_in_buffer(position_) && "linear_alloc has outlived arena");
    // The following temporary variable avoid a warning about comparison of signed and unsigned
    // values: pointer arithmetic gives a std::ptrdiff_t (signed), but allocate() takes a
    // std::size_t (unsigned). By construction, we are sure that position_ is always between
    // buffer_.get() and buffer_.get() + size_, so the difference is always > 0.
    const std::size_t diff = buffer_.get() + size_ - position_;
    if (diff >= n)
    {
#ifndef NDEBUG
      if (active_ == 0)
      {
        unactive_allocated_ += n;
      }
#endif
      char* r = position_;
      position_ += n;
      return r;
    }
    // Not enough room in the buffer, fallback to the default allocator.
    return static_cast<char*>(::operator new(n));
  }

  void
  deallocate(char* p, std::size_t n)
  noexcept
  {
    assert(pointer_in_buffer(position_) && "linear_alloc has outlived arena");
    if (pointer_in_buffer(p))
    {
      if (p + n == position_) // The memory pointed by p was the last allocated one.
      {
#ifndef NDEBUG
        if (active_ == 0)
        {
          unactive_allocated_ -= n;
        }
#endif
        position_ = p;
      }
    }
    else
    {
      // The memory pointed by p was no allocated in this arena.
      ::operator delete(p);
    }
  }

  void
  rewind(position_type pos)
  noexcept
  {
    assert(pointer_in_buffer(pos));
    position_ = pos;
  }

  position_type
  position()
  const noexcept
  {
    return position_;
  }

#ifndef NDEBUG
  std::size_t
  used()
  const noexcept
  {
    return static_cast<std::size_t>(position_ - buffer_.get());
  }

  void
  activate()
  noexcept
  {
    active_ += 1;
  }

  void
  deactivate()
  noexcept
  {
    active_ -= 1;
  }
#endif

private:

  bool
  pointer_in_buffer(char* p)
  const noexcept
  {
    return buffer_.get() <= p and p <= buffer_.get() + size_;
    }
};

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Rewind an arena to its initial position.
///
/// Use RAII to ensure that the arena is always rewound to its initial position .
class rewinder
{
  // Can't copy a rewinder.
  rewinder(const rewinder&) = delete;
  rewinder& operator=(const rewinder&) = delete;

  // Can't move a rewinder.
  rewinder(rewinder&&) = delete;
  rewinder& operator=(rewinder&&) = delete;

private:

  /// @brief The associated memory arena.
  arena& a_;

  /// @brief The position where to rewind the associated arena.
  const arena::position_type pos_;

public:

  /// @brief Constructor.
  ///
  /// Initialize the position to the current position of the arena.
  rewinder(arena& a)
  noexcept
    : a_(a), pos_(a.position())
  {
#ifndef NDEBUG
    a_.activate();
#endif
  }

  /// @brief Destructor.
  ///
  /// Rewind the arena to its position when this object was constructed;
  ~rewinder()
  {
    a_.rewind(pos_);
#ifndef NDEBUG
    a_.deactivate();
#endif
  }
};

/*------------------------------------------------------------------------------------------------*/

} // namespace anonymous

/*------------------------------------------------------------------------------------------------*/

/// @internal
/// @brief Allocate memory contiguously in a preallocated buffer.
///
/// Memory is allocated by moving a pointer in the buffer. Only the memory which was the last
/// one thas was allocated can be deallocated. Thus, this allocator would mostly benefit to
/// recursive algorithms which need a stack.
/// It's an adaptation of http://home.roadrunner.com/~hinnant/stack_alloc.html .
template <typename T>
class linear_alloc
{
public:

  using value_type = T;

private:
  arena& a_;

public:

  template <typename _Up>
  struct rebind
  {
    using other = linear_alloc<_Up>;
  };

  linear_alloc(arena& a)
  noexcept
    : a_(a)
  {}

  template <typename U>
  linear_alloc(const linear_alloc<U>& other)
  noexcept
    : a_(other.a_)
  {}

  linear_alloc(const linear_alloc&) = default;
  linear_alloc& operator=(const linear_alloc&) = delete;

  T*
  allocate(std::size_t n)
  const
  {
    return reinterpret_cast<T*>(a_.allocate(n*sizeof(T)));
  }

  void
  deallocate(T* p, std::size_t n)
  const noexcept
  {
    a_.deallocate(reinterpret_cast<char*>(p), n*sizeof(T));
  }

  template <typename U, typename V>
  friend
  bool
  operator==(const linear_alloc<U>&, const linear_alloc<V>&) noexcept;

  template <typename U> friend class linear_alloc;
};

/*------------------------------------------------------------------------------------------------*/

template <typename U, typename V>
bool
operator==(const linear_alloc<U>& lhs, const linear_alloc<V>& rhs)
noexcept
{
  return &lhs.a_ == &rhs.a_;
}

template <typename U, typename V>
bool
operator!=(const linear_alloc<U>& lhs, const linear_alloc<V>& rhs)
noexcept
{
  return not(lhs == rhs);
}

/*------------------------------------------------------------------------------------------------*/

}} // namespace sdd::mem

#endif // _SDD_MEM_LINEAR_ALLOC_HH_
<|endoftext|>


<commit_before>//===- llvm/unittest/IR/IRBuilderTest.cpp - IRBuilder tests ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/IRBuilder.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace {

class IRBuilderTest : public testing::Test {
protected:
  virtual void SetUp() {
    M.reset(new Module("MyModule", getGlobalContext()));
    FunctionType *FTy = FunctionType::get(Type::getVoidTy(getGlobalContext()),
                                          /*isVarArg=*/false);
    F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
    BB = BasicBlock::Create(getGlobalContext(), "", F);
    GV = new GlobalVariable(*M, Type::getFloatTy(getGlobalContext()), true,
                            GlobalValue::ExternalLinkage, 0);
  }

  virtual void TearDown() {
    BB = 0;
    M.reset();
  }

  OwningPtr<Module> M;
  Function *F;
  BasicBlock *BB;
  GlobalVariable *GV;
};

TEST_F(IRBuilderTest, Lifetime) {
  IRBuilder<> Builder(BB);
  AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());
  AllocaInst *Var2 = Builder.CreateAlloca(Builder.getInt32Ty());
  AllocaInst *Var3 = Builder.CreateAlloca(Builder.getInt8Ty(),
                                          Builder.getInt32(123));

  CallInst *Start1 = Builder.CreateLifetimeStart(Var1);
  CallInst *Start2 = Builder.CreateLifetimeStart(Var2);
  CallInst *Start3 = Builder.CreateLifetimeStart(Var3, Builder.getInt64(100));

  EXPECT_EQ(Start1->getArgOperand(0), Builder.getInt64(-1));
  EXPECT_EQ(Start2->getArgOperand(0), Builder.getInt64(-1));
  EXPECT_EQ(Start3->getArgOperand(0), Builder.getInt64(100));

  EXPECT_EQ(Start1->getArgOperand(1), Var1);
  EXPECT_NE(Start2->getArgOperand(1), Var2);
  EXPECT_EQ(Start3->getArgOperand(1), Var3);

  Value *End1 = Builder.CreateLifetimeEnd(Var1);
  Builder.CreateLifetimeEnd(Var2);
  Builder.CreateLifetimeEnd(Var3);

  IntrinsicInst *II_Start1 = dyn_cast<IntrinsicInst>(Start1);
  IntrinsicInst *II_End1 = dyn_cast<IntrinsicInst>(End1);
  ASSERT_TRUE(II_Start1 != NULL);
  EXPECT_EQ(II_Start1->getIntrinsicID(), Intrinsic::lifetime_start);
  ASSERT_TRUE(II_End1 != NULL);
  EXPECT_EQ(II_End1->getIntrinsicID(), Intrinsic::lifetime_end);
}

TEST_F(IRBuilderTest, CreateCondBr) {
  IRBuilder<> Builder(BB);
  BasicBlock *TBB = BasicBlock::Create(getGlobalContext(), "", F);
  BasicBlock *FBB = BasicBlock::Create(getGlobalContext(), "", F);

  BranchInst *BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
  TerminatorInst *TI = BB->getTerminator();
  EXPECT_EQ(BI, TI);
  EXPECT_EQ(2u, TI->getNumSuccessors());
  EXPECT_EQ(TBB, TI->getSuccessor(0));
  EXPECT_EQ(FBB, TI->getSuccessor(1));

  BI->eraseFromParent();
  MDNode *Weights = MDBuilder(getGlobalContext()).createBranchWeights(42, 13);
  BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB, Weights);
  TI = BB->getTerminator();
  EXPECT_EQ(BI, TI);
  EXPECT_EQ(2u, TI->getNumSuccessors());
  EXPECT_EQ(TBB, TI->getSuccessor(0));
  EXPECT_EQ(FBB, TI->getSuccessor(1));
  EXPECT_EQ(Weights, TI->getMetadata(LLVMContext::MD_prof));
}

TEST_F(IRBuilderTest, LandingPadName) {
  IRBuilder<> Builder(BB);
  LandingPadInst *LP = Builder.CreateLandingPad(Builder.getInt32Ty(),
                                                Builder.getInt32(0), 0, "LP");
  EXPECT_EQ(LP->getName(), "LP");
}

TEST_F(IRBuilderTest, GetIntTy) {
  IRBuilder<> Builder(BB);
  IntegerType *Ty1 = Builder.getInt1Ty();
  EXPECT_EQ(Ty1, IntegerType::get(getGlobalContext(), 1));

  DataLayout* DL = new DataLayout(M.get());
  IntegerType *IntPtrTy = Builder.getIntPtrTy(DL);
  unsigned IntPtrBitSize =  DL->getPointerSizeInBits(0);
  EXPECT_EQ(IntPtrTy, IntegerType::get(getGlobalContext(), IntPtrBitSize));
  delete DL;
}

TEST_F(IRBuilderTest, FastMathFlags) {
  IRBuilder<> Builder(BB);
  Value *F;
  Instruction *FDiv, *FAdd;

  F = Builder.CreateLoad(GV);
  F = Builder.CreateFAdd(F, F);

  EXPECT_FALSE(Builder.getFastMathFlags().any());
  ASSERT_TRUE(isa<Instruction>(F));
  FAdd = cast<Instruction>(F);
  EXPECT_FALSE(FAdd->hasNoNaNs());

  FastMathFlags FMF;
  Builder.SetFastMathFlags(FMF);

  F = Builder.CreateFAdd(F, F);
  EXPECT_FALSE(Builder.getFastMathFlags().any());

  FMF.setUnsafeAlgebra();
  Builder.SetFastMathFlags(FMF);

  F = Builder.CreateFAdd(F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  ASSERT_TRUE(isa<Instruction>(F));
  FAdd = cast<Instruction>(F);
  EXPECT_TRUE(FAdd->hasNoNaNs());

  F = Builder.CreateFDiv(F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  EXPECT_TRUE(Builder.getFastMathFlags().UnsafeAlgebra);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_TRUE(FDiv->hasAllowReciprocal());

  Builder.clearFastMathFlags();

  F = Builder.CreateFDiv(F, F);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_FALSE(FDiv->hasAllowReciprocal());

  FMF.clear();
  FMF.setAllowReciprocal();
  Builder.SetFastMathFlags(FMF);

  F = Builder.CreateFDiv(F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  EXPECT_TRUE(Builder.getFastMathFlags().AllowReciprocal);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_TRUE(FDiv->hasAllowReciprocal());

  Builder.clearFastMathFlags();

  F = Builder.CreateFDiv(F, F);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_FALSE(FDiv->getFastMathFlags().any());
  FDiv->copyFastMathFlags(FAdd);
  EXPECT_TRUE(FDiv->hasNoNaNs());

}

TEST_F(IRBuilderTest, RAIIHelpersTest) {
  IRBuilder<> Builder(BB);
  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
  MDBuilder MDB(M->getContext());

  MDNode *FPMathA = MDB.createFPMath(0.01);
  MDNode *FPMathB = MDB.createFPMath(0.1);

  Builder.SetDefaultFPMathTag(FPMathA);

  {
    IRBuilder<>::FastMathFlagGuard Guard(Builder);
    FastMathFlags FMF;
    FMF.setAllowReciprocal();
    Builder.SetFastMathFlags(FMF);
    Builder.SetDefaultFPMathTag(FPMathB);
    EXPECT_TRUE(Builder.getFastMathFlags().allowReciprocal());
    EXPECT_EQ(FPMathB, Builder.getDefaultFPMathTag());
  }

  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
  EXPECT_EQ(FPMathA, Builder.getDefaultFPMathTag());

  Value *F = Builder.CreateLoad(GV);

  {
    IRBuilder<>::InsertPointGuard Guard(Builder);
    Builder.SetInsertPoint(cast<Instruction>(F));
    EXPECT_EQ(F, Builder.GetInsertPoint());
  }

  EXPECT_EQ(BB->end(), Builder.GetInsertPoint());
  EXPECT_EQ(BB, Builder.GetInsertBlock());
}

}
<commit_msg>Silencing an MSVC warning.<commit_after>//===- llvm/unittest/IR/IRBuilderTest.cpp - IRBuilder tests ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/IRBuilder.h"
#include "llvm/ADT/OwningPtr.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace {

class IRBuilderTest : public testing::Test {
protected:
  virtual void SetUp() {
    M.reset(new Module("MyModule", getGlobalContext()));
    FunctionType *FTy = FunctionType::get(Type::getVoidTy(getGlobalContext()),
                                          /*isVarArg=*/false);
    F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
    BB = BasicBlock::Create(getGlobalContext(), "", F);
    GV = new GlobalVariable(*M, Type::getFloatTy(getGlobalContext()), true,
                            GlobalValue::ExternalLinkage, 0);
  }

  virtual void TearDown() {
    BB = 0;
    M.reset();
  }

  OwningPtr<Module> M;
  Function *F;
  BasicBlock *BB;
  GlobalVariable *GV;
};

TEST_F(IRBuilderTest, Lifetime) {
  IRBuilder<> Builder(BB);
  AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());
  AllocaInst *Var2 = Builder.CreateAlloca(Builder.getInt32Ty());
  AllocaInst *Var3 = Builder.CreateAlloca(Builder.getInt8Ty(),
                                          Builder.getInt32(123));

  CallInst *Start1 = Builder.CreateLifetimeStart(Var1);
  CallInst *Start2 = Builder.CreateLifetimeStart(Var2);
  CallInst *Start3 = Builder.CreateLifetimeStart(Var3, Builder.getInt64(100));

  EXPECT_EQ(Start1->getArgOperand(0), Builder.getInt64(-1));
  EXPECT_EQ(Start2->getArgOperand(0), Builder.getInt64(-1));
  EXPECT_EQ(Start3->getArgOperand(0), Builder.getInt64(100));

  EXPECT_EQ(Start1->getArgOperand(1), Var1);
  EXPECT_NE(Start2->getArgOperand(1), Var2);
  EXPECT_EQ(Start3->getArgOperand(1), Var3);

  Value *End1 = Builder.CreateLifetimeEnd(Var1);
  Builder.CreateLifetimeEnd(Var2);
  Builder.CreateLifetimeEnd(Var3);

  IntrinsicInst *II_Start1 = dyn_cast<IntrinsicInst>(Start1);
  IntrinsicInst *II_End1 = dyn_cast<IntrinsicInst>(End1);
  ASSERT_TRUE(II_Start1 != NULL);
  EXPECT_EQ(II_Start1->getIntrinsicID(), Intrinsic::lifetime_start);
  ASSERT_TRUE(II_End1 != NULL);
  EXPECT_EQ(II_End1->getIntrinsicID(), Intrinsic::lifetime_end);
}

TEST_F(IRBuilderTest, CreateCondBr) {
  IRBuilder<> Builder(BB);
  BasicBlock *TBB = BasicBlock::Create(getGlobalContext(), "", F);
  BasicBlock *FBB = BasicBlock::Create(getGlobalContext(), "", F);

  BranchInst *BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
  TerminatorInst *TI = BB->getTerminator();
  EXPECT_EQ(BI, TI);
  EXPECT_EQ(2u, TI->getNumSuccessors());
  EXPECT_EQ(TBB, TI->getSuccessor(0));
  EXPECT_EQ(FBB, TI->getSuccessor(1));

  BI->eraseFromParent();
  MDNode *Weights = MDBuilder(getGlobalContext()).createBranchWeights(42, 13);
  BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB, Weights);
  TI = BB->getTerminator();
  EXPECT_EQ(BI, TI);
  EXPECT_EQ(2u, TI->getNumSuccessors());
  EXPECT_EQ(TBB, TI->getSuccessor(0));
  EXPECT_EQ(FBB, TI->getSuccessor(1));
  EXPECT_EQ(Weights, TI->getMetadata(LLVMContext::MD_prof));
}

TEST_F(IRBuilderTest, LandingPadName) {
  IRBuilder<> Builder(BB);
  LandingPadInst *LP = Builder.CreateLandingPad(Builder.getInt32Ty(),
                                                Builder.getInt32(0), 0, "LP");
  EXPECT_EQ(LP->getName(), "LP");
}

TEST_F(IRBuilderTest, GetIntTy) {
  IRBuilder<> Builder(BB);
  IntegerType *Ty1 = Builder.getInt1Ty();
  EXPECT_EQ(Ty1, IntegerType::get(getGlobalContext(), 1));

  DataLayout* DL = new DataLayout(M.get());
  IntegerType *IntPtrTy = Builder.getIntPtrTy(DL);
  unsigned IntPtrBitSize =  DL->getPointerSizeInBits(0);
  EXPECT_EQ(IntPtrTy, IntegerType::get(getGlobalContext(), IntPtrBitSize));
  delete DL;
}

TEST_F(IRBuilderTest, FastMathFlags) {
  IRBuilder<> Builder(BB);
  Value *F;
  Instruction *FDiv, *FAdd;

  F = Builder.CreateLoad(GV);
  F = Builder.CreateFAdd(F, F);

  EXPECT_FALSE(Builder.getFastMathFlags().any());
  ASSERT_TRUE(isa<Instruction>(F));
  FAdd = cast<Instruction>(F);
  EXPECT_FALSE(FAdd->hasNoNaNs());

  FastMathFlags FMF;
  Builder.SetFastMathFlags(FMF);

  F = Builder.CreateFAdd(F, F);
  EXPECT_FALSE(Builder.getFastMathFlags().any());

  FMF.setUnsafeAlgebra();
  Builder.SetFastMathFlags(FMF);

  F = Builder.CreateFAdd(F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  ASSERT_TRUE(isa<Instruction>(F));
  FAdd = cast<Instruction>(F);
  EXPECT_TRUE(FAdd->hasNoNaNs());

  F = Builder.CreateFDiv(F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  EXPECT_TRUE(Builder.getFastMathFlags().UnsafeAlgebra);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_TRUE(FDiv->hasAllowReciprocal());

  Builder.clearFastMathFlags();

  F = Builder.CreateFDiv(F, F);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_FALSE(FDiv->hasAllowReciprocal());

  FMF.clear();
  FMF.setAllowReciprocal();
  Builder.SetFastMathFlags(FMF);

  F = Builder.CreateFDiv(F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  EXPECT_TRUE(Builder.getFastMathFlags().AllowReciprocal);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_TRUE(FDiv->hasAllowReciprocal());

  Builder.clearFastMathFlags();

  F = Builder.CreateFDiv(F, F);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_FALSE(FDiv->getFastMathFlags().any());
  FDiv->copyFastMathFlags(FAdd);
  EXPECT_TRUE(FDiv->hasNoNaNs());

}

TEST_F(IRBuilderTest, RAIIHelpersTest) {
  IRBuilder<> Builder(BB);
  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
  MDBuilder MDB(M->getContext());

  MDNode *FPMathA = MDB.createFPMath(0.01f);
  MDNode *FPMathB = MDB.createFPMath(0.1f);

  Builder.SetDefaultFPMathTag(FPMathA);

  {
    IRBuilder<>::FastMathFlagGuard Guard(Builder);
    FastMathFlags FMF;
    FMF.setAllowReciprocal();
    Builder.SetFastMathFlags(FMF);
    Builder.SetDefaultFPMathTag(FPMathB);
    EXPECT_TRUE(Builder.getFastMathFlags().allowReciprocal());
    EXPECT_EQ(FPMathB, Builder.getDefaultFPMathTag());
  }

  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
  EXPECT_EQ(FPMathA, Builder.getDefaultFPMathTag());

  Value *F = Builder.CreateLoad(GV);

  {
    IRBuilder<>::InsertPointGuard Guard(Builder);
    Builder.SetInsertPoint(cast<Instruction>(F));
    EXPECT_EQ(F, Builder.GetInsertPoint());
  }

  EXPECT_EQ(BB->end(), Builder.GetInsertPoint());
  EXPECT_EQ(BB, Builder.GetInsertBlock());
}

}
<|endoftext|>


<commit_before><commit_msg>coverity#1242750 Unused value<commit_after><|endoftext|>


<commit_before>/* Copyright 2015 MINDS-i, INC.

   Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include "MINDSi.h"

using namespace MINDSi;

namespace { //make sure these vars/functions aren't visible outside
	volatile uint32_t	pStart[EXTERNAL_NUM_INTERRUPTS];
	volatile uint32_t	pTime [EXTERNAL_NUM_INTERRUPTS];
	volatile int8_t		interruptPin[EXTERNAL_NUM_INTERRUPTS];
	boolean				interruptOn[EXTERNAL_NUM_INTERRUPTS];

	//normal digitalRead is too slow for Interrupt handlers
	inline bool fastDigitalRead(int pin){
		return *portInputRegister(digitalPinToPort(pin))
				& digitalPinToBitMask(pin);
	}

	boolean inline isIntOn(int interrupt){
		//the registers differ too much on each chip to read directly
		return interruptOn[interrupt];
	}

	template<int num>
	void inline iFunc(void){
		if(fastDigitalRead(interruptPin[num])) pStart[num] = micros();
		else pTime[num] = micros()-pStart[num];
	}

	//number of interrupts can only by 2,3,5 or 8 on current models;
	voidFuncPtr func[EXTERNAL_NUM_INTERRUPTS]={
		 iFunc<0>
		,iFunc<1>
	#if EXTERNAL_NUM_INTERRUPTS > 2
		,iFunc<2>
	#if EXTERNAL_NUM_INTERRUPTS > 3
		,iFunc<3>
	#if EXTERNAL_NUM_INTERRUPTS > 4
		,iFunc<4>
	#if EXTERNAL_NUM_INTERRUPTS > 5
		,iFunc<5>
		,iFunc<6>
		,iFunc<7>
	#endif
	#endif
	#endif
	#endif
	};
}

uint16_t getRadioPulse(int pin, bool interrupt){
	uint16_t pulse = 0;
	int iNum  = digitalPinToInterrupt(pin);

	//get signal width
	if(interrupt && iNum!=NOT_AN_INTERRUPT){
		if (!isIntOn(iNum)) {
			attachInterrupt(iNum, func[iNum], CHANGE);
			interruptPin[iNum] = pin; //there is no interruptToDigitalPin Macro
			interruptOn[iNum]  = true;
			interrupts();
		} else {
			uint32_t refresh_time = micros()-pStart[iNum];
			pulse = (refresh_time >= RADIO_PULSE_TIMEOUT)? 0 : pTime[iNum];
		}
	} else {
		pulse = pulseIn(pin, HIGH, RADIO_PULSE_TIMEOUT);
	}

	if(pulse == 0) return NO_PULSE;
	if(pulse > RADIO_PULSE_TIMEOUT) return NO_PULSE;
	return pulse;
}

uint16_t getRadio(int pin, bool interrupt){
	uint16_t pulse = getRadioPulse(pin, interrupt);
	if (pulse == NO_PULSE) {
		return DEFAULT_RADIO_SIGNAL;
	}
	const int sig = map(pulse, RADIO_MIN_US, RADIO_MAX_US, 0, 180);
	return constrain(sig, 0, 180);
}

bool isRadioOn(int pin, bool interrupt){
	return (getRadioPulse(pin, interrupt) != NO_PULSE);
}

uint16_t getPing(int pin, uint16_t maxMicros){
	pinMode(pin, OUTPUT);
	digitalWrite(pin, LOW);
	delayMicroseconds(5);
	digitalWrite(pin, HIGH);
	delayMicroseconds(5);
	digitalWrite(pin, LOW);
	delayMicroseconds(5);
	pinMode(pin, INPUT);
	int inputpulse = pulseIn(pin, HIGH, maxMicros);
	if(inputpulse == 0) inputpulse = maxMicros;
	delayMicroseconds(200);
	pinMode(pin, OUTPUT);
	digitalWrite(pin, LOW);
	return inputpulse;
}

uint16_t QTI(int pin, uint16_t maxLoops){
	uint16_t time = 0;
	pinMode(pin, OUTPUT);
	digitalWrite(pin, HIGH);
	delay(1);
	pinMode(pin, INPUT);
	digitalWrite(pin, LOW);
	while (digitalRead(pin)) {
		time++;
		if(time >= maxLoops) break;
	}
	return time;
}
<commit_msg>whitespace - change indentation to spaces<commit_after>/* Copyright 2015 MINDS-i, INC.

   Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/

#include "MINDSi.h"

using namespace MINDSi;

namespace { //make sure these vars/functions aren't visible outside
    volatile uint32_t   pStart[EXTERNAL_NUM_INTERRUPTS];
    volatile uint32_t   pTime [EXTERNAL_NUM_INTERRUPTS];
    volatile int8_t     interruptPin[EXTERNAL_NUM_INTERRUPTS];
    boolean             interruptOn[EXTERNAL_NUM_INTERRUPTS];

    //normal digitalRead is too slow for Interrupt handlers
    inline bool fastDigitalRead(int pin){
        return *portInputRegister(digitalPinToPort(pin))
                & digitalPinToBitMask(pin);
    }

    boolean inline isIntOn(int interrupt){
        //the registers differ too much on each chip to read directly
        return interruptOn[interrupt];
    }

    template<int num>
    void inline iFunc(void){
        if(fastDigitalRead(interruptPin[num])) pStart[num] = micros();
        else pTime[num] = micros()-pStart[num];
    }

    //number of interrupts can only by 2,3,5 or 8 on current models;
    voidFuncPtr func[EXTERNAL_NUM_INTERRUPTS]={
         iFunc<0>
        ,iFunc<1>
    #if EXTERNAL_NUM_INTERRUPTS > 2
        ,iFunc<2>
    #if EXTERNAL_NUM_INTERRUPTS > 3
        ,iFunc<3>
    #if EXTERNAL_NUM_INTERRUPTS > 4
        ,iFunc<4>
    #if EXTERNAL_NUM_INTERRUPTS > 5
        ,iFunc<5>
        ,iFunc<6>
        ,iFunc<7>
    #endif
    #endif
    #endif
    #endif
    };
}

uint16_t getRadioPulse(int pin, bool interrupt){
    uint16_t pulse = 0;
    int iNum  = digitalPinToInterrupt(pin);

    //get signal width
    if(interrupt && iNum!=NOT_AN_INTERRUPT){
        if (!isIntOn(iNum)) {
            attachInterrupt(iNum, func[iNum], CHANGE);
            interruptPin[iNum] = pin; //there is no interruptToDigitalPin Macro
            interruptOn[iNum]  = true;
            interrupts();
        } else {
            uint32_t refresh_time = micros()-pStart[iNum];
            pulse = (refresh_time >= RADIO_PULSE_TIMEOUT)? 0 : pTime[iNum];
        }
    } else {
        pulse = pulseIn(pin, HIGH, RADIO_PULSE_TIMEOUT);
    }

    if(pulse == 0) return NO_PULSE;
    if(pulse > RADIO_PULSE_TIMEOUT) return NO_PULSE;
    return pulse;
}

uint16_t getRadio(int pin, bool interrupt){
    uint16_t pulse = getRadioPulse(pin, interrupt);
    if (pulse == NO_PULSE) {
        return DEFAULT_RADIO_SIGNAL;
    }
    const int sig = map(pulse, RADIO_MIN_US, RADIO_MAX_US, 0, 180);
    return constrain(sig, 0, 180);
}

bool isRadioOn(int pin, bool interrupt){
    return (getRadioPulse(pin, interrupt) != NO_PULSE);
}

uint16_t getPing(int pin, uint16_t maxMicros){
    pinMode(pin, OUTPUT);
    digitalWrite(pin, LOW);
    delayMicroseconds(5);
    digitalWrite(pin, HIGH);
    delayMicroseconds(5);
    digitalWrite(pin, LOW);
    delayMicroseconds(5);
    pinMode(pin, INPUT);
    int inputpulse = pulseIn(pin, HIGH, maxMicros);
    if(inputpulse == 0) inputpulse = maxMicros;
    delayMicroseconds(200);
    pinMode(pin, OUTPUT);
    digitalWrite(pin, LOW);
    return inputpulse;
}

uint16_t QTI(int pin, uint16_t maxLoops){
    uint16_t time = 0;
    pinMode(pin, OUTPUT);
    digitalWrite(pin, HIGH);
    delay(1);
    pinMode(pin, INPUT);
    digitalWrite(pin, LOW);
    while (digitalRead(pin)) {
        time++;
        if(time >= maxLoops) break;
    }
    return time;
}
<|endoftext|>


<commit_before>//===- llvm/unittest/IR/IRBuilderTest.cpp - IRBuilder tests ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Verifier.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace {

class IRBuilderTest : public testing::Test {
protected:
  void SetUp() override {
    M.reset(new Module("MyModule", Ctx));
    FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
                                          /*isVarArg=*/false);
    F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
    BB = BasicBlock::Create(Ctx, "", F);
    GV = new GlobalVariable(*M, Type::getFloatTy(Ctx), true,
                            GlobalValue::ExternalLinkage, nullptr);
  }

  void TearDown() override {
    BB = nullptr;
    M.reset();
  }

  LLVMContext Ctx;
  std::unique_ptr<Module> M;
  Function *F;
  BasicBlock *BB;
  GlobalVariable *GV;
};

TEST_F(IRBuilderTest, Lifetime) {
  IRBuilder<> Builder(BB);
  AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());
  AllocaInst *Var2 = Builder.CreateAlloca(Builder.getInt32Ty());
  AllocaInst *Var3 = Builder.CreateAlloca(Builder.getInt8Ty(),
                                          Builder.getInt32(123));

  CallInst *Start1 = Builder.CreateLifetimeStart(Var1);
  CallInst *Start2 = Builder.CreateLifetimeStart(Var2);
  CallInst *Start3 = Builder.CreateLifetimeStart(Var3, Builder.getInt64(100));

  EXPECT_EQ(Start1->getArgOperand(0), Builder.getInt64(-1));
  EXPECT_EQ(Start2->getArgOperand(0), Builder.getInt64(-1));
  EXPECT_EQ(Start3->getArgOperand(0), Builder.getInt64(100));

  EXPECT_EQ(Start1->getArgOperand(1), Var1);
  EXPECT_NE(Start2->getArgOperand(1), Var2);
  EXPECT_EQ(Start3->getArgOperand(1), Var3);

  Value *End1 = Builder.CreateLifetimeEnd(Var1);
  Builder.CreateLifetimeEnd(Var2);
  Builder.CreateLifetimeEnd(Var3);

  IntrinsicInst *II_Start1 = dyn_cast<IntrinsicInst>(Start1);
  IntrinsicInst *II_End1 = dyn_cast<IntrinsicInst>(End1);
  ASSERT_TRUE(II_Start1 != nullptr);
  EXPECT_EQ(II_Start1->getIntrinsicID(), Intrinsic::lifetime_start);
  ASSERT_TRUE(II_End1 != nullptr);
  EXPECT_EQ(II_End1->getIntrinsicID(), Intrinsic::lifetime_end);
}

TEST_F(IRBuilderTest, CreateCondBr) {
  IRBuilder<> Builder(BB);
  BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);
  BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);

  BranchInst *BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
  TerminatorInst *TI = BB->getTerminator();
  EXPECT_EQ(BI, TI);
  EXPECT_EQ(2u, TI->getNumSuccessors());
  EXPECT_EQ(TBB, TI->getSuccessor(0));
  EXPECT_EQ(FBB, TI->getSuccessor(1));

  BI->eraseFromParent();
  MDNode *Weights = MDBuilder(Ctx).createBranchWeights(42, 13);
  BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB, Weights);
  TI = BB->getTerminator();
  EXPECT_EQ(BI, TI);
  EXPECT_EQ(2u, TI->getNumSuccessors());
  EXPECT_EQ(TBB, TI->getSuccessor(0));
  EXPECT_EQ(FBB, TI->getSuccessor(1));
  EXPECT_EQ(Weights, TI->getMetadata(LLVMContext::MD_prof));
}

TEST_F(IRBuilderTest, LandingPadName) {
  IRBuilder<> Builder(BB);
  LandingPadInst *LP = Builder.CreateLandingPad(Builder.getInt32Ty(), 0, "LP");
  EXPECT_EQ(LP->getName(), "LP");
}

TEST_F(IRBuilderTest, DataLayout) {
  std::unique_ptr<Module> M(new Module("test", Ctx));
  M->setDataLayout("e-n32");
  EXPECT_TRUE(M->getDataLayout().isLegalInteger(32));
  M->setDataLayout("e");
  EXPECT_FALSE(M->getDataLayout().isLegalInteger(32));
}

TEST_F(IRBuilderTest, GetIntTy) {
  IRBuilder<> Builder(BB);
  IntegerType *Ty1 = Builder.getInt1Ty();
  EXPECT_EQ(Ty1, IntegerType::get(Ctx, 1));

  DataLayout* DL = new DataLayout(M.get());
  IntegerType *IntPtrTy = Builder.getIntPtrTy(*DL);
  unsigned IntPtrBitSize =  DL->getPointerSizeInBits(0);
  EXPECT_EQ(IntPtrTy, IntegerType::get(Ctx, IntPtrBitSize));
  delete DL;
}

TEST_F(IRBuilderTest, FastMathFlags) {
  IRBuilder<> Builder(BB);
  Value *F;
  Instruction *FDiv, *FAdd;

  F = Builder.CreateLoad(GV);
  F = Builder.CreateFAdd(F, F);

  EXPECT_FALSE(Builder.getFastMathFlags().any());
  ASSERT_TRUE(isa<Instruction>(F));
  FAdd = cast<Instruction>(F);
  EXPECT_FALSE(FAdd->hasNoNaNs());

  FastMathFlags FMF;
  Builder.SetFastMathFlags(FMF);

  F = Builder.CreateFAdd(F, F);
  EXPECT_FALSE(Builder.getFastMathFlags().any());

  FMF.setUnsafeAlgebra();
  Builder.SetFastMathFlags(FMF);

  F = Builder.CreateFAdd(F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  ASSERT_TRUE(isa<Instruction>(F));
  FAdd = cast<Instruction>(F);
  EXPECT_TRUE(FAdd->hasNoNaNs());

  // Now, try it with CreateBinOp
  F = Builder.CreateBinOp(Instruction::FAdd, F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  ASSERT_TRUE(isa<Instruction>(F));
  FAdd = cast<Instruction>(F);
  EXPECT_TRUE(FAdd->hasNoNaNs());

  F = Builder.CreateFDiv(F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  EXPECT_TRUE(Builder.getFastMathFlags().UnsafeAlgebra);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_TRUE(FDiv->hasAllowReciprocal());

  Builder.clearFastMathFlags();

  F = Builder.CreateFDiv(F, F);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_FALSE(FDiv->hasAllowReciprocal());

  FMF.clear();
  FMF.setAllowReciprocal();
  Builder.SetFastMathFlags(FMF);

  F = Builder.CreateFDiv(F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  EXPECT_TRUE(Builder.getFastMathFlags().AllowReciprocal);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_TRUE(FDiv->hasAllowReciprocal());

  Builder.clearFastMathFlags();

  // To test a copy, make sure that a '0' and a '1' change state.
  F = Builder.CreateFDiv(F, F);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_FALSE(FDiv->getFastMathFlags().any());
  FDiv->setHasAllowReciprocal(true);
  FAdd->setHasAllowReciprocal(false);
  FDiv->copyFastMathFlags(FAdd);
  EXPECT_TRUE(FDiv->hasNoNaNs());
  EXPECT_FALSE(FDiv->hasAllowReciprocal());

}

TEST_F(IRBuilderTest, WrapFlags) {
  IRBuilder<true, NoFolder> Builder(BB);

  // Test instructions.
  GlobalVariable *G = new GlobalVariable(*M, Builder.getInt32Ty(), true,
                                         GlobalValue::ExternalLinkage, nullptr);
  Value *V = Builder.CreateLoad(G);
  EXPECT_TRUE(
      cast<BinaryOperator>(Builder.CreateNSWAdd(V, V))->hasNoSignedWrap());
  EXPECT_TRUE(
      cast<BinaryOperator>(Builder.CreateNSWMul(V, V))->hasNoSignedWrap());
  EXPECT_TRUE(
      cast<BinaryOperator>(Builder.CreateNSWSub(V, V))->hasNoSignedWrap());
  EXPECT_TRUE(cast<BinaryOperator>(
                  Builder.CreateShl(V, V, "", /* NUW */ false, /* NSW */ true))
                  ->hasNoSignedWrap());

  EXPECT_TRUE(
      cast<BinaryOperator>(Builder.CreateNUWAdd(V, V))->hasNoUnsignedWrap());
  EXPECT_TRUE(
      cast<BinaryOperator>(Builder.CreateNUWMul(V, V))->hasNoUnsignedWrap());
  EXPECT_TRUE(
      cast<BinaryOperator>(Builder.CreateNUWSub(V, V))->hasNoUnsignedWrap());
  EXPECT_TRUE(cast<BinaryOperator>(
                  Builder.CreateShl(V, V, "", /* NUW */ true, /* NSW */ false))
                  ->hasNoUnsignedWrap());

  // Test operators created with constants.
  Constant *C = Builder.getInt32(42);
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWAdd(C, C))
                  ->hasNoSignedWrap());
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWSub(C, C))
                  ->hasNoSignedWrap());
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWMul(C, C))
                  ->hasNoSignedWrap());
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(
                  Builder.CreateShl(C, C, "", /* NUW */ false, /* NSW */ true))
                  ->hasNoSignedWrap());

  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWAdd(C, C))
                  ->hasNoUnsignedWrap());
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWSub(C, C))
                  ->hasNoUnsignedWrap());
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWMul(C, C))
                  ->hasNoUnsignedWrap());
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(
                  Builder.CreateShl(C, C, "", /* NUW */ true, /* NSW */ false))
                  ->hasNoUnsignedWrap());
}

TEST_F(IRBuilderTest, RAIIHelpersTest) {
  IRBuilder<> Builder(BB);
  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
  MDBuilder MDB(M->getContext());

  MDNode *FPMathA = MDB.createFPMath(0.01f);
  MDNode *FPMathB = MDB.createFPMath(0.1f);

  Builder.SetDefaultFPMathTag(FPMathA);

  {
    IRBuilder<>::FastMathFlagGuard Guard(Builder);
    FastMathFlags FMF;
    FMF.setAllowReciprocal();
    Builder.SetFastMathFlags(FMF);
    Builder.SetDefaultFPMathTag(FPMathB);
    EXPECT_TRUE(Builder.getFastMathFlags().allowReciprocal());
    EXPECT_EQ(FPMathB, Builder.getDefaultFPMathTag());
  }

  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
  EXPECT_EQ(FPMathA, Builder.getDefaultFPMathTag());

  Value *F = Builder.CreateLoad(GV);

  {
    IRBuilder<>::InsertPointGuard Guard(Builder);
    Builder.SetInsertPoint(cast<Instruction>(F));
    EXPECT_EQ(F, Builder.GetInsertPoint());
  }

  EXPECT_EQ(BB->end(), Builder.GetInsertPoint());
  EXPECT_EQ(BB, Builder.GetInsertBlock());
}

TEST_F(IRBuilderTest, DIBuilder) {
  IRBuilder<> Builder(BB);
  DIBuilder DIB(*M);
  auto File = DIB.createFile("F.CBL", "/");
  auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Cobol74, "F.CBL", "/",
                                  "llvm-cobol74", true, "", 0);
  auto Type = DIB.createSubroutineType(File, DIB.getOrCreateTypeArray(None));
  DIB.createFunction(CU, "foo", "", File, 1, Type, false, true, 1, 0, true, F);
  AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
  auto BarSP = DIB.createFunction(CU, "bar", "", File, 1, Type, false, true, 1,
                                  0, true, nullptr);
  auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0);
  I->setDebugLoc(DebugLoc::get(2, 0, BadScope));
  DIB.finalize();
  EXPECT_TRUE(verifyModule(*M));
}

TEST_F(IRBuilderTest, InsertExtractElement) {
  IRBuilder<> Builder(BB);

  auto VecTy = VectorType::get(Builder.getInt64Ty(), 4);
  auto Elt1 = Builder.getInt64(-1);
  auto Elt2 = Builder.getInt64(-2);
  Value *Vec = UndefValue::get(VecTy);
  Vec = Builder.CreateInsertElement(Vec, Elt1, Builder.getInt8(1));
  Vec = Builder.CreateInsertElement(Vec, Elt2, 2);
  auto X1 = Builder.CreateExtractElement(Vec, 1);
  auto X2 = Builder.CreateExtractElement(Vec, Builder.getInt32(2));
  EXPECT_EQ(Elt1, X1);
  EXPECT_EQ(Elt2, X2);
}

}
<commit_msg>IRBuilder: Add unit tests for construction of globals with address space<commit_after>//===- llvm/unittest/IR/IRBuilderTest.cpp - IRBuilder tests ---------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/NoFolder.h"
#include "llvm/IR/Verifier.h"
#include "gtest/gtest.h"

using namespace llvm;

namespace {

class IRBuilderTest : public testing::Test {
protected:
  void SetUp() override {
    M.reset(new Module("MyModule", Ctx));
    FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
                                          /*isVarArg=*/false);
    F = Function::Create(FTy, Function::ExternalLinkage, "", M.get());
    BB = BasicBlock::Create(Ctx, "", F);
    GV = new GlobalVariable(*M, Type::getFloatTy(Ctx), true,
                            GlobalValue::ExternalLinkage, nullptr);
  }

  void TearDown() override {
    BB = nullptr;
    M.reset();
  }

  LLVMContext Ctx;
  std::unique_ptr<Module> M;
  Function *F;
  BasicBlock *BB;
  GlobalVariable *GV;
};

TEST_F(IRBuilderTest, Lifetime) {
  IRBuilder<> Builder(BB);
  AllocaInst *Var1 = Builder.CreateAlloca(Builder.getInt8Ty());
  AllocaInst *Var2 = Builder.CreateAlloca(Builder.getInt32Ty());
  AllocaInst *Var3 = Builder.CreateAlloca(Builder.getInt8Ty(),
                                          Builder.getInt32(123));

  CallInst *Start1 = Builder.CreateLifetimeStart(Var1);
  CallInst *Start2 = Builder.CreateLifetimeStart(Var2);
  CallInst *Start3 = Builder.CreateLifetimeStart(Var3, Builder.getInt64(100));

  EXPECT_EQ(Start1->getArgOperand(0), Builder.getInt64(-1));
  EXPECT_EQ(Start2->getArgOperand(0), Builder.getInt64(-1));
  EXPECT_EQ(Start3->getArgOperand(0), Builder.getInt64(100));

  EXPECT_EQ(Start1->getArgOperand(1), Var1);
  EXPECT_NE(Start2->getArgOperand(1), Var2);
  EXPECT_EQ(Start3->getArgOperand(1), Var3);

  Value *End1 = Builder.CreateLifetimeEnd(Var1);
  Builder.CreateLifetimeEnd(Var2);
  Builder.CreateLifetimeEnd(Var3);

  IntrinsicInst *II_Start1 = dyn_cast<IntrinsicInst>(Start1);
  IntrinsicInst *II_End1 = dyn_cast<IntrinsicInst>(End1);
  ASSERT_TRUE(II_Start1 != nullptr);
  EXPECT_EQ(II_Start1->getIntrinsicID(), Intrinsic::lifetime_start);
  ASSERT_TRUE(II_End1 != nullptr);
  EXPECT_EQ(II_End1->getIntrinsicID(), Intrinsic::lifetime_end);
}

TEST_F(IRBuilderTest, CreateCondBr) {
  IRBuilder<> Builder(BB);
  BasicBlock *TBB = BasicBlock::Create(Ctx, "", F);
  BasicBlock *FBB = BasicBlock::Create(Ctx, "", F);

  BranchInst *BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB);
  TerminatorInst *TI = BB->getTerminator();
  EXPECT_EQ(BI, TI);
  EXPECT_EQ(2u, TI->getNumSuccessors());
  EXPECT_EQ(TBB, TI->getSuccessor(0));
  EXPECT_EQ(FBB, TI->getSuccessor(1));

  BI->eraseFromParent();
  MDNode *Weights = MDBuilder(Ctx).createBranchWeights(42, 13);
  BI = Builder.CreateCondBr(Builder.getTrue(), TBB, FBB, Weights);
  TI = BB->getTerminator();
  EXPECT_EQ(BI, TI);
  EXPECT_EQ(2u, TI->getNumSuccessors());
  EXPECT_EQ(TBB, TI->getSuccessor(0));
  EXPECT_EQ(FBB, TI->getSuccessor(1));
  EXPECT_EQ(Weights, TI->getMetadata(LLVMContext::MD_prof));
}

TEST_F(IRBuilderTest, LandingPadName) {
  IRBuilder<> Builder(BB);
  LandingPadInst *LP = Builder.CreateLandingPad(Builder.getInt32Ty(), 0, "LP");
  EXPECT_EQ(LP->getName(), "LP");
}

TEST_F(IRBuilderTest, DataLayout) {
  std::unique_ptr<Module> M(new Module("test", Ctx));
  M->setDataLayout("e-n32");
  EXPECT_TRUE(M->getDataLayout().isLegalInteger(32));
  M->setDataLayout("e");
  EXPECT_FALSE(M->getDataLayout().isLegalInteger(32));
}

TEST_F(IRBuilderTest, GetIntTy) {
  IRBuilder<> Builder(BB);
  IntegerType *Ty1 = Builder.getInt1Ty();
  EXPECT_EQ(Ty1, IntegerType::get(Ctx, 1));

  DataLayout* DL = new DataLayout(M.get());
  IntegerType *IntPtrTy = Builder.getIntPtrTy(*DL);
  unsigned IntPtrBitSize =  DL->getPointerSizeInBits(0);
  EXPECT_EQ(IntPtrTy, IntegerType::get(Ctx, IntPtrBitSize));
  delete DL;
}

TEST_F(IRBuilderTest, FastMathFlags) {
  IRBuilder<> Builder(BB);
  Value *F;
  Instruction *FDiv, *FAdd;

  F = Builder.CreateLoad(GV);
  F = Builder.CreateFAdd(F, F);

  EXPECT_FALSE(Builder.getFastMathFlags().any());
  ASSERT_TRUE(isa<Instruction>(F));
  FAdd = cast<Instruction>(F);
  EXPECT_FALSE(FAdd->hasNoNaNs());

  FastMathFlags FMF;
  Builder.SetFastMathFlags(FMF);

  F = Builder.CreateFAdd(F, F);
  EXPECT_FALSE(Builder.getFastMathFlags().any());

  FMF.setUnsafeAlgebra();
  Builder.SetFastMathFlags(FMF);

  F = Builder.CreateFAdd(F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  ASSERT_TRUE(isa<Instruction>(F));
  FAdd = cast<Instruction>(F);
  EXPECT_TRUE(FAdd->hasNoNaNs());

  // Now, try it with CreateBinOp
  F = Builder.CreateBinOp(Instruction::FAdd, F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  ASSERT_TRUE(isa<Instruction>(F));
  FAdd = cast<Instruction>(F);
  EXPECT_TRUE(FAdd->hasNoNaNs());

  F = Builder.CreateFDiv(F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  EXPECT_TRUE(Builder.getFastMathFlags().UnsafeAlgebra);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_TRUE(FDiv->hasAllowReciprocal());

  Builder.clearFastMathFlags();

  F = Builder.CreateFDiv(F, F);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_FALSE(FDiv->hasAllowReciprocal());

  FMF.clear();
  FMF.setAllowReciprocal();
  Builder.SetFastMathFlags(FMF);

  F = Builder.CreateFDiv(F, F);
  EXPECT_TRUE(Builder.getFastMathFlags().any());
  EXPECT_TRUE(Builder.getFastMathFlags().AllowReciprocal);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_TRUE(FDiv->hasAllowReciprocal());

  Builder.clearFastMathFlags();

  // To test a copy, make sure that a '0' and a '1' change state.
  F = Builder.CreateFDiv(F, F);
  ASSERT_TRUE(isa<Instruction>(F));
  FDiv = cast<Instruction>(F);
  EXPECT_FALSE(FDiv->getFastMathFlags().any());
  FDiv->setHasAllowReciprocal(true);
  FAdd->setHasAllowReciprocal(false);
  FDiv->copyFastMathFlags(FAdd);
  EXPECT_TRUE(FDiv->hasNoNaNs());
  EXPECT_FALSE(FDiv->hasAllowReciprocal());

}

TEST_F(IRBuilderTest, WrapFlags) {
  IRBuilder<true, NoFolder> Builder(BB);

  // Test instructions.
  GlobalVariable *G = new GlobalVariable(*M, Builder.getInt32Ty(), true,
                                         GlobalValue::ExternalLinkage, nullptr);
  Value *V = Builder.CreateLoad(G);
  EXPECT_TRUE(
      cast<BinaryOperator>(Builder.CreateNSWAdd(V, V))->hasNoSignedWrap());
  EXPECT_TRUE(
      cast<BinaryOperator>(Builder.CreateNSWMul(V, V))->hasNoSignedWrap());
  EXPECT_TRUE(
      cast<BinaryOperator>(Builder.CreateNSWSub(V, V))->hasNoSignedWrap());
  EXPECT_TRUE(cast<BinaryOperator>(
                  Builder.CreateShl(V, V, "", /* NUW */ false, /* NSW */ true))
                  ->hasNoSignedWrap());

  EXPECT_TRUE(
      cast<BinaryOperator>(Builder.CreateNUWAdd(V, V))->hasNoUnsignedWrap());
  EXPECT_TRUE(
      cast<BinaryOperator>(Builder.CreateNUWMul(V, V))->hasNoUnsignedWrap());
  EXPECT_TRUE(
      cast<BinaryOperator>(Builder.CreateNUWSub(V, V))->hasNoUnsignedWrap());
  EXPECT_TRUE(cast<BinaryOperator>(
                  Builder.CreateShl(V, V, "", /* NUW */ true, /* NSW */ false))
                  ->hasNoUnsignedWrap());

  // Test operators created with constants.
  Constant *C = Builder.getInt32(42);
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWAdd(C, C))
                  ->hasNoSignedWrap());
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWSub(C, C))
                  ->hasNoSignedWrap());
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNSWMul(C, C))
                  ->hasNoSignedWrap());
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(
                  Builder.CreateShl(C, C, "", /* NUW */ false, /* NSW */ true))
                  ->hasNoSignedWrap());

  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWAdd(C, C))
                  ->hasNoUnsignedWrap());
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWSub(C, C))
                  ->hasNoUnsignedWrap());
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(Builder.CreateNUWMul(C, C))
                  ->hasNoUnsignedWrap());
  EXPECT_TRUE(cast<OverflowingBinaryOperator>(
                  Builder.CreateShl(C, C, "", /* NUW */ true, /* NSW */ false))
                  ->hasNoUnsignedWrap());
}

TEST_F(IRBuilderTest, RAIIHelpersTest) {
  IRBuilder<> Builder(BB);
  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
  MDBuilder MDB(M->getContext());

  MDNode *FPMathA = MDB.createFPMath(0.01f);
  MDNode *FPMathB = MDB.createFPMath(0.1f);

  Builder.SetDefaultFPMathTag(FPMathA);

  {
    IRBuilder<>::FastMathFlagGuard Guard(Builder);
    FastMathFlags FMF;
    FMF.setAllowReciprocal();
    Builder.SetFastMathFlags(FMF);
    Builder.SetDefaultFPMathTag(FPMathB);
    EXPECT_TRUE(Builder.getFastMathFlags().allowReciprocal());
    EXPECT_EQ(FPMathB, Builder.getDefaultFPMathTag());
  }

  EXPECT_FALSE(Builder.getFastMathFlags().allowReciprocal());
  EXPECT_EQ(FPMathA, Builder.getDefaultFPMathTag());

  Value *F = Builder.CreateLoad(GV);

  {
    IRBuilder<>::InsertPointGuard Guard(Builder);
    Builder.SetInsertPoint(cast<Instruction>(F));
    EXPECT_EQ(F, Builder.GetInsertPoint());
  }

  EXPECT_EQ(BB->end(), Builder.GetInsertPoint());
  EXPECT_EQ(BB, Builder.GetInsertBlock());
}

TEST_F(IRBuilderTest, DIBuilder) {
  IRBuilder<> Builder(BB);
  DIBuilder DIB(*M);
  auto File = DIB.createFile("F.CBL", "/");
  auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Cobol74, "F.CBL", "/",
                                  "llvm-cobol74", true, "", 0);
  auto Type = DIB.createSubroutineType(File, DIB.getOrCreateTypeArray(None));
  DIB.createFunction(CU, "foo", "", File, 1, Type, false, true, 1, 0, true, F);
  AllocaInst *I = Builder.CreateAlloca(Builder.getInt8Ty());
  auto BarSP = DIB.createFunction(CU, "bar", "", File, 1, Type, false, true, 1,
                                  0, true, nullptr);
  auto BadScope = DIB.createLexicalBlockFile(BarSP, File, 0);
  I->setDebugLoc(DebugLoc::get(2, 0, BadScope));
  DIB.finalize();
  EXPECT_TRUE(verifyModule(*M));
}

TEST_F(IRBuilderTest, InsertExtractElement) {
  IRBuilder<> Builder(BB);

  auto VecTy = VectorType::get(Builder.getInt64Ty(), 4);
  auto Elt1 = Builder.getInt64(-1);
  auto Elt2 = Builder.getInt64(-2);
  Value *Vec = UndefValue::get(VecTy);
  Vec = Builder.CreateInsertElement(Vec, Elt1, Builder.getInt8(1));
  Vec = Builder.CreateInsertElement(Vec, Elt2, 2);
  auto X1 = Builder.CreateExtractElement(Vec, 1);
  auto X2 = Builder.CreateExtractElement(Vec, Builder.getInt32(2));
  EXPECT_EQ(Elt1, X1);
  EXPECT_EQ(Elt2, X2);
}

TEST_F(IRBuilderTest, CreateGlobalStringPtr) {
  IRBuilder<> Builder(BB);

  auto String1a = Builder.CreateGlobalStringPtr("TestString", "String1a");
  auto String1b = Builder.CreateGlobalStringPtr("TestString", "String1b", 0);
  auto String2 = Builder.CreateGlobalStringPtr("TestString", "String2", 1);
  auto String3 = Builder.CreateGlobalString("TestString", "String3", 2);

  EXPECT_TRUE(String1a->getType()->getPointerAddressSpace() == 0);
  EXPECT_TRUE(String1b->getType()->getPointerAddressSpace() == 0);
  EXPECT_TRUE(String2->getType()->getPointerAddressSpace() == 1);
  EXPECT_TRUE(String3->getType()->getPointerAddressSpace() == 2);
}
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include <fstream>
#ifdef ACTIONMONITOR_CS_PLUGIN

#include <os/ipclistener.h>
#include "csvirtualmachine.h"

CsVirtualMachine::CsVirtualMachine() :
  PowershellVirtualMachine()
{
}

CsVirtualMachine::~CsVirtualMachine()
{
}

/**
 * \brief Check if a given file extension is used by this API or not.
 * \param file the file we are checking
 * \return bool true|false if the given extension is powershell or not.
 */
bool CsVirtualMachine::IsExt(const MYODD_STRING& file)
{
  return myodd::files::IsExtension(file, _T("CS"));
}

/**
 * \brief create the full command line argument that will be passed to powershell
 * \param action the action we are working with
 * \param dllFullPath the full path of the dll
 * \param pluginPath the path to the plugin
 * \param uuid the unique id
 */
MYODD_STRING CsVirtualMachine::GetCommandLineArguments(
  const ActiveAction& action,
  const std::wstring& dllFullPath,
  const std::wstring& pluginPath,
  const std::wstring& uuid
)
{
  // the command is our class name.
  auto className = action.Command();

  // we want to create the powershell script
  auto script = myodd::strings::Format(

    L"# Press a key\n"
    L"function __amPressKey()\n"
    L"{\n"
    L"  #press key\n"
    L"  Write-Host -NoNewLine 'Press any key to continue...';\n"
    L"  $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');\n"
    L"}\n"
    L"\n"

    L"# Include the dll, (so the c# can access it)\n"
    L"Add-Type -Path \"%s\"\n"
    L"\n"

    L"# Create the Action monitor object to pass to the c# code\n"
    L"$am = New-Object Am.Core \"%s\"\n"
    L"\n"

    L"try {\n"
    L"  # Load the code.\n"
    L"  $code = [IO.File]::ReadAllText(\"%s\")\n"
    L"  \n"

    L"  # Pas it the common assemblies\n"
    L"  $assem = (\n"
    L"    \"System\",\n"
    L"    \"System.Core\",\n"
    L"    \"System.Collections.Generic\",\n"
    L"    \"System.Linq\",\n"
    L"    \"System.Text\",\n"
    L"    \"System.Threading.Tasks\",\n"
    L"    \"System.Data\",\n"
    L"    \"System.Net.Http\",\n"
    L"    \"System.Xml\",\n"
    L"    \"System.Xml.Linq\",\n"
    L"    \"System.Data.DataSetExtensions\",\n"
    L"    \"Microsoft.CSharp\",\n"
    L"    \"%s\"\n"
    L"  )\n"
    L"\n"
    L"  # Putting it all together\n"
    L"  Add-Type -TypeDefinition $code -ReferencedAssemblies $assem -Language CSharp\n"
    L"  $plugin = New-Object Am.%s $am\n"
    L"  [void]($plugin.Go())\n"
    L"\n"
    L"} catch {\n"
    L"  # Give the error message\n"
    L"  $ErrorMessage = $_.Exception.Message\n"
    L"\n"
    L"  $fullMessage = \"There was an error in script '%s', The error message was \"\"$ErrorMessage\"\"\"\n"
    L"  [void]($am.Log( 2, $fullMessage ))\n"
    L"  Write-Warning $fullMessage\n"
    L"  # And then wait\n"
    L"  __amPressKey;\n"
    L"}\n"
    , dllFullPath.c_str()   // create object
    , uuid.c_str()          // unique id
    , pluginPath.c_str()    // the code itself.
    , dllFullPath.c_str()   // assemblies
    , className.c_str()     // the class name
    , pluginPath.c_str()    // the code itself, (for the error).
  );

  std::wstring file;
  myodd::files::GetFullTempFileName(file, L"file", L"ps1");
  std::wofstream myfile;
  myfile.open(file.c_str());
  myfile << script.c_str();
  myfile.close();

  // The simply execute the
  return myodd::strings::Format(
    _T("-command \"&{$policy = Get-ExecutionPolicy; Set-ExecutionPolicy RemoteSigned -Force; Add-Type -Path '%s'; . '%s';Set-ExecutionPolicy $policy -Force; }\""),
    dllFullPath.c_str(),
    file.c_str()
  );
}
#endif /*ACTIONMONITOR_CS_PLUGIN*/<commit_msg>Fixed some c#/PS1 assemblies<commit_after>#include "stdafx.h"
#include <fstream>
#ifdef ACTIONMONITOR_CS_PLUGIN

#include <os/ipclistener.h>
#include "csvirtualmachine.h"

CsVirtualMachine::CsVirtualMachine() :
  PowershellVirtualMachine()
{
}

CsVirtualMachine::~CsVirtualMachine()
{
}

/**
 * \brief Check if a given file extension is used by this API or not.
 * \param file the file we are checking
 * \return bool true|false if the given extension is powershell or not.
 */
bool CsVirtualMachine::IsExt(const MYODD_STRING& file)
{
  return myodd::files::IsExtension(file, _T("CS"));
}

/**
 * \brief create the full command line argument that will be passed to powershell
 * \param action the action we are working with
 * \param dllFullPath the full path of the dll
 * \param pluginPath the path to the plugin
 * \param uuid the unique id
 */
MYODD_STRING CsVirtualMachine::GetCommandLineArguments(
  const ActiveAction& action,
  const std::wstring& dllFullPath,
  const std::wstring& pluginPath,
  const std::wstring& uuid
)
{
  // the command is our class name.
  auto className = action.Command();

  // we want to create the powershell script
  auto script = myodd::strings::Format(

    L"# Press a key\n"
    L"function __amPressKey()\n"
    L"{\n"
    L"  #press key\n"
    L"  Write-Host -NoNewLine 'Press any key to continue...';\n"
    L"  $null = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown');\n"
    L"}\n"
    L"\n"

    L"# Include the dll, (so the c# can access it)\n"
    L"Add-Type -Path \"%s\"\n"
    L"\n"

    L"# Create the Action monitor object to pass to the c# code\n"
    L"$am = New-Object Am.Core \"%s\"\n"
    L"\n"

    L"try {\n"
    L"  # Load the code.\n"
    L"  $code = [IO.File]::ReadAllText(\"%s\")\n"
    L"  \n"

    L"  # Pas it the common assemblies\n"
    L"  $assem = (\n"
    L"    \"Microsoft.CSharp\",\n"
    L"    \"System\",\n"
    L"    \"System.Core\",\n"
    L"    \"System.Data\",\n"
    L"    \"System.Data.DataSetExtensions\",\n"
    L"    \"System.Deployment\",\n"
    L"    \"System.Drawing\",\n"
    L"    \"System.Net.Http\",\n"
    L"    \"System.Windows.Forms\",\n"
    L"    \"System.Linq\",\n"
    L"    \"System.Threading.Tasks\",\n"
    L"    \"System.Xml\",\n"
    L"    \"System.Xml.Linq\",\n"
    L"    \"%s\"\n"
    L"  )\n"
    L"\n"
    L"  # Putting it all together\n"
    L"  Add-Type -TypeDefinition $code -ReferencedAssemblies $assem -Language CSharp\n"
    L"  $plugin = New-Object Am.%s $am\n"
    L"  [void]($plugin.Go())\n"
    L"\n"
    L"} catch {\n"
    L"  # Give the error message\n"
    L"  $ErrorMessage = $_.Exception.Message\n"
    L"\n"
    L"  $fullMessage = \"There was an error in script '%s', The error message was \"\"$ErrorMessage\"\"\"\n"
    L"  [void]($am.Log( 2, $fullMessage ))\n"
    L"  Write-Warning $fullMessage\n"
    L"  # And then wait\n"
    L"  __amPressKey;\n"
    L"}\n"
    , dllFullPath.c_str()   // create object
    , uuid.c_str()          // unique id
    , pluginPath.c_str()    // the code itself.
    , dllFullPath.c_str()   // assemblies
    , className.c_str()     // the class name
    , pluginPath.c_str()    // the code itself, (for the error).
  );

  std::wstring file;
  myodd::files::GetFullTempFileName(file, L"file", L"ps1");
  std::wofstream myfile;
  myfile.open(file.c_str());
  myfile << script.c_str();
  myfile.close();

  // The simply execute the
  return myodd::strings::Format(
    _T("-command \"&{$policy = Get-ExecutionPolicy; Set-ExecutionPolicy RemoteSigned -Force; Add-Type -Path '%s'; . '%s';Set-ExecutionPolicy $policy -Force; }\""),
    dllFullPath.c_str(),
    file.c_str()
  );
}
#endif /*ACTIONMONITOR_CS_PLUGIN*/<|endoftext|>