<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/
#include "remotelinuxdebugsupport.h"

#include "linuxdeviceconfiguration.h"
#include "remotelinuxapplicationrunner.h"
#include "remotelinuxrunconfiguration.h"
#include "remotelinuxusedportsgatherer.h"

#include <debugger/debuggerengine.h>
#include <debugger/debuggerstartparameters.h>
#include <projectexplorer/abi.h>
#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <utils/qtcassert.h>

#include <QtCore/QPointer>
#include <QtCore/QSharedPointer>

using namespace Utils;
using namespace Debugger;
using namespace ProjectExplorer;

namespace RemoteLinux {
namespace Internal {
namespace {
enum State { Inactive, StartingRunner, StartingRemoteProcess, Debugging };
} // anonymous namespace

class AbstractRemoteLinuxDebugSupportPrivate
{
public:
    AbstractRemoteLinuxDebugSupportPrivate(RemoteLinuxRunConfiguration *runConfig,
            DebuggerEngine *engine)
        : engine(engine), runConfig(runConfig), deviceConfig(runConfig->deviceConfig()),
          debuggingType(runConfig->debuggingType()), state(Inactive),
          gdbServerPort(-1), qmlPort(-1)
    {
    }

    const QPointer<Debugger::DebuggerEngine> engine;
    const QPointer<RemoteLinuxRunConfiguration> runConfig;
    const LinuxDeviceConfiguration::ConstPtr deviceConfig;
    const RemoteLinuxRunConfiguration::DebuggingType debuggingType;

    QByteArray gdbserverOutput;
    State state;
    int gdbServerPort;
    int qmlPort;
};

class RemoteLinuxDebugSupportPrivate
{
public:
    RemoteLinuxDebugSupportPrivate(RemoteLinuxRunConfiguration *runConfig) : runner(runConfig) {}

    GenericRemoteLinuxApplicationRunner runner;
};

} // namespace Internal

using namespace Internal;

DebuggerStartParameters AbstractRemoteLinuxDebugSupport::startParameters(const RemoteLinuxRunConfiguration *runConfig)
{
    DebuggerStartParameters params;
    const LinuxDeviceConfiguration::ConstPtr &devConf = runConfig->deviceConfig();
    const RemoteLinuxRunConfiguration::DebuggingType debuggingType
        = runConfig->debuggingType();
    if (debuggingType != RemoteLinuxRunConfiguration::DebugCppOnly) {
        params.qmlServerAddress = runConfig->deviceConfig()->sshParameters().host;
        params.qmlServerPort = -1;
    }
    if (debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) {
        params.processArgs = runConfig->arguments();
        if (runConfig->activeQt4BuildConfiguration()->qtVersion())
            params.sysroot = runConfig->activeQt4BuildConfiguration()->qtVersion()->systemRoot();
        params.toolChainAbi = runConfig->abi();
        params.startMode = AttachToRemote;
        params.executable = runConfig->localExecutableFilePath();
        params.debuggerCommand = runConfig->gdbCmd();
        params.remoteChannel = devConf->sshParameters().host + QLatin1String(":-1");
        params.useServerStartScript = true;

        // TODO: This functionality should be inside the debugger.
        const ProjectExplorer::Abi &abi = runConfig->target()
            ->activeBuildConfiguration()->toolChain()->targetAbi();
        params.remoteArchitecture = abi.toString();
        params.gnuTarget = QLatin1String(abi.architecture() == ProjectExplorer::Abi::ArmArchitecture
            ? "arm-none-linux-gnueabi": "i386-unknown-linux-gnu");
    } else {
        params.startMode = AttachToRemote;
    }
    params.displayName = runConfig->displayName();

    if (const ProjectExplorer::Project *project = runConfig->target()->project()) {
        params.projectSourceDirectory = project->projectDirectory();
        if (const ProjectExplorer::BuildConfiguration *buildConfig = runConfig->target()->activeBuildConfiguration()) {
            params.projectBuildDirectory = buildConfig->buildDirectory();
        }
        params.projectSourceFiles = project->files(Project::ExcludeGeneratedFiles);
    }

    return params;
}

AbstractRemoteLinuxDebugSupport::AbstractRemoteLinuxDebugSupport(RemoteLinuxRunConfiguration *runConfig,
        DebuggerEngine *engine)
    : QObject(engine), m_d(new AbstractRemoteLinuxDebugSupportPrivate(runConfig, engine))
{
    connect(m_d->engine, SIGNAL(requestRemoteSetup()), this, SLOT(handleAdapterSetupRequested()));
}

AbstractRemoteLinuxDebugSupport::~AbstractRemoteLinuxDebugSupport()
{
    setFinished();
    delete m_d;
}

void AbstractRemoteLinuxDebugSupport::showMessage(const QString &msg, int channel)
{
    if (m_d->engine)
        m_d->engine->showMessage(msg, channel);
}

void AbstractRemoteLinuxDebugSupport::handleAdapterSetupRequested()
{
    QTC_ASSERT(m_d->state == Inactive, return);

    m_d->state = StartingRunner;
    showMessage(tr("Preparing remote side ...\n"), AppStuff);
    disconnect(runner(), 0, this, 0);
    connect(runner(), SIGNAL(error(QString)), this, SLOT(handleSshError(QString)));
    connect(runner(), SIGNAL(readyForExecution()), this, SLOT(startExecution()));
    connect(runner(), SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString)));
    runner()->start();
}

void AbstractRemoteLinuxDebugSupport::handleSshError(const QString &error)
{
    if (m_d->state == Debugging) {
        showMessage(error, AppError);
        if (m_d->engine)
            m_d->engine->notifyInferiorIll();
    } else if (m_d->state != Inactive) {
        handleAdapterSetupFailed(error);
    }
}

void AbstractRemoteLinuxDebugSupport::startExecution()
{
    if (m_d->state == Inactive)
        return;

    QTC_ASSERT(m_d->state == StartingRunner, return);

    if (m_d->debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) {
        if (!setPort(m_d->gdbServerPort))
            return;
    }
    if (m_d->debuggingType != RemoteLinuxRunConfiguration::DebugCppOnly) {
        if (!setPort(m_d->qmlPort))
            return;
    }

    m_d->state = StartingRemoteProcess;
    m_d->gdbserverOutput.clear();
    connect(runner(), SIGNAL(remoteErrorOutput(QByteArray)), this,
        SLOT(handleRemoteErrorOutput(QByteArray)));
    connect(runner(), SIGNAL(remoteOutput(QByteArray)), this,
        SLOT(handleRemoteOutput(QByteArray)));
    if (m_d->debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly) {
        connect(runner(), SIGNAL(remoteProcessStarted()),
            SLOT(handleRemoteProcessStarted()));
    }
    const QString &remoteExe = runner()->remoteExecutable();
    QString args = runner()->arguments();
    if (m_d->debuggingType != RemoteLinuxRunConfiguration::DebugCppOnly) {
        args += QString(QLatin1String(" -qmljsdebugger=port:%1,block"))
            .arg(m_d->qmlPort);
    }

    const QString remoteCommandLine = m_d->debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly
        ? QString::fromLocal8Bit("%1 %2 %3").arg(runner()->commandPrefix()).arg(remoteExe).arg(args)
        : QString::fromLocal8Bit("%1 gdbserver :%2 %3 %4").arg(runner()->commandPrefix())
              .arg(m_d->gdbServerPort).arg(remoteExe).arg(args);
    connect(runner(), SIGNAL(remoteProcessFinished(qint64)),
        SLOT(handleRemoteProcessFinished(qint64)));
    runner()->startExecution(remoteCommandLine.toUtf8());
}

void AbstractRemoteLinuxDebugSupport::handleRemoteProcessFinished(qint64 exitCode)
{
    if (!m_d->engine || m_d->state == Inactive)
        return;

    if (m_d->state == Debugging) {
        // The QML engine does not realize on its own that the application has finished.
        if (m_d->debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly)
            m_d->engine->quitDebugger();
        else if (exitCode != 0)
            m_d->engine->notifyInferiorIll();

    } else {
        const QString errorMsg = m_d->debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly
            ? tr("Remote application failed with exit code %1.").arg(exitCode)
            : tr("The gdbserver process closed unexpectedly.");
        m_d->engine->handleRemoteSetupFailed(errorMsg);
    }
}

void AbstractRemoteLinuxDebugSupport::handleDebuggingFinished()
{
    setFinished();
}

void AbstractRemoteLinuxDebugSupport::handleRemoteOutput(const QByteArray &output)
{
    QTC_ASSERT(m_d->state == Inactive || m_d->state == Debugging, return);

    showMessage(QString::fromUtf8(output), AppOutput);
}

void AbstractRemoteLinuxDebugSupport::handleRemoteErrorOutput(const QByteArray &output)
{
    QTC_ASSERT(m_d->state == Inactive || m_d->state == StartingRemoteProcess || m_d->state == Debugging,
        return);

    if (!m_d->engine)
        return;

    showMessage(QString::fromUtf8(output), AppOutput);
    if (m_d->state == StartingRemoteProcess
            && m_d->debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) {
        m_d->gdbserverOutput += output;
        if (m_d->gdbserverOutput.contains("Listening on port")) {
            handleAdapterSetupDone();
            m_d->gdbserverOutput.clear();
        }
    }
}

void AbstractRemoteLinuxDebugSupport::handleProgressReport(const QString &progressOutput)
{
    showMessage(progressOutput + QLatin1Char('\n'), AppStuff);
}

void AbstractRemoteLinuxDebugSupport::handleAdapterSetupFailed(const QString &error)
{
    setFinished();
    m_d->engine->handleRemoteSetupFailed(tr("Initial setup failed: %1").arg(error));
}

void AbstractRemoteLinuxDebugSupport::handleAdapterSetupDone()
{
    m_d->state = Debugging;
    m_d->engine->handleRemoteSetupDone(m_d->gdbServerPort, m_d->qmlPort);
}

void AbstractRemoteLinuxDebugSupport::handleRemoteProcessStarted()
{
    Q_ASSERT(m_d->debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly);
    QTC_ASSERT(m_d->state == StartingRemoteProcess, return);

    handleAdapterSetupDone();
}

void AbstractRemoteLinuxDebugSupport::setFinished()
{
    if (m_d->state == Inactive)
        return;
    m_d->state = Inactive;
    runner()->stop();
}

bool AbstractRemoteLinuxDebugSupport::setPort(int &port)
{
    port = runner()->usedPortsGatherer()->getNextFreePort(runner()->freePorts());
    if (port == -1) {
        handleAdapterSetupFailed(tr("Not enough free ports on device for debugging."));
        return false;
    }
    return true;
}

RemoteLinuxDebugSupport::RemoteLinuxDebugSupport(RemoteLinuxRunConfiguration *runConfig,
        DebuggerEngine *engine)
    : AbstractRemoteLinuxDebugSupport(runConfig, engine),
      m_d(new RemoteLinuxDebugSupportPrivate(runConfig))
{
}

RemoteLinuxDebugSupport::~RemoteLinuxDebugSupport()
{
    delete m_d;
}

AbstractRemoteLinuxApplicationRunner *RemoteLinuxDebugSupport::runner() const
{
    return &m_d->runner;
}

} // namespace RemoteLinux
<commit_msg>RemoteLinux: Remove unused class member.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (info@qt.nokia.com)
**
** GNU Lesser General Public License Usage
**
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this file.
** Please review the following information to ensure the GNU Lesser General
** Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
** If you have questions regarding the use of this file, please contact
** Nokia at info@qt.nokia.com.
**
**************************************************************************/
#include "remotelinuxdebugsupport.h"

#include "linuxdeviceconfiguration.h"
#include "remotelinuxapplicationrunner.h"
#include "remotelinuxrunconfiguration.h"
#include "remotelinuxusedportsgatherer.h"

#include <debugger/debuggerengine.h>
#include <debugger/debuggerstartparameters.h>
#include <projectexplorer/abi.h>
#include <projectexplorer/project.h>
#include <projectexplorer/target.h>
#include <projectexplorer/toolchain.h>
#include <qt4projectmanager/qt4buildconfiguration.h>
#include <utils/qtcassert.h>

#include <QtCore/QPointer>
#include <QtCore/QSharedPointer>

using namespace Utils;
using namespace Debugger;
using namespace ProjectExplorer;

namespace RemoteLinux {
namespace Internal {
namespace {
enum State { Inactive, StartingRunner, StartingRemoteProcess, Debugging };
} // anonymous namespace

class AbstractRemoteLinuxDebugSupportPrivate
{
public:
    AbstractRemoteLinuxDebugSupportPrivate(RemoteLinuxRunConfiguration *runConfig,
            DebuggerEngine *engine)
        : engine(engine), deviceConfig(runConfig->deviceConfig()),
          debuggingType(runConfig->debuggingType()), state(Inactive),
          gdbServerPort(-1), qmlPort(-1)
    {
    }

    const QPointer<Debugger::DebuggerEngine> engine;
    const LinuxDeviceConfiguration::ConstPtr deviceConfig;
    const RemoteLinuxRunConfiguration::DebuggingType debuggingType;

    QByteArray gdbserverOutput;
    State state;
    int gdbServerPort;
    int qmlPort;
};

class RemoteLinuxDebugSupportPrivate
{
public:
    RemoteLinuxDebugSupportPrivate(RemoteLinuxRunConfiguration *runConfig) : runner(runConfig) {}

    GenericRemoteLinuxApplicationRunner runner;
};

} // namespace Internal

using namespace Internal;

DebuggerStartParameters AbstractRemoteLinuxDebugSupport::startParameters(const RemoteLinuxRunConfiguration *runConfig)
{
    DebuggerStartParameters params;
    const LinuxDeviceConfiguration::ConstPtr &devConf = runConfig->deviceConfig();
    const RemoteLinuxRunConfiguration::DebuggingType debuggingType
        = runConfig->debuggingType();
    if (debuggingType != RemoteLinuxRunConfiguration::DebugCppOnly) {
        params.qmlServerAddress = runConfig->deviceConfig()->sshParameters().host;
        params.qmlServerPort = -1;
    }
    if (debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) {
        params.processArgs = runConfig->arguments();
        if (runConfig->activeQt4BuildConfiguration()->qtVersion())
            params.sysroot = runConfig->activeQt4BuildConfiguration()->qtVersion()->systemRoot();
        params.toolChainAbi = runConfig->abi();
        params.startMode = AttachToRemote;
        params.executable = runConfig->localExecutableFilePath();
        params.debuggerCommand = runConfig->gdbCmd();
        params.remoteChannel = devConf->sshParameters().host + QLatin1String(":-1");
        params.useServerStartScript = true;

        // TODO: This functionality should be inside the debugger.
        const ProjectExplorer::Abi &abi = runConfig->target()
            ->activeBuildConfiguration()->toolChain()->targetAbi();
        params.remoteArchitecture = abi.toString();
        params.gnuTarget = QLatin1String(abi.architecture() == ProjectExplorer::Abi::ArmArchitecture
            ? "arm-none-linux-gnueabi": "i386-unknown-linux-gnu");
    } else {
        params.startMode = AttachToRemote;
    }
    params.displayName = runConfig->displayName();

    if (const ProjectExplorer::Project *project = runConfig->target()->project()) {
        params.projectSourceDirectory = project->projectDirectory();
        if (const ProjectExplorer::BuildConfiguration *buildConfig = runConfig->target()->activeBuildConfiguration()) {
            params.projectBuildDirectory = buildConfig->buildDirectory();
        }
        params.projectSourceFiles = project->files(Project::ExcludeGeneratedFiles);
    }

    return params;
}

AbstractRemoteLinuxDebugSupport::AbstractRemoteLinuxDebugSupport(RemoteLinuxRunConfiguration *runConfig,
        DebuggerEngine *engine)
    : QObject(engine), m_d(new AbstractRemoteLinuxDebugSupportPrivate(runConfig, engine))
{
    connect(m_d->engine, SIGNAL(requestRemoteSetup()), this, SLOT(handleAdapterSetupRequested()));
}

AbstractRemoteLinuxDebugSupport::~AbstractRemoteLinuxDebugSupport()
{
    setFinished();
    delete m_d;
}

void AbstractRemoteLinuxDebugSupport::showMessage(const QString &msg, int channel)
{
    if (m_d->engine)
        m_d->engine->showMessage(msg, channel);
}

void AbstractRemoteLinuxDebugSupport::handleAdapterSetupRequested()
{
    QTC_ASSERT(m_d->state == Inactive, return);

    m_d->state = StartingRunner;
    showMessage(tr("Preparing remote side ...\n"), AppStuff);
    disconnect(runner(), 0, this, 0);
    connect(runner(), SIGNAL(error(QString)), this, SLOT(handleSshError(QString)));
    connect(runner(), SIGNAL(readyForExecution()), this, SLOT(startExecution()));
    connect(runner(), SIGNAL(reportProgress(QString)), this, SLOT(handleProgressReport(QString)));
    runner()->start();
}

void AbstractRemoteLinuxDebugSupport::handleSshError(const QString &error)
{
    if (m_d->state == Debugging) {
        showMessage(error, AppError);
        if (m_d->engine)
            m_d->engine->notifyInferiorIll();
    } else if (m_d->state != Inactive) {
        handleAdapterSetupFailed(error);
    }
}

void AbstractRemoteLinuxDebugSupport::startExecution()
{
    if (m_d->state == Inactive)
        return;

    QTC_ASSERT(m_d->state == StartingRunner, return);

    if (m_d->debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) {
        if (!setPort(m_d->gdbServerPort))
            return;
    }
    if (m_d->debuggingType != RemoteLinuxRunConfiguration::DebugCppOnly) {
        if (!setPort(m_d->qmlPort))
            return;
    }

    m_d->state = StartingRemoteProcess;
    m_d->gdbserverOutput.clear();
    connect(runner(), SIGNAL(remoteErrorOutput(QByteArray)), this,
        SLOT(handleRemoteErrorOutput(QByteArray)));
    connect(runner(), SIGNAL(remoteOutput(QByteArray)), this,
        SLOT(handleRemoteOutput(QByteArray)));
    if (m_d->debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly) {
        connect(runner(), SIGNAL(remoteProcessStarted()),
            SLOT(handleRemoteProcessStarted()));
    }
    const QString &remoteExe = runner()->remoteExecutable();
    QString args = runner()->arguments();
    if (m_d->debuggingType != RemoteLinuxRunConfiguration::DebugCppOnly) {
        args += QString(QLatin1String(" -qmljsdebugger=port:%1,block"))
            .arg(m_d->qmlPort);
    }

    const QString remoteCommandLine = m_d->debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly
        ? QString::fromLocal8Bit("%1 %2 %3").arg(runner()->commandPrefix()).arg(remoteExe).arg(args)
        : QString::fromLocal8Bit("%1 gdbserver :%2 %3 %4").arg(runner()->commandPrefix())
              .arg(m_d->gdbServerPort).arg(remoteExe).arg(args);
    connect(runner(), SIGNAL(remoteProcessFinished(qint64)),
        SLOT(handleRemoteProcessFinished(qint64)));
    runner()->startExecution(remoteCommandLine.toUtf8());
}

void AbstractRemoteLinuxDebugSupport::handleRemoteProcessFinished(qint64 exitCode)
{
    if (!m_d->engine || m_d->state == Inactive)
        return;

    if (m_d->state == Debugging) {
        // The QML engine does not realize on its own that the application has finished.
        if (m_d->debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly)
            m_d->engine->quitDebugger();
        else if (exitCode != 0)
            m_d->engine->notifyInferiorIll();

    } else {
        const QString errorMsg = m_d->debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly
            ? tr("Remote application failed with exit code %1.").arg(exitCode)
            : tr("The gdbserver process closed unexpectedly.");
        m_d->engine->handleRemoteSetupFailed(errorMsg);
    }
}

void AbstractRemoteLinuxDebugSupport::handleDebuggingFinished()
{
    setFinished();
}

void AbstractRemoteLinuxDebugSupport::handleRemoteOutput(const QByteArray &output)
{
    QTC_ASSERT(m_d->state == Inactive || m_d->state == Debugging, return);

    showMessage(QString::fromUtf8(output), AppOutput);
}

void AbstractRemoteLinuxDebugSupport::handleRemoteErrorOutput(const QByteArray &output)
{
    QTC_ASSERT(m_d->state == Inactive || m_d->state == StartingRemoteProcess || m_d->state == Debugging,
        return);

    if (!m_d->engine)
        return;

    showMessage(QString::fromUtf8(output), AppOutput);
    if (m_d->state == StartingRemoteProcess
            && m_d->debuggingType != RemoteLinuxRunConfiguration::DebugQmlOnly) {
        m_d->gdbserverOutput += output;
        if (m_d->gdbserverOutput.contains("Listening on port")) {
            handleAdapterSetupDone();
            m_d->gdbserverOutput.clear();
        }
    }
}

void AbstractRemoteLinuxDebugSupport::handleProgressReport(const QString &progressOutput)
{
    showMessage(progressOutput + QLatin1Char('\n'), AppStuff);
}

void AbstractRemoteLinuxDebugSupport::handleAdapterSetupFailed(const QString &error)
{
    setFinished();
    m_d->engine->handleRemoteSetupFailed(tr("Initial setup failed: %1").arg(error));
}

void AbstractRemoteLinuxDebugSupport::handleAdapterSetupDone()
{
    m_d->state = Debugging;
    m_d->engine->handleRemoteSetupDone(m_d->gdbServerPort, m_d->qmlPort);
}

void AbstractRemoteLinuxDebugSupport::handleRemoteProcessStarted()
{
    Q_ASSERT(m_d->debuggingType == RemoteLinuxRunConfiguration::DebugQmlOnly);
    QTC_ASSERT(m_d->state == StartingRemoteProcess, return);

    handleAdapterSetupDone();
}

void AbstractRemoteLinuxDebugSupport::setFinished()
{
    if (m_d->state == Inactive)
        return;
    m_d->state = Inactive;
    runner()->stop();
}

bool AbstractRemoteLinuxDebugSupport::setPort(int &port)
{
    port = runner()->usedPortsGatherer()->getNextFreePort(runner()->freePorts());
    if (port == -1) {
        handleAdapterSetupFailed(tr("Not enough free ports on device for debugging."));
        return false;
    }
    return true;
}

RemoteLinuxDebugSupport::RemoteLinuxDebugSupport(RemoteLinuxRunConfiguration *runConfig,
        DebuggerEngine *engine)
    : AbstractRemoteLinuxDebugSupport(runConfig, engine),
      m_d(new RemoteLinuxDebugSupportPrivate(runConfig))
{
}

RemoteLinuxDebugSupport::~RemoteLinuxDebugSupport()
{
    delete m_d;
}

AbstractRemoteLinuxApplicationRunner *RemoteLinuxDebugSupport::runner() const
{
    return &m_d->runner;
}

} // namespace RemoteLinux
<|endoftext|>


<commit_before>/*
 * Copyright 2011 Sven Verdoolaege. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *    1. Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *
 *    2. Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY SVEN VERDOOLAEGE ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SVEN VERDOOLAEGE OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation
 * are those of the authors and should not be interpreted as
 * representing official policies, either expressed or implied, of
 * Sven Verdoolaege.
 */

#include "isl_config.h"

#include <assert.h>
#include <iostream>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/Host.h>
#include <llvm/Support/ManagedStatic.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/ASTConsumer.h>
#include <clang/Basic/FileSystemOptions.h>
#include <clang/Basic/FileManager.h>
#include <clang/Basic/TargetOptions.h>
#include <clang/Basic/TargetInfo.h>
#include <clang/Basic/Version.h>
#include <clang/Driver/Compilation.h>
#include <clang/Driver/Driver.h>
#include <clang/Driver/Tool.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/CompilerInvocation.h>
#ifdef HAVE_BASIC_DIAGNOSTICOPTIONS_H
#include <clang/Basic/DiagnosticOptions.h>
#else
#include <clang/Frontend/DiagnosticOptions.h>
#endif
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Frontend/Utils.h>
#include <clang/Lex/HeaderSearch.h>
#include <clang/Lex/Preprocessor.h>
#include <clang/Parse/ParseAST.h>
#include <clang/Sema/Sema.h>

#include "extract_interface.h"
#include "python.h"

using namespace std;
using namespace clang;
using namespace clang::driver;

static llvm::cl::opt<string> InputFilename(llvm::cl::Positional,
			llvm::cl::Required, llvm::cl::desc("<input file>"));
static llvm::cl::list<string> Includes("I",
			llvm::cl::desc("Header search path"),
			llvm::cl::value_desc("path"), llvm::cl::Prefix);

static const char *ResourceDir =
	CLANG_PREFIX "/lib/clang/" CLANG_VERSION_STRING;

/* Does decl have an attribute of the following form?
 *
 *	__attribute__((annotate("name")))
 */
bool has_annotation(Decl *decl, const char *name)
{
	if (!decl->hasAttrs())
		return false;

	AttrVec attrs = decl->getAttrs();
	for (AttrVec::const_iterator i = attrs.begin() ; i != attrs.end(); ++i) {
		const AnnotateAttr *ann = dyn_cast<AnnotateAttr>(*i);
		if (!ann)
			continue;
		if (ann->getAnnotation().str() == name)
			return true;
	}

	return false;
}

/* Is decl marked as exported?
 */
static bool is_exported(Decl *decl)
{
	return has_annotation(decl, "isl_export");
}

/* Collect all types and functions that are annotated "isl_export"
 * in "types" and "function".
 *
 * We currently only consider single declarations.
 */
struct MyASTConsumer : public ASTConsumer {
	set<RecordDecl *> types;
	set<FunctionDecl *> functions;

	virtual HandleTopLevelDeclReturn HandleTopLevelDecl(DeclGroupRef D) {
		Decl *decl;

		if (!D.isSingleDecl())
			return HandleTopLevelDeclContinue;
		decl = D.getSingleDecl();
		if (!is_exported(decl))
			return HandleTopLevelDeclContinue;
		switch (decl->getKind()) {
		case Decl::Record:
			types.insert(cast<RecordDecl>(decl));
			break;
		case Decl::Function:
			functions.insert(cast<FunctionDecl>(decl));
			break;
		default:
			break;
		}
		return HandleTopLevelDeclContinue;
	}
};

#ifdef USE_ARRAYREF

#ifdef HAVE_CXXISPRODUCTION
static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
{
	return new Driver(binary, llvm::sys::getDefaultTargetTriple(),
			    "", false, false, Diags);
}
#elif defined(HAVE_ISPRODUCTION)
static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
{
	return new Driver(binary, llvm::sys::getDefaultTargetTriple(),
			    "", false, Diags);
}
#else
static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
{
	return new Driver(binary, llvm::sys::getDefaultTargetTriple(),
			    "", Diags);
}
#endif

/* Create a CompilerInvocation object that stores the command line
 * arguments constructed by the driver.
 * The arguments are mainly useful for setting up the system include
 * paths on newer clangs and on some platforms.
 */
static CompilerInvocation *construct_invocation(const char *filename,
	DiagnosticsEngine &Diags)
{
	const char *binary = CLANG_PREFIX"/bin/clang";
	const llvm::OwningPtr<Driver> driver(construct_driver(binary, Diags));
	std::vector<const char *> Argv;
	Argv.push_back(binary);
	Argv.push_back(filename);
	const llvm::OwningPtr<Compilation> compilation(
		driver->BuildCompilation(llvm::ArrayRef<const char *>(Argv)));
	JobList &Jobs = compilation->getJobs();

	Command *cmd = cast<Command>(*Jobs.begin());
	if (strcmp(cmd->getCreator().getName(), "clang"))
		return NULL;

	const ArgStringList *args = &cmd->getArguments();

	CompilerInvocation *invocation = new CompilerInvocation;
	CompilerInvocation::CreateFromArgs(*invocation, args->data() + 1,
						args->data() + args->size(),
						Diags);
	return invocation;
}

#else

static CompilerInvocation *construct_invocation(const char *filename,
	DiagnosticsEngine &Diags)
{
	return NULL;
}

#endif

#ifdef HAVE_BASIC_DIAGNOSTICOPTIONS_H

static TextDiagnosticPrinter *construct_printer(void)
{
	return new TextDiagnosticPrinter(llvm::errs(), new DiagnosticOptions());
}

#else

static TextDiagnosticPrinter *construct_printer(void)
{
	DiagnosticOptions DO;
	return new TextDiagnosticPrinter(llvm::errs(), DO);
}

#endif

#ifdef CREATETARGETINFO_TAKES_POINTER

static TargetInfo *create_target_info(CompilerInstance *Clang,
	DiagnosticsEngine &Diags)
{
	TargetOptions &TO = Clang->getTargetOpts();
	TO.Triple = llvm::sys::getDefaultTargetTriple();
	return TargetInfo::CreateTargetInfo(Diags, &TO);
}

#else

static TargetInfo *create_target_info(CompilerInstance *Clang,
	DiagnosticsEngine &Diags)
{
	TargetOptions &TO = Clang->getTargetOpts();
	TO.Triple = llvm::sys::getDefaultTargetTriple();
	return TargetInfo::CreateTargetInfo(Diags, TO);
}

#endif

#ifdef CREATEDIAGNOSTICS_TAKES_ARG

static void create_diagnostics(CompilerInstance *Clang)
{
	Clang->createDiagnostics(0, NULL, construct_printer());
}

#else

static void create_diagnostics(CompilerInstance *Clang)
{
	Clang->createDiagnostics(construct_printer());
}

#endif

#ifdef CREATEPREPROCESSOR_TAKES_TUKIND

static void create_preprocessor(CompilerInstance *Clang)
{
	Clang->createPreprocessor(TU_Complete);
}

#else

static void create_preprocessor(CompilerInstance *Clang)
{
	Clang->createPreprocessor();
}

#endif

#ifdef ADDPATH_TAKES_4_ARGUMENTS

void add_path(HeaderSearchOptions &HSO, string Path)
{
	HSO.AddPath(Path, frontend::Angled, false, false);
}

#else

void add_path(HeaderSearchOptions &HSO, string Path)
{
	HSO.AddPath(Path, frontend::Angled, true, false, false);
}

#endif

int main(int argc, char *argv[])
{
	llvm::cl::ParseCommandLineOptions(argc, argv);

	CompilerInstance *Clang = new CompilerInstance();
	create_diagnostics(Clang);
	DiagnosticsEngine &Diags = Clang->getDiagnostics();
	Diags.setSuppressSystemWarnings(true);
	CompilerInvocation *invocation =
		construct_invocation(InputFilename.c_str(), Diags);
	if (invocation)
		Clang->setInvocation(invocation);
	Clang->createFileManager();
	Clang->createSourceManager(Clang->getFileManager());
	TargetInfo *target = create_target_info(Clang, Diags);
	Clang->setTarget(target);
	CompilerInvocation::setLangDefaults(Clang->getLangOpts(), IK_C,
					    LangStandard::lang_unspecified);
	HeaderSearchOptions &HSO = Clang->getHeaderSearchOpts();
	LangOptions &LO = Clang->getLangOpts();
	PreprocessorOptions &PO = Clang->getPreprocessorOpts();
	HSO.ResourceDir = ResourceDir;

	for (int i = 0; i < Includes.size(); ++i)
		add_path(HSO, Includes[i]);

	PO.addMacroDef("__isl_give=__attribute__((annotate(\"isl_give\")))");
	PO.addMacroDef("__isl_keep=__attribute__((annotate(\"isl_keep\")))");
	PO.addMacroDef("__isl_take=__attribute__((annotate(\"isl_take\")))");
	PO.addMacroDef("__isl_export=__attribute__((annotate(\"isl_export\")))");
	PO.addMacroDef("__isl_constructor=__attribute__((annotate(\"isl_constructor\"))) __attribute__((annotate(\"isl_export\")))");
	PO.addMacroDef("__isl_subclass(super)=__attribute__((annotate(\"isl_subclass(\" #super \")\"))) __attribute__((annotate(\"isl_export\")))");

	create_preprocessor(Clang);
	Preprocessor &PP = Clang->getPreprocessor();

	PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), LO);

	const FileEntry *file = Clang->getFileManager().getFile(InputFilename);
	assert(file);
	Clang->getSourceManager().createMainFileID(file);

	Clang->createASTContext();
	MyASTConsumer consumer;
	Sema *sema = new Sema(PP, Clang->getASTContext(), consumer);

	Diags.getClient()->BeginSourceFile(LO, &PP);
	ParseAST(*sema);
	Diags.getClient()->EndSourceFile();

	generate_python(consumer.types, consumer.functions);

	delete sema;
	delete Clang;
	llvm::llvm_shutdown();

	return 0;
}
<commit_msg>interface/extract_interface.cc: explicitly include llvm/ADT/OwningPtr.h<commit_after>/*
 * Copyright 2011 Sven Verdoolaege. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *    1. Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *
 *    2. Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY SVEN VERDOOLAEGE ''AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SVEN VERDOOLAEGE OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation
 * are those of the authors and should not be interpreted as
 * representing official policies, either expressed or implied, of
 * Sven Verdoolaege.
 */

#include "isl_config.h"

#include <assert.h>
#include <iostream>
#include <llvm/ADT/OwningPtr.h>
#include <llvm/Support/raw_ostream.h>
#include <llvm/Support/CommandLine.h>
#include <llvm/Support/Host.h>
#include <llvm/Support/ManagedStatic.h>
#include <clang/AST/ASTContext.h>
#include <clang/AST/ASTConsumer.h>
#include <clang/Basic/FileSystemOptions.h>
#include <clang/Basic/FileManager.h>
#include <clang/Basic/TargetOptions.h>
#include <clang/Basic/TargetInfo.h>
#include <clang/Basic/Version.h>
#include <clang/Driver/Compilation.h>
#include <clang/Driver/Driver.h>
#include <clang/Driver/Tool.h>
#include <clang/Frontend/CompilerInstance.h>
#include <clang/Frontend/CompilerInvocation.h>
#ifdef HAVE_BASIC_DIAGNOSTICOPTIONS_H
#include <clang/Basic/DiagnosticOptions.h>
#else
#include <clang/Frontend/DiagnosticOptions.h>
#endif
#include <clang/Frontend/TextDiagnosticPrinter.h>
#include <clang/Frontend/Utils.h>
#include <clang/Lex/HeaderSearch.h>
#include <clang/Lex/Preprocessor.h>
#include <clang/Parse/ParseAST.h>
#include <clang/Sema/Sema.h>

#include "extract_interface.h"
#include "python.h"

using namespace std;
using namespace clang;
using namespace clang::driver;

static llvm::cl::opt<string> InputFilename(llvm::cl::Positional,
			llvm::cl::Required, llvm::cl::desc("<input file>"));
static llvm::cl::list<string> Includes("I",
			llvm::cl::desc("Header search path"),
			llvm::cl::value_desc("path"), llvm::cl::Prefix);

static const char *ResourceDir =
	CLANG_PREFIX "/lib/clang/" CLANG_VERSION_STRING;

/* Does decl have an attribute of the following form?
 *
 *	__attribute__((annotate("name")))
 */
bool has_annotation(Decl *decl, const char *name)
{
	if (!decl->hasAttrs())
		return false;

	AttrVec attrs = decl->getAttrs();
	for (AttrVec::const_iterator i = attrs.begin() ; i != attrs.end(); ++i) {
		const AnnotateAttr *ann = dyn_cast<AnnotateAttr>(*i);
		if (!ann)
			continue;
		if (ann->getAnnotation().str() == name)
			return true;
	}

	return false;
}

/* Is decl marked as exported?
 */
static bool is_exported(Decl *decl)
{
	return has_annotation(decl, "isl_export");
}

/* Collect all types and functions that are annotated "isl_export"
 * in "types" and "function".
 *
 * We currently only consider single declarations.
 */
struct MyASTConsumer : public ASTConsumer {
	set<RecordDecl *> types;
	set<FunctionDecl *> functions;

	virtual HandleTopLevelDeclReturn HandleTopLevelDecl(DeclGroupRef D) {
		Decl *decl;

		if (!D.isSingleDecl())
			return HandleTopLevelDeclContinue;
		decl = D.getSingleDecl();
		if (!is_exported(decl))
			return HandleTopLevelDeclContinue;
		switch (decl->getKind()) {
		case Decl::Record:
			types.insert(cast<RecordDecl>(decl));
			break;
		case Decl::Function:
			functions.insert(cast<FunctionDecl>(decl));
			break;
		default:
			break;
		}
		return HandleTopLevelDeclContinue;
	}
};

#ifdef USE_ARRAYREF

#ifdef HAVE_CXXISPRODUCTION
static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
{
	return new Driver(binary, llvm::sys::getDefaultTargetTriple(),
			    "", false, false, Diags);
}
#elif defined(HAVE_ISPRODUCTION)
static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
{
	return new Driver(binary, llvm::sys::getDefaultTargetTriple(),
			    "", false, Diags);
}
#else
static Driver *construct_driver(const char *binary, DiagnosticsEngine &Diags)
{
	return new Driver(binary, llvm::sys::getDefaultTargetTriple(),
			    "", Diags);
}
#endif

/* Create a CompilerInvocation object that stores the command line
 * arguments constructed by the driver.
 * The arguments are mainly useful for setting up the system include
 * paths on newer clangs and on some platforms.
 */
static CompilerInvocation *construct_invocation(const char *filename,
	DiagnosticsEngine &Diags)
{
	const char *binary = CLANG_PREFIX"/bin/clang";
	const llvm::OwningPtr<Driver> driver(construct_driver(binary, Diags));
	std::vector<const char *> Argv;
	Argv.push_back(binary);
	Argv.push_back(filename);
	const llvm::OwningPtr<Compilation> compilation(
		driver->BuildCompilation(llvm::ArrayRef<const char *>(Argv)));
	JobList &Jobs = compilation->getJobs();

	Command *cmd = cast<Command>(*Jobs.begin());
	if (strcmp(cmd->getCreator().getName(), "clang"))
		return NULL;

	const ArgStringList *args = &cmd->getArguments();

	CompilerInvocation *invocation = new CompilerInvocation;
	CompilerInvocation::CreateFromArgs(*invocation, args->data() + 1,
						args->data() + args->size(),
						Diags);
	return invocation;
}

#else

static CompilerInvocation *construct_invocation(const char *filename,
	DiagnosticsEngine &Diags)
{
	return NULL;
}

#endif

#ifdef HAVE_BASIC_DIAGNOSTICOPTIONS_H

static TextDiagnosticPrinter *construct_printer(void)
{
	return new TextDiagnosticPrinter(llvm::errs(), new DiagnosticOptions());
}

#else

static TextDiagnosticPrinter *construct_printer(void)
{
	DiagnosticOptions DO;
	return new TextDiagnosticPrinter(llvm::errs(), DO);
}

#endif

#ifdef CREATETARGETINFO_TAKES_POINTER

static TargetInfo *create_target_info(CompilerInstance *Clang,
	DiagnosticsEngine &Diags)
{
	TargetOptions &TO = Clang->getTargetOpts();
	TO.Triple = llvm::sys::getDefaultTargetTriple();
	return TargetInfo::CreateTargetInfo(Diags, &TO);
}

#else

static TargetInfo *create_target_info(CompilerInstance *Clang,
	DiagnosticsEngine &Diags)
{
	TargetOptions &TO = Clang->getTargetOpts();
	TO.Triple = llvm::sys::getDefaultTargetTriple();
	return TargetInfo::CreateTargetInfo(Diags, TO);
}

#endif

#ifdef CREATEDIAGNOSTICS_TAKES_ARG

static void create_diagnostics(CompilerInstance *Clang)
{
	Clang->createDiagnostics(0, NULL, construct_printer());
}

#else

static void create_diagnostics(CompilerInstance *Clang)
{
	Clang->createDiagnostics(construct_printer());
}

#endif

#ifdef CREATEPREPROCESSOR_TAKES_TUKIND

static void create_preprocessor(CompilerInstance *Clang)
{
	Clang->createPreprocessor(TU_Complete);
}

#else

static void create_preprocessor(CompilerInstance *Clang)
{
	Clang->createPreprocessor();
}

#endif

#ifdef ADDPATH_TAKES_4_ARGUMENTS

void add_path(HeaderSearchOptions &HSO, string Path)
{
	HSO.AddPath(Path, frontend::Angled, false, false);
}

#else

void add_path(HeaderSearchOptions &HSO, string Path)
{
	HSO.AddPath(Path, frontend::Angled, true, false, false);
}

#endif

int main(int argc, char *argv[])
{
	llvm::cl::ParseCommandLineOptions(argc, argv);

	CompilerInstance *Clang = new CompilerInstance();
	create_diagnostics(Clang);
	DiagnosticsEngine &Diags = Clang->getDiagnostics();
	Diags.setSuppressSystemWarnings(true);
	CompilerInvocation *invocation =
		construct_invocation(InputFilename.c_str(), Diags);
	if (invocation)
		Clang->setInvocation(invocation);
	Clang->createFileManager();
	Clang->createSourceManager(Clang->getFileManager());
	TargetInfo *target = create_target_info(Clang, Diags);
	Clang->setTarget(target);
	CompilerInvocation::setLangDefaults(Clang->getLangOpts(), IK_C,
					    LangStandard::lang_unspecified);
	HeaderSearchOptions &HSO = Clang->getHeaderSearchOpts();
	LangOptions &LO = Clang->getLangOpts();
	PreprocessorOptions &PO = Clang->getPreprocessorOpts();
	HSO.ResourceDir = ResourceDir;

	for (int i = 0; i < Includes.size(); ++i)
		add_path(HSO, Includes[i]);

	PO.addMacroDef("__isl_give=__attribute__((annotate(\"isl_give\")))");
	PO.addMacroDef("__isl_keep=__attribute__((annotate(\"isl_keep\")))");
	PO.addMacroDef("__isl_take=__attribute__((annotate(\"isl_take\")))");
	PO.addMacroDef("__isl_export=__attribute__((annotate(\"isl_export\")))");
	PO.addMacroDef("__isl_constructor=__attribute__((annotate(\"isl_constructor\"))) __attribute__((annotate(\"isl_export\")))");
	PO.addMacroDef("__isl_subclass(super)=__attribute__((annotate(\"isl_subclass(\" #super \")\"))) __attribute__((annotate(\"isl_export\")))");

	create_preprocessor(Clang);
	Preprocessor &PP = Clang->getPreprocessor();

	PP.getBuiltinInfo().InitializeBuiltins(PP.getIdentifierTable(), LO);

	const FileEntry *file = Clang->getFileManager().getFile(InputFilename);
	assert(file);
	Clang->getSourceManager().createMainFileID(file);

	Clang->createASTContext();
	MyASTConsumer consumer;
	Sema *sema = new Sema(PP, Clang->getASTContext(), consumer);

	Diags.getClient()->BeginSourceFile(LO, &PP);
	ParseAST(*sema);
	Diags.getClient()->EndSourceFile();

	generate_python(consumer.types, consumer.functions);

	delete sema;
	delete Clang;
	llvm::llvm_shutdown();

	return 0;
}
<|endoftext|>


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

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "itkMeanImageFilter.h"
#include "itkDiscreteGaussianImageFilter.h"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "otbPerBandVectorImageFilter.h"

namespace otb
{
namespace Wrapper
{

enum
{
  Smoothing_Mean,
  Smoothing_Gaussian,
  Smoothing_Anisotropic
};

typedef otb::Image<FloatVectorImageType::InternalPixelType, 2>  ImageType;

class Smoothing : public Application
{
public:
  /** Standard class typedefs. */
  typedef Smoothing                      Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(Smoothing, otb::Application);

private:
  void DoInit()
  {
    SetName("Smoothing");
    SetDescription("Apply a smoothing filter to an image");

    SetDocName("Smoothing");
    SetDocLongDescription("This application applies smoothing filter to an image."
      " Either gaussian, mean, or anisotropic diffusion are available.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag(Tags::Filter);

    AddParameter(ParameterType_InputImage,  "in",   "Input Image");
    SetParameterDescription("in", "Input image to smooth.");
    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
    SetParameterDescription("out", "Output smoothed image.");

    AddRAMParameter();

    AddParameter(ParameterType_Choice,      "type", "Smoothing Type");
    SetParameterDescription("type", "Smoothing kernel to apply");

    AddChoice("type.mean",     "Mean");

    AddParameter(ParameterType_Radius, "type.mean.radius", "Radius");
    SetParameterDescription("type.mean.radius", "Mean radius (in pixels)");
    SetDefaultParameterInt("type.mean.radius", 2);

    AddChoice("type.gaussian", "Gaussian");

    AddParameter(ParameterType_Float, "type.gaussian.radius", "Radius");
    SetParameterDescription("type.gaussian.radius", "Gaussian radius (in pixels)");
    SetDefaultParameterFloat("type.gaussian.radius", 2.0);

    AddChoice("type.anidif",   "Anisotropic Diffusion");

    AddParameter(ParameterType_Float,  "type.anidif.timestep", "Time Step");
    SetParameterDescription("type.anidif.timestep", "Diffusion equation time step");

    AddParameter(ParameterType_Int,  "type.anidif.nbiter", "Nb Iterations");
    SetParameterDescription("type.anidif.nbiter", "Number of iterations");

    SetDefaultParameterFloat("type.anidif.timestep",   0.125);
    SetDefaultParameterInt("type.anidif.nbiter",     10);

    SetParameterString("type", "anidif");

    // Doc example parameter settings
    SetExampleComment("Image smoothing using a mean filter.", 0);
    SetDocExampleParameterValue("in", "Romania_Extract.tif");
    SetDocExampleParameterValue("out", "smoothedImage_mean.png uchar");
    SetDocExampleParameterValue("type", "mean");

    unsigned int exId = AddExample( "Image smoothing using an anisotropic diffusion filter." );
    SetDocExampleParameterValue("in", "Romania_Extract.tif", exId);
    SetDocExampleParameterValue("out", "smoothedImage_ani.png float", exId);
    SetDocExampleParameterValue("type", "anidif", exId);
    SetDocExampleParameterValue("type.anidif.timestep", "0.1", exId);
    SetDocExampleParameterValue("type.anidif.nbiter", "5", exId);
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {
    GetLogger()->Debug("Entering DoExecute\n");

    FloatVectorImageType::Pointer inImage = GetParameterImage("in");

    switch ( GetParameterInt("type") )
      {
      case Smoothing_Mean:
        {
        GetLogger()->Debug("Using mean");

        typedef itk::MeanImageFilter<ImageType, ImageType>         MeanFilterType;
        typedef otb::PerBandVectorImageFilter<FloatVectorImageType, FloatVectorImageType, MeanFilterType>
          PerBandMeanFilterType;

        PerBandMeanFilterType::Pointer perBand
          = PerBandMeanFilterType::New();
        perBand->SetInput(inImage);

        MeanFilterType::InputSizeType radius;
        radius.Fill( GetParameterInt("type.mean.radius") );
        perBand->GetFilter()->SetRadius(radius);
        perBand->UpdateOutputInformation();
        m_FilterRef = perBand;
        SetParameterOutputImage("out", perBand->GetOutput());
        }
        break;
      case Smoothing_Gaussian:
        {
        GetLogger()->Debug("Using gaussian");

        typedef itk::DiscreteGaussianImageFilter<ImageType, ImageType>  DiscreteGaussianFilterType;
        typedef otb::PerBandVectorImageFilter<FloatVectorImageType, FloatVectorImageType, DiscreteGaussianFilterType>
          PerBandDiscreteGaussianFilterType;

        PerBandDiscreteGaussianFilterType::Pointer perBand
          = PerBandDiscreteGaussianFilterType::New();
        perBand->SetInput(inImage);

        double radius = GetParameterFloat("type.gaussian.radius");
        double variance = radius * radius;
        perBand->GetFilter()->SetVariance(variance);
        perBand->GetFilter()->SetUseImageSpacing(false);
        perBand->UpdateOutputInformation();
        m_FilterRef = perBand;
        SetParameterOutputImage("out", perBand->GetOutput());
        }
        break;
      case Smoothing_Anisotropic:
        {
        GetLogger()->Debug("Using anisotropic diffusion");

        typedef itk::GradientAnisotropicDiffusionImageFilter<ImageType, ImageType>  GradientAnisotropicDiffusionFilterType;
        typedef otb::PerBandVectorImageFilter<FloatVectorImageType, FloatVectorImageType, GradientAnisotropicDiffusionFilterType>
          PerBandGradientAnisotropicDiffusionFilterType;

        PerBandGradientAnisotropicDiffusionFilterType::Pointer perBand
          = PerBandGradientAnisotropicDiffusionFilterType::New();
        perBand->SetInput(inImage);

        int aniDifNbIter = GetParameterInt("type.anidif.nbiter");
        perBand->GetFilter()->SetNumberOfIterations(static_cast<unsigned int>(aniDifNbIter));

        float aniDifTimeStep = GetParameterFloat("type.anidif.timestep");
        perBand->GetFilter()->SetTimeStep(static_cast<double>(aniDifTimeStep));
        // perBand->GetFilter()->SetConductanceParameter()
        perBand->UpdateOutputInformation();
        m_FilterRef = perBand;
        SetParameterOutputImage("out", perBand->GetOutput());
        }
        break;
      }
  }

  itk::LightObject::Pointer m_FilterRef;
};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::Smoothing)

<commit_msg>ENH: add conductance parameter for anidifusion which was added recently in ITK filter<commit_after>/*=========================================================================

 Program:   ORFEO Toolbox
 Language:  C++
 Date:      $Date$
 Version:   $Revision$

 Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
 See OTBCopyright.txt for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notices for more information.

 =========================================================================*/
#include "otbWrapperApplication.h"
#include "otbWrapperApplicationFactory.h"

#include "itkMeanImageFilter.h"
#include "itkDiscreteGaussianImageFilter.h"
#include "itkGradientAnisotropicDiffusionImageFilter.h"
#include "otbPerBandVectorImageFilter.h"

namespace otb
{
namespace Wrapper
{

enum
{
  Smoothing_Mean,
  Smoothing_Gaussian,
  Smoothing_Anisotropic
};

typedef otb::Image<FloatVectorImageType::InternalPixelType, 2>  ImageType;

class Smoothing : public Application
{
public:
  /** Standard class typedefs. */
  typedef Smoothing                      Self;
  typedef Application                   Superclass;
  typedef itk::SmartPointer<Self>       Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;

  /** Standard macro */
  itkNewMacro(Self);

  itkTypeMacro(Smoothing, otb::Application);

private:
  void DoInit()
  {
    SetName("Smoothing");
    SetDescription("Apply a smoothing filter to an image");

    SetDocName("Smoothing");
    SetDocLongDescription("This application applies smoothing filter to an image."
      " Either gaussian, mean, or anisotropic diffusion are available.");
    SetDocLimitations("None");
    SetDocAuthors("OTB-Team");
    SetDocSeeAlso(" ");

    AddDocTag(Tags::Filter);

    AddParameter(ParameterType_InputImage,  "in",   "Input Image");
    SetParameterDescription("in", "Input image to smooth.");
    AddParameter(ParameterType_OutputImage, "out",  "Output Image");
    SetParameterDescription("out", "Output smoothed image.");

    AddRAMParameter();

    AddParameter(ParameterType_Choice,      "type", "Smoothing Type");
    SetParameterDescription("type", "Smoothing kernel to apply");

    AddChoice("type.mean",     "Mean");

    AddParameter(ParameterType_Radius, "type.mean.radius", "Radius");
    SetParameterDescription("type.mean.radius", "Mean radius (in pixels)");
    SetDefaultParameterInt("type.mean.radius", 2);

    AddChoice("type.gaussian", "Gaussian");

    AddParameter(ParameterType_Float, "type.gaussian.radius", "Radius");
    SetParameterDescription("type.gaussian.radius", "Gaussian radius (in pixels)");
    SetDefaultParameterFloat("type.gaussian.radius", 2.0);

    AddChoice("type.anidif",   "Anisotropic Diffusion");

    AddParameter(ParameterType_Float,  "type.anidif.timestep", "Time Step");
    SetParameterDescription("type.anidif.timestep", "Diffusion equation time step");

    AddParameter(ParameterType_Int,  "type.anidif.nbiter", "Nb Iterations");
    SetParameterDescription("type.anidif.nbiter", "Number of iterations");

    AddParameter(ParameterType_Float,  "type.anidif.conductance", "Conductance");
    SetParameterDescription("type.anidif.nbiter", "Controls the sensitivity of the conductance term");

    SetDefaultParameterFloat("type.anidif.timestep",   0.125);
    SetDefaultParameterInt("type.anidif.nbiter",     10);
    SetDefaultParameterInt("type.anidif.conductance",     1.);

    SetParameterString("type", "anidif");

    // Doc example parameter settings
    SetExampleComment("Image smoothing using a mean filter.", 0);
    SetDocExampleParameterValue("in", "Romania_Extract.tif");
    SetDocExampleParameterValue("out", "smoothedImage_mean.png uchar");
    SetDocExampleParameterValue("type", "mean");

    unsigned int exId = AddExample( "Image smoothing using an anisotropic diffusion filter." );
    SetDocExampleParameterValue("in", "Romania_Extract.tif", exId);
    SetDocExampleParameterValue("out", "smoothedImage_ani.png float", exId);
    SetDocExampleParameterValue("type", "anidif", exId);
    SetDocExampleParameterValue("type.anidif.timestep", "0.1", exId);
    SetDocExampleParameterValue("type.anidif.nbiter", "5", exId);
    SetDocExampleParameterValue("type.anidif.conductance", "1.5", exId);
  }

  void DoUpdateParameters()
  {
    // Nothing to do here : all parameters are independent
  }

  void DoExecute()
  {
    GetLogger()->Debug("Entering DoExecute\n");

    FloatVectorImageType::Pointer inImage = GetParameterImage("in");

    switch ( GetParameterInt("type") )
      {
      case Smoothing_Mean:
        {
        GetLogger()->Debug("Using mean");

        typedef itk::MeanImageFilter<ImageType, ImageType>         MeanFilterType;
        typedef otb::PerBandVectorImageFilter<FloatVectorImageType, FloatVectorImageType, MeanFilterType>
          PerBandMeanFilterType;

        PerBandMeanFilterType::Pointer perBand
          = PerBandMeanFilterType::New();
        perBand->SetInput(inImage);

        MeanFilterType::InputSizeType radius;
        radius.Fill( GetParameterInt("type.mean.radius") );
        perBand->GetFilter()->SetRadius(radius);
        perBand->UpdateOutputInformation();
        m_FilterRef = perBand;
        SetParameterOutputImage("out", perBand->GetOutput());
        }
        break;
      case Smoothing_Gaussian:
        {
        GetLogger()->Debug("Using gaussian");

        typedef itk::DiscreteGaussianImageFilter<ImageType, ImageType>  DiscreteGaussianFilterType;
        typedef otb::PerBandVectorImageFilter<FloatVectorImageType, FloatVectorImageType, DiscreteGaussianFilterType>
          PerBandDiscreteGaussianFilterType;

        PerBandDiscreteGaussianFilterType::Pointer perBand
          = PerBandDiscreteGaussianFilterType::New();
        perBand->SetInput(inImage);

        double radius = GetParameterFloat("type.gaussian.radius");
        double variance = radius * radius;
        perBand->GetFilter()->SetVariance(variance);
        perBand->GetFilter()->SetUseImageSpacing(false);
        perBand->UpdateOutputInformation();
        m_FilterRef = perBand;
        SetParameterOutputImage("out", perBand->GetOutput());
        }
        break;
      case Smoothing_Anisotropic:
        {
        GetLogger()->Debug("Using anisotropic diffusion");

        typedef itk::GradientAnisotropicDiffusionImageFilter<ImageType, ImageType>  GradientAnisotropicDiffusionFilterType;
        typedef otb::PerBandVectorImageFilter<FloatVectorImageType, FloatVectorImageType, GradientAnisotropicDiffusionFilterType>
          PerBandGradientAnisotropicDiffusionFilterType;

        PerBandGradientAnisotropicDiffusionFilterType::Pointer perBand
          = PerBandGradientAnisotropicDiffusionFilterType::New();
        perBand->SetInput(inImage);

        const int aniDifNbIter = GetParameterInt("type.anidif.nbiter");
        perBand->GetFilter()->SetNumberOfIterations(static_cast<unsigned int>(aniDifNbIter));

        const float aniDifTimeStep = GetParameterFloat("type.anidif.timestep");
        perBand->GetFilter()->SetTimeStep(static_cast<double>(aniDifTimeStep));

        perBand->GetFilter()->SetConductanceParameter(GetParameterFloat("type.anidif.conductance"));
        perBand->UpdateOutputInformation();

        m_FilterRef = perBand;
        SetParameterOutputImage("out", perBand->GetOutput());
        }
        break;
      }
  }

  itk::LightObject::Pointer m_FilterRef;
};

}
}

OTB_APPLICATION_EXPORT(otb::Wrapper::Smoothing)

<|endoftext|>


<commit_before>//===----------------------------------------------------------------------===//
//
//                         PelotonDB
//
// pair_test.cpp
//
// Identification: tests/mfabric/pair_test.cpp
//
// Copyright (c) 2015, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <string.h>
#include <unistd.h>
#include <cstdio>
#include <cassert>

#include "gtest/gtest.h"
#include "harness.h"

#include "backend/mfabric/libnanomsg/src/nn.h"
#include "backend/mfabric/libnanomsg/src/pair.h"

namespace peloton {
namespace test {

//===--------------------------------------------------------------------===//
// Pair Tests
//===--------------------------------------------------------------------===//

#define NODE0 "node0"
#define NODE1 "node1"

int send_name(int sock, const char *name)
{
	printf ("%s: SENDING \"%s\"\n", name, name);
	int sz_n = strlen (name) + 1; // '\0' too
	return nn_send (sock, name, sz_n, 0);
}

int recv_name(int sock, const char *name)
{
	char *buf = NULL;
	int result = nn_recv (sock, &buf, NN_MSG, 0);
	if (result > 0)
	{
		printf ("%s: RECEIVED \"%s\"\n", name, buf);
		nn_freemsg (buf);
	}
	return result;
}

int send_recv(int sock, const char *name)
{
	int to = 100;
	assert (nn_setsockopt (sock, NN_SOL_SOCKET, NN_RCVTIMEO, &to, sizeof (to)) >= 0);
	while(1)
	{
		recv_name(sock, name);
		sleep(1);
		send_name(sock, name);
	}
}

int node0 (const char *url)
{
	int sock = nn_socket (AF_SP, NN_PAIR);
	assert (sock >= 0);
	assert (nn_bind (sock, url) >= 0);
	send_recv(sock, NODE0);
	return nn_shutdown (sock, 0);
}

int node1 (const char *url)
{
	int sock = nn_socket (AF_SP, NN_PAIR);
	assert (sock >= 0);
	assert (nn_connect (sock, url) >= 0);
	send_recv(sock, NODE1);
	return nn_shutdown (sock, 0);
}

TEST(PairTest, BasicTest) {

 node0(NODE0);
 node1(NODE1);

}

}  // End test namespace
}  // End peloton namespace

<commit_msg>Fixing pair test<commit_after>//===----------------------------------------------------------------------===//
//
//                         PelotonDB
//
// pair_test.cpp
//
// Identification: tests/mfabric/pair_test.cpp
//
// Copyright (c) 2015, Carnegie Mellon University Database Group
//
//===----------------------------------------------------------------------===//

#include <string.h>
#include <unistd.h>
#include <cstdio>
#include <cassert>

#include "gtest/gtest.h"
#include "harness.h"

#include "backend/mfabric/libnanomsg/src/nn.h"
#include "backend/mfabric/libnanomsg/src/pair.h"

namespace peloton {
namespace test {

//===--------------------------------------------------------------------===//
// Pair Tests
//===--------------------------------------------------------------------===//

#define NODE0 "node0"
#define NODE1 "node1"

int send_name(int sock, const char *name)
{
  printf("Send name \n");

  printf ("%s: SENDING \"%s\"\n", name, name);
  int sz_n = strlen (name) + 1; // '\0' too
  return nn_send (sock, name, sz_n, 0);
}

int recv_name(int sock, const char *name)
{
  printf("Recv name \n");

  char *buf = NULL;
  int result = nn_recv (sock, &buf, NN_MSG, 0);
  if (result > 0)
  {
    printf ("%s: RECEIVED \"%s\"\n", name, buf);
    nn_freemsg (buf);
  }
  return result;
}

int send_recv(int sock, const char *name)
{
  int to = 100;
  assert (nn_setsockopt (sock, NN_SOL_SOCKET, NN_RCVTIMEO, &to, sizeof (to)) >= 0);
  while(1)
  {
    printf("Send Recv \n");
    recv_name(sock, name);
    //sleep(1);
    send_name(sock, name);
  }
}

int node0 (const char *url)
{
  int sock = nn_socket (AF_SP, NN_PAIR);
  assert (sock >= 0);
  assert (nn_bind (sock, url) >= 0);
  send_recv(sock, NODE0);
  return nn_shutdown (sock, 0);
}

int node1 (const char *url)
{
  int sock = nn_socket (AF_SP, NN_PAIR);
  assert (sock >= 0);
  assert (nn_connect (sock, url) >= 0);
  send_recv(sock, NODE1);
  return nn_shutdown (sock, 0);
}

TEST(PairTest, BasicTest) {

  std::thread send(node0,"ipc:///tmp/pair.ipc");
  send.detach();
  std::thread recv(node1,"ipc:///tmp/pair.ipc");
  recv.detach();

  sleep(3);

}

}  // End test namespace
}  // End peloton namespace

<|endoftext|>


<commit_before>//===-- TargetData.cpp - Data size & alignment routines --------------------==//
//
// This file defines target properties related to datatype size/offset/alignment
// information.  It uses lazy annotations to cache information about how
// structure types are laid out and used.
//
// This structure should be created once, filled in if the defaults are not
// correct and then passed around by const&.  None of the members functions
// require modification to the object.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetData.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"

static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
			       uint64_t &Size, unsigned char &Alignment);

//===----------------------------------------------------------------------===//
// Support for StructLayout Annotation
//===----------------------------------------------------------------------===//

StructLayout::StructLayout(const StructType *ST, const TargetData &TD)
  : Annotation(TD.getStructLayoutAID()) {
  StructAlignment = 0;
  StructSize = 0;

  // Loop over each of the elements, placing them in memory...
  for (StructType::ElementTypes::const_iterator
	 TI = ST->getElementTypes().begin(),
	 TE = ST->getElementTypes().end(); TI != TE; ++TI) {
    const Type *Ty = *TI;
    unsigned char A;
    unsigned TyAlign;
    uint64_t TySize;
    getTypeInfo(Ty, &TD, TySize, A);
    TyAlign = A;

    // Add padding if neccesary to make the data element aligned properly...
    if (StructSize % TyAlign != 0)
      StructSize = (StructSize/TyAlign + 1) * TyAlign;   // Add padding...

    // Keep track of maximum alignment constraint
    StructAlignment = std::max(TyAlign, StructAlignment);

    MemberOffsets.push_back(StructSize);
    StructSize += TySize;                 // Consume space for this data item
  }

  // Add padding to the end of the struct so that it could be put in an array
  // and all array elements would be aligned correctly.
  if (StructSize % StructAlignment != 0)
    StructSize = (StructSize/StructAlignment + 1) * StructAlignment;

  if (StructSize == 0) {
    StructSize = 1;           // Empty struct is 1 byte
    StructAlignment = 1;
  }
}

Annotation *TargetData::TypeAnFactory(AnnotationID AID, const Annotable *T,
				      void *D) {
  const TargetData &TD = *(const TargetData*)D;
  assert(AID == TD.AID && "Target data annotation ID mismatch!");
  const Type *Ty = cast<const Type>((const Value *)T);
  assert(isa<StructType>(Ty) &&
	 "Can only create StructLayout annotation on structs!");
  return new StructLayout((const StructType *)Ty, TD);
}

//===----------------------------------------------------------------------===//
//                       TargetData Class Implementation
//===----------------------------------------------------------------------===//

TargetData::TargetData(const std::string &TargetName,
             unsigned char IntRegSize, unsigned char PtrSize,
	     unsigned char PtrAl, unsigned char DoubleAl,
	     unsigned char FloatAl, unsigned char LongAl,
	     unsigned char IntAl, unsigned char ShortAl,
	     unsigned char ByteAl)
  : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
  AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);

  IntegerRegSize   = IntRegSize;
  PointerSize      = PtrSize;
  PointerAlignment = PtrAl;
  DoubleAlignment  = DoubleAl;
  FloatAlignment   = FloatAl;
  LongAlignment    = LongAl;
  IntAlignment     = IntAl;
  ShortAlignment   = ShortAl;
  ByteAlignment    = ByteAl;
}

TargetData::~TargetData() {
  AnnotationManager::registerAnnotationFactory(AID, 0);   // Deregister factory
}

static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
			       uint64_t &Size, unsigned char &Alignment) {
  assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
  switch (Ty->getPrimitiveID()) {
  case Type::VoidTyID:
  case Type::BoolTyID:
  case Type::UByteTyID:
  case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
  case Type::UShortTyID:
  case Type::ShortTyID:  Size = 2; Alignment = TD->getShortAlignment(); return;
  case Type::UIntTyID:
  case Type::IntTyID:    Size = 4; Alignment = TD->getIntAlignment(); return;
  case Type::ULongTyID:
  case Type::LongTyID:   Size = 8; Alignment = TD->getLongAlignment(); return;
  case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return;
  case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
  case Type::LabelTyID:
  case Type::PointerTyID:
    Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
    return;
  case Type::ArrayTyID: {
    const ArrayType *ATy = (const ArrayType *)Ty;
    getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
    Size *= ATy->getNumElements();
    return;
  }
  case Type::StructTyID: {
    // Get the layout annotation... which is lazily created on demand.
    const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
    Size = Layout->StructSize; Alignment = Layout->StructAlignment;
    return;
  }

  case Type::TypeTyID:
  default:
    assert(0 && "Bad type for getTypeInfo!!!");
    return;
  }
}

uint64_t TargetData::getTypeSize(const Type *Ty) const {
  uint64_t Size;
  unsigned char Align;
  getTypeInfo(Ty, this, Size, Align);
  return Size;
}

unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
  uint64_t Size;
  unsigned char Align;
  getTypeInfo(Ty, this, Size, Align);
  return Align;
}

uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
				      const std::vector<Value*> &Idx) const {
  const Type *Ty = ptrTy;
  assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
  uint64_t Result = 0;

  for (unsigned CurIDX = 0; CurIDX < Idx.size(); ++CurIDX) {
    if (Idx[CurIDX]->getType() == Type::UIntTy) {
      // Update Ty to refer to current element
      Ty = cast<SequentialType>(Ty)->getElementType();

      // Get the array index and the size of each array element.
      // Both must be known constants, or this will fail.
      // Also, the arrayIdx needs to be sign-extended from 32 bits to uint64_t
      // since uint is not normally sign-extended when cast to uint64_t.
      uint64_t elementSize = this->getTypeSize(Ty);
      uint64_t arrayIdx = cast<ConstantUInt>(Idx[CurIDX])->getValue();
      arrayIdx = (uint64_t) (int) arrayIdx; // sign-extend from 32 to 64 bits
      Result += arrayIdx * elementSize;

    } else if (const StructType *STy = dyn_cast<const StructType>(Ty)) {
      assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
      unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();

      // Get structure layout information...
      const StructLayout *Layout = getStructLayout(STy);

      // Add in the offset, as calculated by the structure layout info...
      assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
      Result += Layout->MemberOffsets[FieldNo];

      // Update Ty to refer to current element
      Ty = STy->getElementTypes()[FieldNo];

    } else if (isa<const ArrayType>(Ty)) {
      assert(0 && "Loading from arrays not implemented yet!");
    } else {
      assert(0 && "Indexing type that is not struct or array?");
      return 0;                         // Load directly through ptr
    }
  }

  return Result;
}
<commit_msg>Fix sign-extension: it needs to happen *after* multiplying by type size.<commit_after>//===-- TargetData.cpp - Data size & alignment routines --------------------==//
//
// This file defines target properties related to datatype size/offset/alignment
// information.  It uses lazy annotations to cache information about how
// structure types are laid out and used.
//
// This structure should be created once, filled in if the defaults are not
// correct and then passed around by const&.  None of the members functions
// require modification to the object.
//
//===----------------------------------------------------------------------===//

#include "llvm/Target/TargetData.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"

static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
			       uint64_t &Size, unsigned char &Alignment);

//===----------------------------------------------------------------------===//
// Support for StructLayout Annotation
//===----------------------------------------------------------------------===//

StructLayout::StructLayout(const StructType *ST, const TargetData &TD)
  : Annotation(TD.getStructLayoutAID()) {
  StructAlignment = 0;
  StructSize = 0;

  // Loop over each of the elements, placing them in memory...
  for (StructType::ElementTypes::const_iterator
	 TI = ST->getElementTypes().begin(),
	 TE = ST->getElementTypes().end(); TI != TE; ++TI) {
    const Type *Ty = *TI;
    unsigned char A;
    unsigned TyAlign;
    uint64_t TySize;
    getTypeInfo(Ty, &TD, TySize, A);
    TyAlign = A;

    // Add padding if neccesary to make the data element aligned properly...
    if (StructSize % TyAlign != 0)
      StructSize = (StructSize/TyAlign + 1) * TyAlign;   // Add padding...

    // Keep track of maximum alignment constraint
    StructAlignment = std::max(TyAlign, StructAlignment);

    MemberOffsets.push_back(StructSize);
    StructSize += TySize;                 // Consume space for this data item
  }

  // Add padding to the end of the struct so that it could be put in an array
  // and all array elements would be aligned correctly.
  if (StructSize % StructAlignment != 0)
    StructSize = (StructSize/StructAlignment + 1) * StructAlignment;

  if (StructSize == 0) {
    StructSize = 1;           // Empty struct is 1 byte
    StructAlignment = 1;
  }
}

Annotation *TargetData::TypeAnFactory(AnnotationID AID, const Annotable *T,
				      void *D) {
  const TargetData &TD = *(const TargetData*)D;
  assert(AID == TD.AID && "Target data annotation ID mismatch!");
  const Type *Ty = cast<const Type>((const Value *)T);
  assert(isa<StructType>(Ty) &&
	 "Can only create StructLayout annotation on structs!");
  return new StructLayout((const StructType *)Ty, TD);
}

//===----------------------------------------------------------------------===//
//                       TargetData Class Implementation
//===----------------------------------------------------------------------===//

TargetData::TargetData(const std::string &TargetName,
             unsigned char IntRegSize, unsigned char PtrSize,
	     unsigned char PtrAl, unsigned char DoubleAl,
	     unsigned char FloatAl, unsigned char LongAl,
	     unsigned char IntAl, unsigned char ShortAl,
	     unsigned char ByteAl)
  : AID(AnnotationManager::getID("TargetData::" + TargetName)) {
  AnnotationManager::registerAnnotationFactory(AID, TypeAnFactory, this);

  IntegerRegSize   = IntRegSize;
  PointerSize      = PtrSize;
  PointerAlignment = PtrAl;
  DoubleAlignment  = DoubleAl;
  FloatAlignment   = FloatAl;
  LongAlignment    = LongAl;
  IntAlignment     = IntAl;
  ShortAlignment   = ShortAl;
  ByteAlignment    = ByteAl;
}

TargetData::~TargetData() {
  AnnotationManager::registerAnnotationFactory(AID, 0);   // Deregister factory
}

static inline void getTypeInfo(const Type *Ty, const TargetData *TD,
			       uint64_t &Size, unsigned char &Alignment) {
  assert(Ty->isSized() && "Cannot getTypeInfo() on a type that is unsized!");
  switch (Ty->getPrimitiveID()) {
  case Type::VoidTyID:
  case Type::BoolTyID:
  case Type::UByteTyID:
  case Type::SByteTyID:  Size = 1; Alignment = TD->getByteAlignment(); return;
  case Type::UShortTyID:
  case Type::ShortTyID:  Size = 2; Alignment = TD->getShortAlignment(); return;
  case Type::UIntTyID:
  case Type::IntTyID:    Size = 4; Alignment = TD->getIntAlignment(); return;
  case Type::ULongTyID:
  case Type::LongTyID:   Size = 8; Alignment = TD->getLongAlignment(); return;
  case Type::FloatTyID:  Size = 4; Alignment = TD->getFloatAlignment(); return;
  case Type::DoubleTyID: Size = 8; Alignment = TD->getDoubleAlignment(); return;
  case Type::LabelTyID:
  case Type::PointerTyID:
    Size = TD->getPointerSize(); Alignment = TD->getPointerAlignment();
    return;
  case Type::ArrayTyID: {
    const ArrayType *ATy = (const ArrayType *)Ty;
    getTypeInfo(ATy->getElementType(), TD, Size, Alignment);
    Size *= ATy->getNumElements();
    return;
  }
  case Type::StructTyID: {
    // Get the layout annotation... which is lazily created on demand.
    const StructLayout *Layout = TD->getStructLayout((const StructType*)Ty);
    Size = Layout->StructSize; Alignment = Layout->StructAlignment;
    return;
  }

  case Type::TypeTyID:
  default:
    assert(0 && "Bad type for getTypeInfo!!!");
    return;
  }
}

uint64_t TargetData::getTypeSize(const Type *Ty) const {
  uint64_t Size;
  unsigned char Align;
  getTypeInfo(Ty, this, Size, Align);
  return Size;
}

unsigned char TargetData::getTypeAlignment(const Type *Ty) const {
  uint64_t Size;
  unsigned char Align;
  getTypeInfo(Ty, this, Size, Align);
  return Align;
}

uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
				      const std::vector<Value*> &Idx) const {
  const Type *Ty = ptrTy;
  assert(isa<PointerType>(Ty) && "Illegal argument for getIndexedOffset()");
  uint64_t Result = 0;

  for (unsigned CurIDX = 0; CurIDX < Idx.size(); ++CurIDX) {
    if (Idx[CurIDX]->getType() == Type::UIntTy) {
      // Update Ty to refer to current element
      Ty = cast<SequentialType>(Ty)->getElementType();

      // Get the array index and the size of each array element.
      // Both must be known constants, or this will fail.
      // Also, the product needs to be sign-extended from 32 to 64 bits.
      uint64_t elementSize = this->getTypeSize(Ty);
      uint64_t arrayIdx = cast<ConstantUInt>(Idx[CurIDX])->getValue();
      Result += (uint64_t) (int) (arrayIdx * elementSize); // sign-extend

    } else if (const StructType *STy = dyn_cast<const StructType>(Ty)) {
      assert(Idx[CurIDX]->getType() == Type::UByteTy && "Illegal struct idx");
      unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();

      // Get structure layout information...
      const StructLayout *Layout = getStructLayout(STy);

      // Add in the offset, as calculated by the structure layout info...
      assert(FieldNo < Layout->MemberOffsets.size() &&"FieldNo out of range!");
      Result += Layout->MemberOffsets[FieldNo];

      // Update Ty to refer to current element
      Ty = STy->getElementTypes()[FieldNo];

    } else if (isa<const ArrayType>(Ty)) {
      assert(0 && "Loading from arrays not implemented yet!");
    } else {
      assert(0 && "Indexing type that is not struct or array?");
      return 0;                         // Load directly through ptr
    }
  }

  return Result;
}
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------
//    $Id: integrate_difference.cc 24418 2011-09-26 12:52:19Z bangerth $
//    Version: $Name$
//
//    Copyright (C) 2009, 2010, 2011 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//---------------------------------------------------------------------------

// in Trilinos 10.12.1 interpolate() hangs with a small number of cells (smaller than the number of CPUs). This works fine in 10.4.2 and 10.8.5

#include "../tests.h"
#include "coarse_grid_common.h"
#include <deal.II/base/logstream.h>
#include <deal.II/base/function.h>
#include <deal.II/base/tensor.h>
#include <deal.II/lac/trilinos_vector.h>
#include <deal.II/grid/tria.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/distributed/tria.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/grid_out.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/dofs/dof_tools.h>
#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/dofs/dof_accessor.h>

#include <deal.II/fe/fe_q.h>
#include <deal.II/numerics/vectors.h>

#include <fstream>

template <int dim>
class LinearFunction : public Function<dim>
{
  public:
    double value (const Point<dim> &p,
		  const unsigned int) const
      {
	return 1;
      }
};

template<int dim>
void test()
{
  parallel::distributed::Triangulation<dim> tr(MPI_COMM_WORLD);

  GridGenerator::hyper_cube(tr);

//tr.refine_global (2);

  const FE_Q<dim> fe(2);
  DoFHandler<dim> dofh(tr);
  dofh.distribute_dofs (fe);

  TrilinosWrappers::MPI::Vector interpolated(dofh.locally_owned_dofs(),
					     MPI_COMM_WORLD);
  deallog << "before" << std::endl;
  VectorTools::interpolate (dofh,
			    LinearFunction<dim>(),
			    interpolated);
  deallog << "after" << std::endl;
  interpolated.compress();

  double norm = interpolated.l2_norm();
  if (Utilities::MPI::this_mpi_process (MPI_COMM_WORLD) == 0)
    deallog << "norm = " << norm
	    << std::endl;
}

int main(int argc, char *argv[])
{
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
  MPI_Init (&argc,&argv);
#else
  (void)argc;
  (void)argv;
#endif

  unsigned int myid = Utilities::MPI::this_mpi_process (MPI_COMM_WORLD);

  deallog.push(Utilities::int_to_string(myid));

  if (myid == 0)
    {
      std::ofstream logfile(output_file_for_mpi("interpolate_03").c_str());
      deallog.attach(logfile);
      deallog.depth_console(0);
      deallog.threshold_double(1.e-10);

      deallog.push("2d");
      test<2>();
      deallog.pop();

      deallog.push("3d");
				       //    test<3>();
      deallog.pop();
    }
  else
    {
      deallog.push("2d");
      test<2>();
      deallog.pop();

      deallog.push("3d");
//      test<3>();
      deallog.pop();
    }

#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
  MPI_Finalize();
#endif
}
<commit_msg>document test better<commit_after>//---------------------------------------------------------------------------
//    $Id: integrate_difference.cc 24418 2011-09-26 12:52:19Z bangerth $
//    Version: $Name$
//
//    Copyright (C) 2009, 2010, 2011 by the deal.II authors
//
//    This file is subject to QPL and may not be  distributed
//    without copyright and license information. Please refer
//    to the file deal.II/doc/license.html for the  text  and
//    further information on this license.
//
//---------------------------------------------------------------------------

// In Trilinos 10.12.1 interpolate() hangs with a small number of cells (smaller than the number of CPUs). This works fine in 10.4.2 and 10.8.5
// As it turns out, this is because vector creation after interpolate()
// reacts differently in 10.12.1 and causes a hang. The bug is
// that interpolate() does not call compress()!

#include "../tests.h"
#include "coarse_grid_common.h"
#include <deal.II/base/logstream.h>
#include <deal.II/base/function.h>
#include <deal.II/base/tensor.h>
#include <deal.II/lac/trilinos_vector.h>
#include <deal.II/grid/tria.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/distributed/tria.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/grid_out.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/dofs/dof_tools.h>
#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/dofs/dof_accessor.h>

#include <deal.II/fe/fe_q.h>
#include <deal.II/numerics/vectors.h>

#include <fstream>

template <int dim>
class LinearFunction : public Function<dim>
{
  public:
    double value (const Point<dim> &p,
		  const unsigned int) const
      {
	return 1;
      }
};

template<int dim>
void test()
{
  parallel::distributed::Triangulation<dim> tr(MPI_COMM_WORLD);

  GridGenerator::hyper_cube(tr);

//tr.refine_global (2);

  const FE_Q<dim> fe(2);
  DoFHandler<dim> dofh(tr);
  dofh.distribute_dofs (fe);

  TrilinosWrappers::MPI::Vector interpolated(dofh.locally_owned_dofs(),
					     MPI_COMM_WORLD);
  deallog << "before" << std::endl;
  VectorTools::interpolate (dofh,
			    LinearFunction<dim>(),
			    interpolated);
  deallog << "after" << std::endl;
  interpolated.compress();

  double norm = interpolated.l2_norm();
  if (Utilities::MPI::this_mpi_process (MPI_COMM_WORLD) == 0)
    deallog << "norm = " << norm
	    << std::endl;
}

int main(int argc, char *argv[])
{
#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
  MPI_Init (&argc,&argv);
#else
  (void)argc;
  (void)argv;
#endif

  unsigned int myid = Utilities::MPI::this_mpi_process (MPI_COMM_WORLD);

  deallog.push(Utilities::int_to_string(myid));

  if (myid == 0)
    {
      std::ofstream logfile(output_file_for_mpi("interpolate_03").c_str());
      deallog.attach(logfile);
      deallog.depth_console(0);
      deallog.threshold_double(1.e-10);

      deallog.push("2d");
      test<2>();
      deallog.pop();

      deallog.push("3d");
				       //    test<3>();
      deallog.pop();
    }
  else
    {
      deallog.push("2d");
      test<2>();
      deallog.pop();

      deallog.push("3d");
//      test<3>();
      deallog.pop();
    }

#ifdef DEAL_II_COMPILER_SUPPORTS_MPI
  MPI_Finalize();
#endif
}
<|endoftext|>