<commit_before>#ifndef LIBPORT_LOCKABLE_HXX
# define LIBPORT_LOCKABLE_HXX

#include <libport/assert.hh>

/*--------------------------.
| Implementation: Windows.  |
`--------------------------*/

# if defined WIN32

namespace libport
{
  inline void initLock(Lock& l)
  {
    l = CreateMutex(0, false, 0);
    if (!l)
      errabort("CreateMutex");
  }

  inline void lockLock(Lock& l)
  {
    if (WaitForSingleObject(l, INFINITE) ==  WAIT_FAILED)
      errabort("WaitForSingleObject");
  }

  inline void lockUnlock(Lock& l)
  {
    if (!ReleaseMutex(l))
      errabort("ReleaseMutex");
  }

  inline void deleteLock(Lock& l)
  {
    CloseHandle(l);
  }

  inline bool lockTryLock(Lock& l)
  {
    DWORD ret = WaitForSingleObject(l, 0);
    if (ret == WAIT_FAILED)
      errabort("WaitForSingleObject");
    return ret != WAIT_TIMEOUT;
  }
} // namespace libport

/*---------------------------.
| Implementation: pthreads.  |
`---------------------------*/

# else

namespace libport
{

  inline void initLock(Lock& l)
  {
    pthread_mutexattr_t ma;
    pthread_mutexattr_init(&ma);
    /* See
     * http://www.nabble.com/Compiling-on-MacOS-10.4-Tiger-t284385.html
     * for more about this code.  Yes, the second #if is very
     * suspicious, I don't know why it's like this.  */
#  if defined  __APPLE__ || defined __FreeBSD__
    pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE);
#  elif defined PTHREAD_MUTEX_RECURSIVE_NP
    // cygwin
    pthread_mutexattr_setkind_np(&ma, PTHREAD_MUTEX_RECURSIVE);
#  else
    // deprecated according to man page and fails to compile
    // pthread_mutexattr_setkind_np(&ma, PTHREAD_MUTEX_RECURSIVE_NP);
    pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE_NP);
#  endif
    pthread_mutex_init(&l, &ma);
  }

  inline void lockLock(Lock& l)
  {
    pthread_mutex_lock(&l);
  }

  inline void lockUnlock(Lock& l)
  {
    pthread_mutex_unlock(&l);
  }

  inline void deleteLock(Lock& l)
  {
    pthread_mutex_destroy(&l);
  }

  inline bool lockTryLock(Lock& l)
  {
    return !pthread_mutex_trylock(&l);
  }

} // namespace libport
# endif

namespace libport
{

  /*-----------.
  | Lockable.  |
  `-----------*/
  inline
  Lockable::Lockable()
  {
    initLock(lock_);
  }

  inline
  Lockable::~Lockable()
  {
    deleteLock(lock_);
  }

  inline
  void Lockable::lock()
  {
    lockLock(lock_);
  }

  inline
  void Lockable::unlock()
  {
    lockUnlock(lock_);
  }

  inline
  bool Lockable::tryLock()
  {
    return lockTryLock(lock_);
  }

  /*------------.
  | BlockLock.  |
  `------------*/

  inline
  BlockLock::BlockLock(Lockable& l)
    : lockable_(l)
  {
    lockable_.lock();
  }

  inline
  BlockLock::BlockLock(Lockable* l)
    : lockable_(*l)
  {
    //std::cerr <<"lock "<<l<<std::endl;
    lockable_.lock();
  }

  inline
  BlockLock::~BlockLock()
  {
    //std::cerr <<"unlock "<<&l<<std::endl;
    lockable_.unlock();
  }

} // namespace libport

#endif // !LIBPORT_LOCKABLE_HXX
<commit_msg>lockable: more assertions.<commit_after>#ifndef LIBPORT_LOCKABLE_HXX
# define LIBPORT_LOCKABLE_HXX

# include <libport/cerrno>
# include <libport/assert.hh>

/*--------------------------.
| Implementation: Windows.  |
`--------------------------*/

# if defined WIN32

namespace libport
{
  inline void initLock(Lock& l)
  {
    l = CreateMutex(0, false, 0);
    if (!l)
      errabort("CreateMutex");
  }

  inline void lockLock(Lock& l)
  {
    if (WaitForSingleObject(l, INFINITE) ==  WAIT_FAILED)
      errabort("WaitForSingleObject");
  }

  inline void lockUnlock(Lock& l)
  {
    if (!ReleaseMutex(l))
      errabort("ReleaseMutex");
  }

  inline void deleteLock(Lock& l)
  {
    CloseHandle(l);
  }

  inline bool lockTryLock(Lock& l)
  {
    DWORD ret = WaitForSingleObject(l, 0);
    if (ret == WAIT_FAILED)
      errabort("WaitForSingleObject");
    return ret != WAIT_TIMEOUT;
  }
} // namespace libport

/*---------------------------.
| Implementation: pthreads.  |
`---------------------------*/

# else

namespace libport
{

  inline void initLock(Lock& l)
  {
    pthread_mutexattr_t ma;
    if (pthread_mutexattr_init(&ma))
      errabort("pthread_mutexattr_init");
    /* See
     * http://www.nabble.com/Compiling-on-MacOS-10.4-Tiger-t284385.html
     * for more about this code.  Yes, the second #if is very
     * suspicious, I don't know why it's like this.  */
#  if defined  __APPLE__ || defined __FreeBSD__
    if (pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE))
      errabort("pthread_mutexattr_settype");
#  elif defined PTHREAD_MUTEX_RECURSIVE_NP
    // cygwin
    if (pthread_mutexattr_setkind_np(&ma, PTHREAD_MUTEX_RECURSIVE))
      errabort("pthread_mutexattr_setkind_np");
#  else
    // deprecated according to man page and fails to compile
    // pthread_mutexattr_setkind_np(&ma, PTHREAD_MUTEX_RECURSIVE_NP);
    if (pthread_mutexattr_settype(&ma, PTHREAD_MUTEX_RECURSIVE_NP))
      errabort("pthread_mutexattr_settype");
#  endif
    if (pthread_mutex_init(&l, &ma))
      errabort("pthread_mutex_init");
  }

  inline void lockLock(Lock& l)
  {
    if (pthread_mutex_lock(&l))
      errabort("pthread_mutex_lock");
  }

  inline void lockUnlock(Lock& l)
  {
    if (pthread_mutex_unlock(&l))
      errabort("pthread_mutex_unlock");
  }

  inline void deleteLock(Lock& l)
  {
    if (pthread_mutex_destroy(&l))
      errabort("pthread_mutex_destroy");
  }

  inline bool lockTryLock(Lock& l)
  {
    if (pthread_mutex_trylock(&l))
    {
      if (errno == EBUSY)
        return false;
      else
        errabort("pthread_mutex_trylock");
    }
    else
      return true;
  }

} // namespace libport
# endif

namespace libport
{

  /*-----------.
  | Lockable.  |
  `-----------*/
  inline
  Lockable::Lockable()
  {
    initLock(lock_);
  }

  inline
  Lockable::~Lockable()
  {
    deleteLock(lock_);
  }

  inline
  void Lockable::lock()
  {
    lockLock(lock_);
  }

  inline
  void Lockable::unlock()
  {
    lockUnlock(lock_);
  }

  inline
  bool Lockable::tryLock()
  {
    return lockTryLock(lock_);
  }

  /*------------.
  | BlockLock.  |
  `------------*/

  inline
  BlockLock::BlockLock(Lockable& l)
    : lockable_(l)
  {
    lockable_.lock();
  }

  inline
  BlockLock::BlockLock(Lockable* l)
    : lockable_(*l)
  {
    //std::cerr <<"lock "<<l<<std::endl;
    lockable_.lock();
  }

  inline
  BlockLock::~BlockLock()
  {
    //std::cerr <<"unlock "<<&l<<std::endl;
    lockable_.unlock();
  }

} // namespace libport

#endif // !LIBPORT_LOCKABLE_HXX
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2009, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */
#ifdef WIN32

int
mkdir(const char *path, mode_t)
{
  return _mkdir(path);
}

#endif
<commit_msg>Do not redefine mkdir under mingw, only under vcxx.<commit_after>/*
 * Copyright (C) 2009, Gostai S.A.S.
 *
 * This software is provided "as is" without warranty of any kind,
 * either expressed or implied, including but not limited to the
 * implied warranties of fitness for a particular purpose.
 *
 * See the LICENSE file for more information.
 */
#ifdef MSVC_VERSION

int
mkdir(const char *path, mode_t)
{
  return _mkdir(path);
}

#endif
<|endoftext|>


<commit_before>//===- FunctionResolution.cpp - Resolve declarations to implementations ---===//
//
// Loop over the functions that are in the module and look for functions that
// have the same name.  More often than not, there will be things like:
//
//    declare void %foo(...)
//    void %foo(int, int) { ... }
//
// because of the way things are declared in C.  If this is the case, patch
// things up.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO.h"
#include "llvm/Module.h"
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Pass.h"
#include "llvm/iOther.h"
#include "llvm/Constants.h"
#include "llvm/Assembly/Writer.h"  // FIXME: remove when varargs implemented
#include "Support/Statistic.h"
#include <algorithm>

namespace {
  Statistic<>NumResolved("funcresolve", "Number of varargs functions resolved");
  Statistic<> NumGlobals("funcresolve", "Number of global variables resolved");

  struct FunctionResolvingPass : public Pass {
    bool run(Module &M);
  };
  RegisterOpt<FunctionResolvingPass> X("funcresolve", "Resolve Functions");
}

Pass *createFunctionResolvingPass() {
  return new FunctionResolvingPass();
}

static bool ResolveFunctions(Module &M, std::vector<GlobalValue*> &Globals,
                             Function *Concrete) {
  bool Changed = false;
  for (unsigned i = 0; i != Globals.size(); ++i)
    if (Globals[i] != Concrete) {
      Function *Old = cast<Function>(Globals[i]);
      const FunctionType *OldMT = Old->getFunctionType();
      const FunctionType *ConcreteMT = Concrete->getFunctionType();

      if (OldMT->getParamTypes().size() > ConcreteMT->getParamTypes().size() &&
          !ConcreteMT->isVarArg())
        if (!Old->use_empty()) {
          std::cerr << "WARNING: Linking function '" << Old->getName()
                    << "' is causing arguments to be dropped.\n";
          std::cerr << "WARNING: Prototype: ";
          WriteAsOperand(std::cerr, Old);
          std::cerr << " resolved to ";
          WriteAsOperand(std::cerr, Concrete);
          std::cerr << "\n";
        }

      // Check to make sure that if there are specified types, that they
      // match...
      //
      unsigned NumArguments = std::min(OldMT->getParamTypes().size(),
                                       ConcreteMT->getParamTypes().size());

      if (!Old->use_empty() && !Concrete->use_empty())
        for (unsigned i = 0; i < NumArguments; ++i)
          if (OldMT->getParamTypes()[i] != ConcreteMT->getParamTypes()[i]) {
            std::cerr << "WARNING: Function [" << Old->getName()
                      << "]: Parameter types conflict for: '" << OldMT
                      << "' and '" << ConcreteMT << "'\n";
            return Changed;
          }

      // Attempt to convert all of the uses of the old function to the concrete
      // form of the function.  If there is a use of the fn that we don't
      // understand here we punt to avoid making a bad transformation.
      //
      // At this point, we know that the return values are the same for our two
      // functions and that the Old function has no varargs fns specified.  In
      // otherwords it's just <retty> (...)
      //
      Value *Replacement = Concrete;
      if (Concrete->getType() != Old->getType())
        Replacement = ConstantExpr::getCast(ConstantPointerRef::get(Concrete),
                                            Old->getType());
      NumResolved += Old->use_size();
      Old->replaceAllUsesWith(Replacement);

      // Since there are no uses of Old anymore, remove it from the module.
      M.getFunctionList().erase(Old);
    }
  return Changed;
}

static bool ResolveGlobalVariables(Module &M,
                                   std::vector<GlobalValue*> &Globals,
                                   GlobalVariable *Concrete) {
  bool Changed = false;
  assert(isa<ArrayType>(Concrete->getType()->getElementType()) &&
         "Concrete version should be an array type!");

  // Get the type of the things that may be resolved to us...
  const ArrayType *CATy =cast<ArrayType>(Concrete->getType()->getElementType());
  const Type *AETy = CATy->getElementType();

  Constant *CCPR = ConstantPointerRef::get(Concrete);

  for (unsigned i = 0; i != Globals.size(); ++i)
    if (Globals[i] != Concrete) {
      GlobalVariable *Old = cast<GlobalVariable>(Globals[i]);
      const ArrayType *OATy = cast<ArrayType>(Old->getType()->getElementType());
      if (OATy->getElementType() != AETy || OATy->getNumElements() != 0) {
        std::cerr << "WARNING: Two global variables exist with the same name "
                  << "that cannot be resolved!\n";
        return false;
      }

      Old->replaceAllUsesWith(ConstantExpr::getCast(CCPR, Old->getType()));

      // Since there are no uses of Old anymore, remove it from the module.
      M.getGlobalList().erase(Old);

      ++NumGlobals;
      Changed = true;
    }
  return Changed;
}

static bool ProcessGlobalsWithSameName(Module &M,
                                       std::vector<GlobalValue*> &Globals) {
  assert(!Globals.empty() && "Globals list shouldn't be empty here!");

  bool isFunction = isa<Function>(Globals[0]);   // Is this group all functions?
  GlobalValue *Concrete = 0;  // The most concrete implementation to resolve to

  assert((isFunction ^ isa<GlobalVariable>(Globals[0])) &&
         "Should either be function or gvar!");

  for (unsigned i = 0; i != Globals.size(); ) {
    if (isa<Function>(Globals[i]) != isFunction) {
      std::cerr << "WARNING: Found function and global variable with the "
                << "same name: '" << Globals[i]->getName() << "'.\n";
      return false;                 // Don't know how to handle this, bail out!
    }

    if (isFunction) {
      // For functions, we look to merge functions definitions of "int (...)"
      // to 'int (int)' or 'int ()' or whatever else is not completely generic.
      //
      Function *F = cast<Function>(Globals[i]);
      if (!F->isExternal()) {
        if (Concrete && !Concrete->isExternal())
          return false;   // Found two different functions types.  Can't choose!

        Concrete = Globals[i];
      } else if (Concrete) {
        if (Concrete->isExternal()) // If we have multiple external symbols...x
          if (F->getFunctionType()->getNumParams() >
              cast<Function>(Concrete)->getFunctionType()->getNumParams())
            Concrete = F;  // We are more concrete than "Concrete"!

      } else {
        Concrete = F;
      }
    } else {
      // For global variables, we have to merge C definitions int A[][4] with
      // int[6][4].  A[][4] is represented as A[0][4] by the CFE.
      GlobalVariable *GV = cast<GlobalVariable>(Globals[i]);
      if (!isa<ArrayType>(GV->getType()->getElementType())) {
        Concrete = 0;
        break;  // Non array's cannot be compatible with other types.
      } else if (Concrete == 0) {
        Concrete = GV;
      } else {
        // Must have different types... allow merging A[0][4] w/ A[6][4] if
        // A[0][4] is external.
        const ArrayType *NAT = cast<ArrayType>(GV->getType()->getElementType());
        const ArrayType *CAT =
          cast<ArrayType>(Concrete->getType()->getElementType());

        if (NAT->getElementType() != CAT->getElementType()) {
          Concrete = 0;  // Non-compatible types
          break;
        } else if (NAT->getNumElements() == 0 && GV->isExternal()) {
          // Concrete remains the same
        } else if (CAT->getNumElements() == 0 && Concrete->isExternal()) {
          Concrete = GV;   // Concrete becomes GV
        } else {
          Concrete = 0;    // Cannot merge these types...
          break;
        }
      }
    }
    ++i;
  }

  if (Globals.size() > 1) {         // Found a multiply defined global...
    // If there are no external declarations, and there is at most one
    // externally visible instance of the global, then there is nothing to do.
    //
    bool HasExternal = false;
    unsigned NumInstancesWithExternalLinkage = 0;

    for (unsigned i = 0, e = Globals.size(); i != e; ++i) {
      if (Globals[i]->isExternal())
        HasExternal = true;
      else if (!Globals[i]->hasInternalLinkage())
        NumInstancesWithExternalLinkage++;
    }

    if (!HasExternal && NumInstancesWithExternalLinkage <= 1)
      return false;  // Nothing to do?  Must have multiple internal definitions.

    // We should find exactly one concrete function definition, which is
    // probably the implementation.  Change all of the function definitions and
    // uses to use it instead.
    //
    if (!Concrete) {
      std::cerr << "WARNING: Found global types that are not compatible:\n";
      for (unsigned i = 0; i < Globals.size(); ++i) {
        std::cerr << "\t" << Globals[i]->getType()->getDescription() << " %"
                  << Globals[i]->getName() << "\n";
      }
      std::cerr << "  No linkage of globals named '" << Globals[0]->getName()
                << "' performed!\n";
      return false;
    }

    if (isFunction)
      return ResolveFunctions(M, Globals, cast<Function>(Concrete));
    else
      return ResolveGlobalVariables(M, Globals,
                                    cast<GlobalVariable>(Concrete));
  }
  return false;
}

bool FunctionResolvingPass::run(Module &M) {
  SymbolTable &ST = M.getSymbolTable();

  std::map<std::string, std::vector<GlobalValue*> > Globals;

  // Loop over the entries in the symbol table. If an entry is a func pointer,
  // then add it to the Functions map.  We do a two pass algorithm here to avoid
  // problems with iterators getting invalidated if we did a one pass scheme.
  //
  for (SymbolTable::iterator I = ST.begin(), E = ST.end(); I != E; ++I)
    if (const PointerType *PT = dyn_cast<PointerType>(I->first)) {
      SymbolTable::VarMap &Plane = I->second;
      for (SymbolTable::type_iterator PI = Plane.begin(), PE = Plane.end();
           PI != PE; ++PI) {
        GlobalValue *GV = cast<GlobalValue>(PI->second);
        assert(PI->first == GV->getName() &&
               "Global name and symbol table do not agree!");
        Globals[PI->first].push_back(GV);
      }
    }

  bool Changed = false;

  // Now we have a list of all functions with a particular name.  If there is
  // more than one entry in a list, merge the functions together.
  //
  for (std::map<std::string, std::vector<GlobalValue*> >::iterator
         I = Globals.begin(), E = Globals.end(); I != E; ++I)
    Changed |= ProcessGlobalsWithSameName(M, I->second);

  // Now loop over all of the globals, checking to see if any are trivially
  // dead.  If so, remove them now.

  for (Module::iterator I = M.begin(), E = M.end(); I != E; )
    if (I->isExternal() && I->use_empty()) {
      Function *F = I;
      ++I;
      M.getFunctionList().erase(F);
      ++NumResolved;
      Changed = true;
    } else {
      ++I;
    }

  for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; )
    if (I->isExternal() && I->use_empty()) {
      GlobalVariable *GV = I;
      ++I;
      M.getGlobalList().erase(GV);
      ++NumGlobals;
      Changed = true;
    } else {
      ++I;
    }

  return Changed;
}
<commit_msg>Fix bug: FunctionResolve/2003-07-23-CPR-Reference.ll<commit_after>//===- FunctionResolution.cpp - Resolve declarations to implementations ---===//
//
// Loop over the functions that are in the module and look for functions that
// have the same name.  More often than not, there will be things like:
//
//    declare void %foo(...)
//    void %foo(int, int) { ... }
//
// because of the way things are declared in C.  If this is the case, patch
// things up.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO.h"
#include "llvm/Module.h"
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Pass.h"
#include "llvm/iOther.h"
#include "llvm/Constants.h"
#include "llvm/Assembly/Writer.h"  // FIXME: remove when varargs implemented
#include "Support/Statistic.h"
#include <algorithm>

namespace {
  Statistic<>NumResolved("funcresolve", "Number of varargs functions resolved");
  Statistic<> NumGlobals("funcresolve", "Number of global variables resolved");

  struct FunctionResolvingPass : public Pass {
    bool run(Module &M);
  };
  RegisterOpt<FunctionResolvingPass> X("funcresolve", "Resolve Functions");
}

Pass *createFunctionResolvingPass() {
  return new FunctionResolvingPass();
}

static bool ResolveFunctions(Module &M, std::vector<GlobalValue*> &Globals,
                             Function *Concrete) {
  bool Changed = false;
  for (unsigned i = 0; i != Globals.size(); ++i)
    if (Globals[i] != Concrete) {
      Function *Old = cast<Function>(Globals[i]);
      const FunctionType *OldMT = Old->getFunctionType();
      const FunctionType *ConcreteMT = Concrete->getFunctionType();

      if (OldMT->getParamTypes().size() > ConcreteMT->getParamTypes().size() &&
          !ConcreteMT->isVarArg())
        if (!Old->use_empty()) {
          std::cerr << "WARNING: Linking function '" << Old->getName()
                    << "' is causing arguments to be dropped.\n";
          std::cerr << "WARNING: Prototype: ";
          WriteAsOperand(std::cerr, Old);
          std::cerr << " resolved to ";
          WriteAsOperand(std::cerr, Concrete);
          std::cerr << "\n";
        }

      // Check to make sure that if there are specified types, that they
      // match...
      //
      unsigned NumArguments = std::min(OldMT->getParamTypes().size(),
                                       ConcreteMT->getParamTypes().size());

      if (!Old->use_empty() && !Concrete->use_empty())
        for (unsigned i = 0; i < NumArguments; ++i)
          if (OldMT->getParamTypes()[i] != ConcreteMT->getParamTypes()[i]) {
            std::cerr << "WARNING: Function [" << Old->getName()
                      << "]: Parameter types conflict for: '" << OldMT
                      << "' and '" << ConcreteMT << "'\n";
            return Changed;
          }

      // Attempt to convert all of the uses of the old function to the concrete
      // form of the function.  If there is a use of the fn that we don't
      // understand here we punt to avoid making a bad transformation.
      //
      // At this point, we know that the return values are the same for our two
      // functions and that the Old function has no varargs fns specified.  In
      // otherwords it's just <retty> (...)
      //
      if (!Old->use_empty()) {  // Avoid making the CPR unless we really need it
        Value *Replacement = Concrete;
        if (Concrete->getType() != Old->getType())
          Replacement = ConstantExpr::getCast(ConstantPointerRef::get(Concrete),
                                              Old->getType());
        NumResolved += Old->use_size();
        Old->replaceAllUsesWith(Replacement);
      }

      // Since there are no uses of Old anymore, remove it from the module.
      M.getFunctionList().erase(Old);
    }
  return Changed;
}

static bool ResolveGlobalVariables(Module &M,
                                   std::vector<GlobalValue*> &Globals,
                                   GlobalVariable *Concrete) {
  bool Changed = false;
  assert(isa<ArrayType>(Concrete->getType()->getElementType()) &&
         "Concrete version should be an array type!");

  // Get the type of the things that may be resolved to us...
  const ArrayType *CATy =cast<ArrayType>(Concrete->getType()->getElementType());
  const Type *AETy = CATy->getElementType();

  Constant *CCPR = ConstantPointerRef::get(Concrete);

  for (unsigned i = 0; i != Globals.size(); ++i)
    if (Globals[i] != Concrete) {
      GlobalVariable *Old = cast<GlobalVariable>(Globals[i]);
      const ArrayType *OATy = cast<ArrayType>(Old->getType()->getElementType());
      if (OATy->getElementType() != AETy || OATy->getNumElements() != 0) {
        std::cerr << "WARNING: Two global variables exist with the same name "
                  << "that cannot be resolved!\n";
        return false;
      }

      Old->replaceAllUsesWith(ConstantExpr::getCast(CCPR, Old->getType()));

      // Since there are no uses of Old anymore, remove it from the module.
      M.getGlobalList().erase(Old);

      ++NumGlobals;
      Changed = true;
    }
  return Changed;
}

static bool ProcessGlobalsWithSameName(Module &M,
                                       std::vector<GlobalValue*> &Globals) {
  assert(!Globals.empty() && "Globals list shouldn't be empty here!");

  bool isFunction = isa<Function>(Globals[0]);   // Is this group all functions?
  GlobalValue *Concrete = 0;  // The most concrete implementation to resolve to

  assert((isFunction ^ isa<GlobalVariable>(Globals[0])) &&
         "Should either be function or gvar!");

  for (unsigned i = 0; i != Globals.size(); ) {
    if (isa<Function>(Globals[i]) != isFunction) {
      std::cerr << "WARNING: Found function and global variable with the "
                << "same name: '" << Globals[i]->getName() << "'.\n";
      return false;                 // Don't know how to handle this, bail out!
    }

    if (isFunction) {
      // For functions, we look to merge functions definitions of "int (...)"
      // to 'int (int)' or 'int ()' or whatever else is not completely generic.
      //
      Function *F = cast<Function>(Globals[i]);
      if (!F->isExternal()) {
        if (Concrete && !Concrete->isExternal())
          return false;   // Found two different functions types.  Can't choose!

        Concrete = Globals[i];
      } else if (Concrete) {
        if (Concrete->isExternal()) // If we have multiple external symbols...x
          if (F->getFunctionType()->getNumParams() >
              cast<Function>(Concrete)->getFunctionType()->getNumParams())
            Concrete = F;  // We are more concrete than "Concrete"!

      } else {
        Concrete = F;
      }
    } else {
      // For global variables, we have to merge C definitions int A[][4] with
      // int[6][4].  A[][4] is represented as A[0][4] by the CFE.
      GlobalVariable *GV = cast<GlobalVariable>(Globals[i]);
      if (!isa<ArrayType>(GV->getType()->getElementType())) {
        Concrete = 0;
        break;  // Non array's cannot be compatible with other types.
      } else if (Concrete == 0) {
        Concrete = GV;
      } else {
        // Must have different types... allow merging A[0][4] w/ A[6][4] if
        // A[0][4] is external.
        const ArrayType *NAT = cast<ArrayType>(GV->getType()->getElementType());
        const ArrayType *CAT =
          cast<ArrayType>(Concrete->getType()->getElementType());

        if (NAT->getElementType() != CAT->getElementType()) {
          Concrete = 0;  // Non-compatible types
          break;
        } else if (NAT->getNumElements() == 0 && GV->isExternal()) {
          // Concrete remains the same
        } else if (CAT->getNumElements() == 0 && Concrete->isExternal()) {
          Concrete = GV;   // Concrete becomes GV
        } else {
          Concrete = 0;    // Cannot merge these types...
          break;
        }
      }
    }
    ++i;
  }

  if (Globals.size() > 1) {         // Found a multiply defined global...
    // If there are no external declarations, and there is at most one
    // externally visible instance of the global, then there is nothing to do.
    //
    bool HasExternal = false;
    unsigned NumInstancesWithExternalLinkage = 0;

    for (unsigned i = 0, e = Globals.size(); i != e; ++i) {
      if (Globals[i]->isExternal())
        HasExternal = true;
      else if (!Globals[i]->hasInternalLinkage())
        NumInstancesWithExternalLinkage++;
    }

    if (!HasExternal && NumInstancesWithExternalLinkage <= 1)
      return false;  // Nothing to do?  Must have multiple internal definitions.

    // We should find exactly one concrete function definition, which is
    // probably the implementation.  Change all of the function definitions and
    // uses to use it instead.
    //
    if (!Concrete) {
      std::cerr << "WARNING: Found global types that are not compatible:\n";
      for (unsigned i = 0; i < Globals.size(); ++i) {
        std::cerr << "\t" << Globals[i]->getType()->getDescription() << " %"
                  << Globals[i]->getName() << "\n";
      }
      std::cerr << "  No linkage of globals named '" << Globals[0]->getName()
                << "' performed!\n";
      return false;
    }

    if (isFunction)
      return ResolveFunctions(M, Globals, cast<Function>(Concrete));
    else
      return ResolveGlobalVariables(M, Globals,
                                    cast<GlobalVariable>(Concrete));
  }
  return false;
}

bool FunctionResolvingPass::run(Module &M) {
  SymbolTable &ST = M.getSymbolTable();

  std::map<std::string, std::vector<GlobalValue*> > Globals;

  // Loop over the entries in the symbol table. If an entry is a func pointer,
  // then add it to the Functions map.  We do a two pass algorithm here to avoid
  // problems with iterators getting invalidated if we did a one pass scheme.
  //
  for (SymbolTable::iterator I = ST.begin(), E = ST.end(); I != E; ++I)
    if (const PointerType *PT = dyn_cast<PointerType>(I->first)) {
      SymbolTable::VarMap &Plane = I->second;
      for (SymbolTable::type_iterator PI = Plane.begin(), PE = Plane.end();
           PI != PE; ++PI) {
        GlobalValue *GV = cast<GlobalValue>(PI->second);
        assert(PI->first == GV->getName() &&
               "Global name and symbol table do not agree!");
        Globals[PI->first].push_back(GV);
      }
    }

  bool Changed = false;

  // Now we have a list of all functions with a particular name.  If there is
  // more than one entry in a list, merge the functions together.
  //
  for (std::map<std::string, std::vector<GlobalValue*> >::iterator
         I = Globals.begin(), E = Globals.end(); I != E; ++I)
    Changed |= ProcessGlobalsWithSameName(M, I->second);

  // Now loop over all of the globals, checking to see if any are trivially
  // dead.  If so, remove them now.

  for (Module::iterator I = M.begin(), E = M.end(); I != E; )
    if (I->isExternal() && I->use_empty()) {
      Function *F = I;
      ++I;
      M.getFunctionList().erase(F);
      ++NumResolved;
      Changed = true;
    } else {
      ++I;
    }

  for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; )
    if (I->isExternal() && I->use_empty()) {
      GlobalVariable *GV = I;
      ++I;
      M.getGlobalList().erase(GV);
      ++NumGlobals;
      Changed = true;
    } else {
      ++I;
    }

  return Changed;
}
<|endoftext|>


<commit_before>//===- FunctionResolution.cpp - Resolve declarations to implementations ---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Loop over the functions that are in the module and look for functions that
// have the same name.  More often than not, there will be things like:
//
//    declare void %foo(...)
//    void %foo(int, int) { ... }
//
// because of the way things are declared in C.  If this is the case, patch
// things up.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO.h"
#include "llvm/Module.h"
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Pass.h"
#include "llvm/iOther.h"
#include "llvm/Constants.h"
#include "llvm/Assembly/Writer.h"
#include "Support/Statistic.h"
#include <algorithm>

namespace {
  Statistic<>NumResolved("funcresolve", "Number of varargs functions resolved");
  Statistic<> NumGlobals("funcresolve", "Number of global variables resolved");

  struct FunctionResolvingPass : public Pass {
    bool run(Module &M);
  };
  RegisterOpt<FunctionResolvingPass> X("funcresolve", "Resolve Functions");
}

Pass *createFunctionResolvingPass() {
  return new FunctionResolvingPass();
}

static bool ResolveFunctions(Module &M, std::vector<GlobalValue*> &Globals,
                             Function *Concrete) {
  bool Changed = false;
  for (unsigned i = 0; i != Globals.size(); ++i)
    if (Globals[i] != Concrete) {
      Function *Old = cast<Function>(Globals[i]);
      const FunctionType *OldMT = Old->getFunctionType();
      const FunctionType *ConcreteMT = Concrete->getFunctionType();

      if (OldMT->getParamTypes().size() > ConcreteMT->getParamTypes().size() &&
          !ConcreteMT->isVarArg())
        if (!Old->use_empty()) {
          std::cerr << "WARNING: Linking function '" << Old->getName()
                    << "' is causing arguments to be dropped.\n";
          std::cerr << "WARNING: Prototype: ";
          WriteAsOperand(std::cerr, Old);
          std::cerr << " resolved to ";
          WriteAsOperand(std::cerr, Concrete);
          std::cerr << "\n";
        }

      // Check to make sure that if there are specified types, that they
      // match...
      //
      unsigned NumArguments = std::min(OldMT->getParamTypes().size(),
                                       ConcreteMT->getParamTypes().size());

      if (!Old->use_empty() && !Concrete->use_empty())
        for (unsigned i = 0; i < NumArguments; ++i)
          if (OldMT->getParamTypes()[i] != ConcreteMT->getParamTypes()[i])
            if (OldMT->getParamTypes()[i]->getPrimitiveID() !=
                ConcreteMT->getParamTypes()[i]->getPrimitiveID()) {
              std::cerr << "WARNING: Function [" << Old->getName()
                        << "]: Parameter types conflict for: '" << OldMT
                        << "' and '" << ConcreteMT << "'\n";
              return Changed;
            }

      // Attempt to convert all of the uses of the old function to the concrete
      // form of the function.  If there is a use of the fn that we don't
      // understand here we punt to avoid making a bad transformation.
      //
      // At this point, we know that the return values are the same for our two
      // functions and that the Old function has no varargs fns specified.  In
      // otherwords it's just <retty> (...)
      //
      if (!Old->use_empty()) {  // Avoid making the CPR unless we really need it
        Value *Replacement = Concrete;
        if (Concrete->getType() != Old->getType())
          Replacement = ConstantExpr::getCast(ConstantPointerRef::get(Concrete),
                                              Old->getType());
        NumResolved += Old->use_size();
        Old->replaceAllUsesWith(Replacement);
      }

      // Since there are no uses of Old anymore, remove it from the module.
      M.getFunctionList().erase(Old);
    }
  return Changed;
}

static bool ResolveGlobalVariables(Module &M,
                                   std::vector<GlobalValue*> &Globals,
                                   GlobalVariable *Concrete) {
  bool Changed = false;
  assert(isa<ArrayType>(Concrete->getType()->getElementType()) &&
         "Concrete version should be an array type!");

  // Get the type of the things that may be resolved to us...
  const ArrayType *CATy =cast<ArrayType>(Concrete->getType()->getElementType());
  const Type *AETy = CATy->getElementType();

  Constant *CCPR = ConstantPointerRef::get(Concrete);

  for (unsigned i = 0; i != Globals.size(); ++i)
    if (Globals[i] != Concrete) {
      GlobalVariable *Old = cast<GlobalVariable>(Globals[i]);
      const ArrayType *OATy = cast<ArrayType>(Old->getType()->getElementType());
      if (OATy->getElementType() != AETy || OATy->getNumElements() != 0) {
        std::cerr << "WARNING: Two global variables exist with the same name "
                  << "that cannot be resolved!\n";
        return false;
      }

      Old->replaceAllUsesWith(ConstantExpr::getCast(CCPR, Old->getType()));

      // Since there are no uses of Old anymore, remove it from the module.
      M.getGlobalList().erase(Old);

      ++NumGlobals;
      Changed = true;
    }
  return Changed;
}

static bool ProcessGlobalsWithSameName(Module &M,
                                       std::vector<GlobalValue*> &Globals) {
  assert(!Globals.empty() && "Globals list shouldn't be empty here!");

  bool isFunction = isa<Function>(Globals[0]);   // Is this group all functions?
  GlobalValue *Concrete = 0;  // The most concrete implementation to resolve to

  assert((isFunction ^ isa<GlobalVariable>(Globals[0])) &&
         "Should either be function or gvar!");

  for (unsigned i = 0; i != Globals.size(); ) {
    if (isa<Function>(Globals[i]) != isFunction) {
      std::cerr << "WARNING: Found function and global variable with the "
                << "same name: '" << Globals[i]->getName() << "'.\n";
      return false;                 // Don't know how to handle this, bail out!
    }

    if (isFunction) {
      // For functions, we look to merge functions definitions of "int (...)"
      // to 'int (int)' or 'int ()' or whatever else is not completely generic.
      //
      Function *F = cast<Function>(Globals[i]);
      if (!F->isExternal()) {
        if (Concrete && !Concrete->isExternal())
          return false;   // Found two different functions types.  Can't choose!

        Concrete = Globals[i];
      } else if (Concrete) {
        if (Concrete->isExternal()) // If we have multiple external symbols...x
          if (F->getFunctionType()->getNumParams() >
              cast<Function>(Concrete)->getFunctionType()->getNumParams())
            Concrete = F;  // We are more concrete than "Concrete"!

      } else {
        Concrete = F;
      }
    } else {
      // For global variables, we have to merge C definitions int A[][4] with
      // int[6][4].  A[][4] is represented as A[0][4] by the CFE.
      GlobalVariable *GV = cast<GlobalVariable>(Globals[i]);
      if (!isa<ArrayType>(GV->getType()->getElementType())) {
        Concrete = 0;
        break;  // Non array's cannot be compatible with other types.
      } else if (Concrete == 0) {
        Concrete = GV;
      } else {
        // Must have different types... allow merging A[0][4] w/ A[6][4] if
        // A[0][4] is external.
        const ArrayType *NAT = cast<ArrayType>(GV->getType()->getElementType());
        const ArrayType *CAT =
          cast<ArrayType>(Concrete->getType()->getElementType());

        if (NAT->getElementType() != CAT->getElementType()) {
          Concrete = 0;  // Non-compatible types
          break;
        } else if (NAT->getNumElements() == 0 && GV->isExternal()) {
          // Concrete remains the same
        } else if (CAT->getNumElements() == 0 && Concrete->isExternal()) {
          Concrete = GV;   // Concrete becomes GV
        } else {
          Concrete = 0;    // Cannot merge these types...
          break;
        }
      }
    }
    ++i;
  }

  if (Globals.size() > 1) {         // Found a multiply defined global...
    // If there are no external declarations, and there is at most one
    // externally visible instance of the global, then there is nothing to do.
    //
    bool HasExternal = false;
    unsigned NumInstancesWithExternalLinkage = 0;

    for (unsigned i = 0, e = Globals.size(); i != e; ++i) {
      if (Globals[i]->isExternal())
        HasExternal = true;
      else if (!Globals[i]->hasInternalLinkage())
        NumInstancesWithExternalLinkage++;
    }

    if (!HasExternal && NumInstancesWithExternalLinkage <= 1)
      return false;  // Nothing to do?  Must have multiple internal definitions.

    // We should find exactly one concrete function definition, which is
    // probably the implementation.  Change all of the function definitions and
    // uses to use it instead.
    //
    if (!Concrete) {
      std::cerr << "WARNING: Found global types that are not compatible:\n";
      for (unsigned i = 0; i < Globals.size(); ++i) {
        std::cerr << "\t" << Globals[i]->getType()->getDescription() << " %"
                  << Globals[i]->getName() << "\n";
      }
      std::cerr << "  No linkage of globals named '" << Globals[0]->getName()
                << "' performed!\n";
      return false;
    }

    if (isFunction)
      return ResolveFunctions(M, Globals, cast<Function>(Concrete));
    else
      return ResolveGlobalVariables(M, Globals,
                                    cast<GlobalVariable>(Concrete));
  }
  return false;
}

bool FunctionResolvingPass::run(Module &M) {
  SymbolTable &ST = M.getSymbolTable();

  std::map<std::string, std::vector<GlobalValue*> > Globals;

  // Loop over the entries in the symbol table. If an entry is a func pointer,
  // then add it to the Functions map.  We do a two pass algorithm here to avoid
  // problems with iterators getting invalidated if we did a one pass scheme.
  //
  for (SymbolTable::iterator I = ST.begin(), E = ST.end(); I != E; ++I)
    if (const PointerType *PT = dyn_cast<PointerType>(I->first)) {
      SymbolTable::VarMap &Plane = I->second;
      for (SymbolTable::type_iterator PI = Plane.begin(), PE = Plane.end();
           PI != PE; ++PI) {
        GlobalValue *GV = cast<GlobalValue>(PI->second);
        assert(PI->first == GV->getName() &&
               "Global name and symbol table do not agree!");
        Globals[PI->first].push_back(GV);
      }
    }

  bool Changed = false;

  // Now we have a list of all functions with a particular name.  If there is
  // more than one entry in a list, merge the functions together.
  //
  for (std::map<std::string, std::vector<GlobalValue*> >::iterator
         I = Globals.begin(), E = Globals.end(); I != E; ++I)
    Changed |= ProcessGlobalsWithSameName(M, I->second);

  // Now loop over all of the globals, checking to see if any are trivially
  // dead.  If so, remove them now.

  for (Module::iterator I = M.begin(), E = M.end(); I != E; )
    if (I->isExternal() && I->use_empty()) {
      Function *F = I;
      ++I;
      M.getFunctionList().erase(F);
      ++NumResolved;
      Changed = true;
    } else {
      ++I;
    }

  for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; )
    if (I->isExternal() && I->use_empty()) {
      GlobalVariable *GV = I;
      ++I;
      M.getGlobalList().erase(GV);
      ++NumGlobals;
      Changed = true;
    } else {
      ++I;
    }

  return Changed;
}
<commit_msg>Fix bug: FunctionResolve/2003-10-21-GlobalTypeDifference.ll<commit_after>//===- FunctionResolution.cpp - Resolve declarations to implementations ---===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Loop over the functions that are in the module and look for functions that
// have the same name.  More often than not, there will be things like:
//
//    declare void %foo(...)
//    void %foo(int, int) { ... }
//
// because of the way things are declared in C.  If this is the case, patch
// things up.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO.h"
#include "llvm/Module.h"
#include "llvm/SymbolTable.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Pass.h"
#include "llvm/iOther.h"
#include "llvm/Constants.h"
#include "llvm/Assembly/Writer.h"
#include "Support/Statistic.h"
#include <algorithm>

namespace {
  Statistic<>NumResolved("funcresolve", "Number of varargs functions resolved");
  Statistic<> NumGlobals("funcresolve", "Number of global variables resolved");

  struct FunctionResolvingPass : public Pass {
    bool run(Module &M);
  };
  RegisterOpt<FunctionResolvingPass> X("funcresolve", "Resolve Functions");
}

Pass *createFunctionResolvingPass() {
  return new FunctionResolvingPass();
}

static bool ResolveFunctions(Module &M, std::vector<GlobalValue*> &Globals,
                             Function *Concrete) {
  bool Changed = false;
  for (unsigned i = 0; i != Globals.size(); ++i)
    if (Globals[i] != Concrete) {
      Function *Old = cast<Function>(Globals[i]);
      const FunctionType *OldMT = Old->getFunctionType();
      const FunctionType *ConcreteMT = Concrete->getFunctionType();

      if (OldMT->getParamTypes().size() > ConcreteMT->getParamTypes().size() &&
          !ConcreteMT->isVarArg())
        if (!Old->use_empty()) {
          std::cerr << "WARNING: Linking function '" << Old->getName()
                    << "' is causing arguments to be dropped.\n";
          std::cerr << "WARNING: Prototype: ";
          WriteAsOperand(std::cerr, Old);
          std::cerr << " resolved to ";
          WriteAsOperand(std::cerr, Concrete);
          std::cerr << "\n";
        }

      // Check to make sure that if there are specified types, that they
      // match...
      //
      unsigned NumArguments = std::min(OldMT->getParamTypes().size(),
                                       ConcreteMT->getParamTypes().size());

      if (!Old->use_empty() && !Concrete->use_empty())
        for (unsigned i = 0; i < NumArguments; ++i)
          if (OldMT->getParamTypes()[i] != ConcreteMT->getParamTypes()[i])
            if (OldMT->getParamTypes()[i]->getPrimitiveID() !=
                ConcreteMT->getParamTypes()[i]->getPrimitiveID()) {
              std::cerr << "WARNING: Function [" << Old->getName()
                        << "]: Parameter types conflict for: '" << OldMT
                        << "' and '" << ConcreteMT << "'\n";
              return Changed;
            }

      // Attempt to convert all of the uses of the old function to the concrete
      // form of the function.  If there is a use of the fn that we don't
      // understand here we punt to avoid making a bad transformation.
      //
      // At this point, we know that the return values are the same for our two
      // functions and that the Old function has no varargs fns specified.  In
      // otherwords it's just <retty> (...)
      //
      if (!Old->use_empty()) {  // Avoid making the CPR unless we really need it
        Value *Replacement = Concrete;
        if (Concrete->getType() != Old->getType())
          Replacement = ConstantExpr::getCast(ConstantPointerRef::get(Concrete),
                                              Old->getType());
        NumResolved += Old->use_size();
        Old->replaceAllUsesWith(Replacement);
      }

      // Since there are no uses of Old anymore, remove it from the module.
      M.getFunctionList().erase(Old);
    }
  return Changed;
}

static bool ResolveGlobalVariables(Module &M,
                                   std::vector<GlobalValue*> &Globals,
                                   GlobalVariable *Concrete) {
  bool Changed = false;
  Constant *CCPR = ConstantPointerRef::get(Concrete);

  for (unsigned i = 0; i != Globals.size(); ++i)
    if (Globals[i] != Concrete) {
      Constant *Cast = ConstantExpr::getCast(CCPR, Globals[i]->getType());
      Globals[i]->replaceAllUsesWith(Cast);

      // Since there are no uses of Old anymore, remove it from the module.
      M.getGlobalList().erase(cast<GlobalVariable>(Globals[i]));

      ++NumGlobals;
      Changed = true;
    }
  return Changed;
}

static bool ProcessGlobalsWithSameName(Module &M,
                                       std::vector<GlobalValue*> &Globals) {
  assert(!Globals.empty() && "Globals list shouldn't be empty here!");

  bool isFunction = isa<Function>(Globals[0]);   // Is this group all functions?
  GlobalValue *Concrete = 0;  // The most concrete implementation to resolve to

  assert((isFunction ^ isa<GlobalVariable>(Globals[0])) &&
         "Should either be function or gvar!");

  for (unsigned i = 0; i != Globals.size(); ) {
    if (isa<Function>(Globals[i]) != isFunction) {
      std::cerr << "WARNING: Found function and global variable with the "
                << "same name: '" << Globals[i]->getName() << "'.\n";
      return false;                 // Don't know how to handle this, bail out!
    }

    if (isFunction) {
      // For functions, we look to merge functions definitions of "int (...)"
      // to 'int (int)' or 'int ()' or whatever else is not completely generic.
      //
      Function *F = cast<Function>(Globals[i]);
      if (!F->isExternal()) {
        if (Concrete && !Concrete->isExternal())
          return false;   // Found two different functions types.  Can't choose!

        Concrete = Globals[i];
      } else if (Concrete) {
        if (Concrete->isExternal()) // If we have multiple external symbols...x
          if (F->getFunctionType()->getNumParams() >
              cast<Function>(Concrete)->getFunctionType()->getNumParams())
            Concrete = F;  // We are more concrete than "Concrete"!

      } else {
        Concrete = F;
      }
    } else {
      GlobalVariable *GV = cast<GlobalVariable>(Globals[i]);
      if (!GV->isExternal()) {
        if (Concrete) {
          std::cerr << "WARNING: Two global variables with external linkage"
                    << " exist with the same name: '" << GV->getName()
                    << "'!\n";
          return false;
        }
        Concrete = GV;
      }
    }
    ++i;
  }

  if (Globals.size() > 1) {         // Found a multiply defined global...
    // If there are no external declarations, and there is at most one
    // externally visible instance of the global, then there is nothing to do.
    //
    bool HasExternal = false;
    unsigned NumInstancesWithExternalLinkage = 0;

    for (unsigned i = 0, e = Globals.size(); i != e; ++i) {
      if (Globals[i]->isExternal())
        HasExternal = true;
      else if (!Globals[i]->hasInternalLinkage())
        NumInstancesWithExternalLinkage++;
    }

    if (!HasExternal && NumInstancesWithExternalLinkage <= 1)
      return false;  // Nothing to do?  Must have multiple internal definitions.

    std::cerr << "WARNING: Found global types that are not compatible:\n";
    for (unsigned i = 0; i < Globals.size(); ++i) {
      std::cerr << "\t" << *Globals[i]->getType() << " %"
                << Globals[i]->getName() << "\n";
    }

    if (!Concrete)
      Concrete = Globals[0];

    if (isFunction)
      return ResolveFunctions(M, Globals, cast<Function>(Concrete));
    else
      return ResolveGlobalVariables(M, Globals,
                                    cast<GlobalVariable>(Concrete));
  }
  return false;
}

bool FunctionResolvingPass::run(Module &M) {
  SymbolTable &ST = M.getSymbolTable();

  std::map<std::string, std::vector<GlobalValue*> > Globals;

  // Loop over the entries in the symbol table. If an entry is a func pointer,
  // then add it to the Functions map.  We do a two pass algorithm here to avoid
  // problems with iterators getting invalidated if we did a one pass scheme.
  //
  for (SymbolTable::iterator I = ST.begin(), E = ST.end(); I != E; ++I)
    if (const PointerType *PT = dyn_cast<PointerType>(I->first)) {
      SymbolTable::VarMap &Plane = I->second;
      for (SymbolTable::type_iterator PI = Plane.begin(), PE = Plane.end();
           PI != PE; ++PI) {
        GlobalValue *GV = cast<GlobalValue>(PI->second);
        assert(PI->first == GV->getName() &&
               "Global name and symbol table do not agree!");
        if (!GV->hasInternalLinkage())
          Globals[PI->first].push_back(GV);
      }
    }

  bool Changed = false;

  // Now we have a list of all functions with a particular name.  If there is
  // more than one entry in a list, merge the functions together.
  //
  for (std::map<std::string, std::vector<GlobalValue*> >::iterator
         I = Globals.begin(), E = Globals.end(); I != E; ++I)
    Changed |= ProcessGlobalsWithSameName(M, I->second);

  // Now loop over all of the globals, checking to see if any are trivially
  // dead.  If so, remove them now.

  for (Module::iterator I = M.begin(), E = M.end(); I != E; )
    if (I->isExternal() && I->use_empty()) {
      Function *F = I;
      ++I;
      M.getFunctionList().erase(F);
      ++NumResolved;
      Changed = true;
    } else {
      ++I;
    }

  for (Module::giterator I = M.gbegin(), E = M.gend(); I != E; )
    if (I->isExternal() && I->use_empty()) {
      GlobalVariable *GV = I;
      ++I;
      M.getGlobalList().erase(GV);
      ++NumGlobals;
      Changed = true;
    } else {
      ++I;
    }

  return Changed;
}
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

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

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

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

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

#ifndef MITKDIFFUSIONIMAGETODIFFUSIONIMAGEFILTER_CPP
#define MITKDIFFUSIONIMAGETODIFFUSIONIMAGEFILTER_CPP

#include "mitkDWIHeadMotionCorrectionFilter.h"

#include "itkSplitDWImageFilter.h"
#include "itkB0ImageExtractionToSeparateImageFilter.h"

#include "mitkImageTimeSelector.h"

#include "mitkPyramidImageRegistrationMethod.h"
#include "mitkImageToDiffusionImageSource.h"

#include "mitkIOUtil.h"

template< typename DiffusionPixelType>
mitk::DWIHeadMotionCorrectionFilter<DiffusionPixelType>
::DWIHeadMotionCorrectionFilter()
{

}

template< typename DiffusionPixelType>
void mitk::DWIHeadMotionCorrectionFilter<DiffusionPixelType>
::GenerateData()
{
  typedef itk::SplitDWImageFilter< DiffusionPixelType, DiffusionPixelType> SplitFilterType;

  DiffusionImageType* input = const_cast<DiffusionImageType*>(this->GetInput(0));

  //
  //  (1) Extract the b-zero images to a 3d+t image, register them by NCorr metric and
  //     rigid registration : they will then be used are reference image for registering
  //     the gradient images
  //
  typedef itk::B0ImageExtractionToSeparateImageFilter< DiffusionPixelType, DiffusionPixelType> B0ExtractorType;
  typename B0ExtractorType::Pointer b0_extractor = B0ExtractorType::New();
  b0_extractor->SetInput( input->GetVectorImage() );
  b0_extractor->SetDirections( input->GetDirections() );
  b0_extractor->Update();

  mitk::Image::Pointer b0Image = mitk::Image::New();
  b0Image->InitializeByItk( b0_extractor->GetOutput() );
  b0Image->SetImportChannel( b0_extractor->GetOutput()->GetBufferPointer(),
                             mitk::Image::CopyMemory );

  // (2.1) Use the extractor to access the extracted b0 volumes
  mitk::ImageTimeSelector::Pointer t_selector =
      mitk::ImageTimeSelector::New();

  t_selector->SetInput( b0Image );
  t_selector->SetTimeNr(0);
  t_selector->Update();

  // first unweighted image as reference space for the registration
  mitk::Image::Pointer b0referenceImage = t_selector->GetOutput();

  mitk::PyramidImageRegistrationMethod::Pointer registrationMethod = mitk::PyramidImageRegistrationMethod::New();
  registrationMethod->SetFixedImage( b0referenceImage );
  registrationMethod->SetTransformToRigid();

  // the unweighted images are of same modality
  registrationMethod->SetCrossModalityOff();

  // Initialize the temporary output image
  mitk::Image::Pointer registeredB0Image = b0Image->Clone();
  const unsigned int numberOfb0Images = b0Image->GetTimeSteps();

  mitk::ImageTimeSelector::Pointer t_selector2 =
      mitk::ImageTimeSelector::New();

  t_selector2->SetInput( b0Image );

  for( unsigned int i=1; i<numberOfb0Images; i++)
  {

    t_selector2->SetTimeNr(i);
    t_selector2->Update();

    registrationMethod->SetMovingImage( t_selector2->GetOutput() );

    try
    {
      MITK_INFO << " === (" << i <<"/"<< numberOfb0Images-1 << ") :: Starting registration";
      registrationMethod->Update();
    }
    catch( const itk::ExceptionObject& e)
    {
      mitkThrow() << "Failed to register the b0 images, the PyramidRegistration threw an exception: \n" << e.what();
    }

    // import volume to the inter-results
    registeredB0Image->SetImportVolume( registrationMethod->GetResampledMovingImage()->GetData(),
                                       i, 0, mitk::Image::ReferenceMemory );

  }

  //
  // (2) Split the diffusion image into a 3d+t regular image, extract only the weighted images
  //
  typename SplitFilterType::Pointer split_filter = SplitFilterType::New();
  split_filter->SetInput (input->GetVectorImage() );
  split_filter->SetExtractAllAboveThreshold(20, input->GetB_ValueMap() );

  try
  {
    split_filter->Update();
  }
  catch( const itk::ExceptionObject &e)
  {
    mitkThrow() << " Caught exception from SplitImageFilter : " << e.what();
  }

  mitk::Image::Pointer splittedImage = mitk::Image::New();
  splittedImage->InitializeByItk( split_filter->GetOutput() );
  splittedImage->SetImportChannel( split_filter->GetOutput()->GetBufferPointer(),
                                   mitk::Image::CopyMemory );

  //
  // (3) Use again the time-selector to access the components separately in order
  //     to perform the registration of  Image -> unweighted reference
  //

  mitk::PyramidImageRegistrationMethod::Pointer weightedRegistrationMethod
      = mitk::PyramidImageRegistrationMethod::New();

  weightedRegistrationMethod->SetTransformToAffine();
  weightedRegistrationMethod->SetCrossModalityOn();
  //
  //   - (3.1) Create a reference image by averaging the aligned b0 images
  //
  //   !!!FIXME: For rapid prototyping using the first one
  //

  weightedRegistrationMethod->SetFixedImage( b0referenceImage );

  //
  //   - (3.2) Register all timesteps in the splitted image onto the first reference
  //
  unsigned int maxImageIdx = splittedImage->GetTimeSteps();
  mitk::TimeSlicedGeometry* tsg = splittedImage->GetTimeSlicedGeometry();
  tsg->ExpandToNumberOfTimeSteps( maxImageIdx+1 );

  mitk::Image::Pointer registeredWeighted = mitk::Image::New();
  registeredWeighted->Initialize( splittedImage->GetPixelType(0), *tsg );

  // insert the first unweighted reference as the first volume
  registeredWeighted->SetImportVolume( b0referenceImage->GetData(),
                                      0,0, mitk::Image::CopyMemory );

  // mitk::Image::Pointer registeredWeighted = splittedImage->Clone();
  // this time start at 0, we have only gradient images in the 3d+t file
  // the reference image comes form an other image
  mitk::ImageTimeSelector::Pointer t_selector_w =
      mitk::ImageTimeSelector::New();

  t_selector_w->SetInput( splittedImage );

  for( unsigned int i=0; i<maxImageIdx; i++)
  {
    t_selector_w->SetTimeNr(i);
    t_selector_w->Update();

    weightedRegistrationMethod->SetMovingImage( t_selector_w->GetOutput() );

    try
    {
      MITK_INFO << " === (" << i+1 <<"/"<< maxImageIdx << ") :: Starting registration";
      weightedRegistrationMethod->Update();
    }
    catch( const itk::ExceptionObject& e)
    {
      mitkThrow() << "Failed to register the b0 images, the PyramidRegistration threw an exception: \n" << e.what();
    }

    // allow expansion
    registeredWeighted->SetImportVolume( weightedRegistrationMethod->GetResampledMovingImage()->GetData(),
                                         i+1, 0, mitk::Image::CopyMemory);
  }

  //
  // (4) Cast the resulting image back to an diffusion weighted image
  //

  typename DiffusionImageType::GradientDirectionContainerType *gradients = input->GetDirections();
  typename DiffusionImageType::GradientDirectionContainerType::Pointer gradients_new =
      DiffusionImageType::GradientDirectionContainerType::New();
  typename DiffusionImageType::GradientDirectionType bzero_vector;
  bzero_vector.fill(0);
  // compose the direction vector
  //  - no direction for the first image
  //  - correct ordering of the directions based on the index list
  gradients_new->push_back( bzero_vector );

  typename SplitFilterType::IndexListType index_list = split_filter->GetIndexList();
  typename SplitFilterType::IndexListType::const_iterator lIter = index_list.begin();

  while( lIter != index_list.end() )
  {
    gradients_new->push_back( gradients->at( *lIter ) );
    ++lIter;
  }

  typename mitk::ImageToDiffusionImageSource< DiffusionPixelType >::Pointer caster =
      mitk::ImageToDiffusionImageSource< DiffusionPixelType >::New();

  caster->SetImage( registeredWeighted );
  caster->SetBValue( input->GetB_Value() );
  caster->SetGradientDirections( gradients_new );

  try
  {
    caster->Update();
    this->itk::ProcessObject::SetOutput(0 , caster->GetOutput() );
  }
  catch( const itk::ExceptionObject& e)
  {
    MITK_ERROR << "Casting back to diffusion image failed: ";
    mitkThrow() << "Subprocess failed with exception: " << e.what();
  }

}

template< typename DiffusionPixelType>
void mitk::DWIHeadMotionCorrectionFilter<DiffusionPixelType>
::GenerateOutputInformation()
{
  if( ! this->GetInput(0) )
  {
    mitkThrow() << "No input specified!";
  }
}

#endif // MITKDIFFUSIONIMAGETODIFFUSIONIMAGEFILTER_CPP
<commit_msg>WIP(unstable) Finalizing the head motion correction<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

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

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

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

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

#ifndef MITKDIFFUSIONIMAGETODIFFUSIONIMAGEFILTER_CPP
#define MITKDIFFUSIONIMAGETODIFFUSIONIMAGEFILTER_CPP

#include "mitkDWIHeadMotionCorrectionFilter.h"

#include "itkSplitDWImageFilter.h"
#include "itkB0ImageExtractionToSeparateImageFilter.h"

#include "mitkImageTimeSelector.h"

#include "mitkPyramidImageRegistrationMethod.h"
#include "mitkImageToDiffusionImageSource.h"

#include "mitkIOUtil.h"

template< typename DiffusionPixelType>
mitk::DWIHeadMotionCorrectionFilter<DiffusionPixelType>
::DWIHeadMotionCorrectionFilter()
{

}

template< typename DiffusionPixelType>
void mitk::DWIHeadMotionCorrectionFilter<DiffusionPixelType>
::GenerateData()
{
  typedef itk::SplitDWImageFilter< DiffusionPixelType, DiffusionPixelType> SplitFilterType;

  DiffusionImageType* input = const_cast<DiffusionImageType*>(this->GetInput(0));

  //
  //  (1) Extract the b-zero images to a 3d+t image, register them by NCorr metric and
  //     rigid registration : they will then be used are reference image for registering
  //     the gradient images
  //
  typedef itk::B0ImageExtractionToSeparateImageFilter< DiffusionPixelType, DiffusionPixelType> B0ExtractorType;
  typename B0ExtractorType::Pointer b0_extractor = B0ExtractorType::New();
  b0_extractor->SetInput( input->GetVectorImage() );
  b0_extractor->SetDirections( input->GetDirections() );
  b0_extractor->Update();

  mitk::Image::Pointer b0Image = mitk::Image::New();
  b0Image->InitializeByItk( b0_extractor->GetOutput() );
  b0Image->SetImportChannel( b0_extractor->GetOutput()->GetBufferPointer(),
                             mitk::Image::CopyMemory );

  // (2.1) Use the extractor to access the extracted b0 volumes
  mitk::ImageTimeSelector::Pointer t_selector =
      mitk::ImageTimeSelector::New();

  t_selector->SetInput( b0Image );
  t_selector->SetTimeNr(0);
  t_selector->Update();

  // first unweighted image as reference space for the registration
  mitk::Image::Pointer b0referenceImage = t_selector->GetOutput();

  mitk::PyramidImageRegistrationMethod::Pointer registrationMethod = mitk::PyramidImageRegistrationMethod::New();
  registrationMethod->SetFixedImage( b0referenceImage );
  registrationMethod->SetTransformToRigid();

  // the unweighted images are of same modality
  registrationMethod->SetCrossModalityOff();

  // Initialize the temporary output image
  mitk::Image::Pointer registeredB0Image = b0Image->Clone();
  const unsigned int numberOfb0Images = b0Image->GetTimeSteps();

  mitk::ImageTimeSelector::Pointer t_selector2 =
      mitk::ImageTimeSelector::New();

  t_selector2->SetInput( b0Image );

  for( unsigned int i=1; i<numberOfb0Images; i++)
  {

    t_selector2->SetTimeNr(i);
    t_selector2->Update();

    registrationMethod->SetMovingImage( t_selector2->GetOutput() );

    try
    {
      MITK_INFO << " === (" << i <<"/"<< numberOfb0Images-1 << ") :: Starting registration";
      registrationMethod->Update();
    }
    catch( const itk::ExceptionObject& e)
    {
      mitkThrow() << "Failed to register the b0 images, the PyramidRegistration threw an exception: \n" << e.what();
    }

    // import volume to the inter-results
    registeredB0Image->SetImportVolume( registrationMethod->GetResampledMovingImage()->GetData(),
                                       i, 0, mitk::Image::ReferenceMemory );

  }

  //
  // (2) Split the diffusion image into a 3d+t regular image, extract only the weighted images
  //
  typename SplitFilterType::Pointer split_filter = SplitFilterType::New();
  split_filter->SetInput (input->GetVectorImage() );
  split_filter->SetExtractAllAboveThreshold(20, input->GetB_ValueMap() );

  try
  {
    split_filter->Update();
  }
  catch( const itk::ExceptionObject &e)
  {
    mitkThrow() << " Caught exception from SplitImageFilter : " << e.what();
  }

  mitk::Image::Pointer splittedImage = mitk::Image::New();
  splittedImage->InitializeByItk( split_filter->GetOutput() );
  splittedImage->SetImportChannel( split_filter->GetOutput()->GetBufferPointer(),
                                   mitk::Image::CopyMemory );

  //
  // (3) Use again the time-selector to access the components separately in order
  //     to perform the registration of  Image -> unweighted reference
  //

  mitk::PyramidImageRegistrationMethod::Pointer weightedRegistrationMethod
      = mitk::PyramidImageRegistrationMethod::New();

  weightedRegistrationMethod->SetTransformToAffine();
  weightedRegistrationMethod->SetCrossModalityOn();
  //
  //   - (3.1) Create a reference image by averaging the aligned b0 images
  //
  //   !!!FIXME: For rapid prototyping using the first one
  //

  weightedRegistrationMethod->SetFixedImage( b0referenceImage );

  //
  //   - (3.2) Register all timesteps in the splitted image onto the first reference
  //
  unsigned int maxImageIdx = splittedImage->GetTimeSteps();
  mitk::TimeSlicedGeometry* tsg = splittedImage->GetTimeSlicedGeometry();
  tsg->ExpandToNumberOfTimeSteps( maxImageIdx+1 );

  mitk::Image::Pointer registeredWeighted = mitk::Image::New();
  registeredWeighted->Initialize( splittedImage->GetPixelType(0), *tsg );

  // insert the first unweighted reference as the first volume
  registeredWeighted->SetImportVolume( b0referenceImage->GetData(),
                                      0,0, mitk::Image::CopyMemory );

  // mitk::Image::Pointer registeredWeighted = splittedImage->Clone();
  // this time start at 0, we have only gradient images in the 3d+t file
  // the reference image comes form an other image
  mitk::ImageTimeSelector::Pointer t_selector_w =
      mitk::ImageTimeSelector::New();

  t_selector_w->SetInput( splittedImage );

  for( unsigned int i=0; i<maxImageIdx; i++)
  {
    t_selector_w->SetTimeNr(i);
    t_selector_w->Update();

    weightedRegistrationMethod->SetMovingImage( t_selector_w->GetOutput() );

    try
    {
      MITK_INFO << " === (" << i+1 <<"/"<< maxImageIdx << ") :: Starting registration";
      weightedRegistrationMethod->Update();
    }
    catch( const itk::ExceptionObject& e)
    {
      mitkThrow() << "Failed to register the b0 images, the PyramidRegistration threw an exception: \n" << e.what();
    }

    // allow expansion
    registeredWeighted->SetImportVolume( weightedRegistrationMethod->GetResampledMovingImage()->GetData(),
                                         i+1, 0, mitk::Image::CopyMemory);
  }

  //
  // (4) Cast the resulting image back to an diffusion weighted image
  //

  typename DiffusionImageType::GradientDirectionContainerType *gradients = input->GetDirections();
  typename DiffusionImageType::GradientDirectionContainerType::Pointer gradients_new =
      DiffusionImageType::GradientDirectionContainerType::New();
  typename DiffusionImageType::GradientDirectionType bzero_vector;
  bzero_vector.fill(0);
  // compose the direction vector
  //  - no direction for the first image
  //  - correct ordering of the directions based on the index list
  gradients_new->push_back( bzero_vector );

  typename SplitFilterType::IndexListType index_list = split_filter->GetIndexList();
  typename SplitFilterType::IndexListType::const_iterator lIter = index_list.begin();

  while( lIter != index_list.end() )
  {
    gradients_new->push_back( gradients->at( *lIter ) );
    ++lIter;
  }

  typename mitk::ImageToDiffusionImageSource< DiffusionPixelType >::Pointer caster =
      mitk::ImageToDiffusionImageSource< DiffusionPixelType >::New();

  caster->SetImage( registeredWeighted );
  caster->SetBValue( input->GetB_Value() );
  caster->SetGradientDirections( gradients_new.GetPointer() );

  try
  {
    caster->Update();
  }
  catch( const itk::ExceptionObject& e)
  {
    MITK_ERROR << "Casting back to diffusion image failed: ";
    mitkThrow() << "Subprocess failed with exception: " << e.what();
  }

  //
  // FIXME!!! EXTREME QUICK-HACK

  typedef typename mitk::DiffusionImageSource< DiffusionPixelType>::OutputType OutputType;

  DiffusionImageType* dwimageout =
      static_cast<DiffusionImageType*>( caster->GetOutput() );

  static_cast<OutputType*>(this->GetOutput())
      ->SetVectorImage(dwimageout->GetVectorImage());
  static_cast<OutputType*>(this->GetOutput())
      ->SetB_Value(dwimageout->GetB_Value());
  static_cast<OutputType*>(this->GetOutput())
      ->SetDirections(dwimageout->GetDirections());
  static_cast<OutputType*>(this->GetOutput())
      ->SetMeasurementFrame(dwimageout->GetMeasurementFrame());
  static_cast<OutputType*>(this->GetOutput())->InitializeFromVectorImage();

}

template< typename DiffusionPixelType>
void mitk::DWIHeadMotionCorrectionFilter<DiffusionPixelType>
::GenerateOutputInformation()
{
  if( ! this->GetInput(0) )
  {
    mitkThrow() << "No input specified!";
  }
}

#endif // MITKDIFFUSIONIMAGETODIFFUSIONIMAGEFILTER_CPP
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_IMAGE_ANY_HPP
#define MAPNIK_IMAGE_ANY_HPP

#include <mapnik/image.hpp>
#include <mapnik/image_null.hpp>
#include <mapnik/util/variant.hpp>

namespace mapnik {

using image_base = util::variant<image_null,
                                      image_rgba8,
                                      image_gray8,
                                      image_gray8s,
                                      image_gray16,
                                      image_gray16s,
                                      image_gray32,
                                      image_gray32s,
                                      image_gray32f,
                                      image_gray64,
                                      image_gray64s,
                                      image_gray64f>;

struct MAPNIK_DECL image_any : image_base
{
    image_any() = default;

    image_any(int width,
              int height,
              image_dtype type = image_dtype_rgba8,
              bool initialize = true,
              bool premultiplied = false,
              bool painted = false);

    template <typename T>
    image_any(T && data) noexcept
    : image_base(std::move(data)) {}

    unsigned char const* getBytes() const;
    unsigned char* getBytes();
    std::size_t width() const;
    std::size_t height() const;
    bool get_premultiplied() const;
    bool painted() const;
    unsigned getSize() const;
    unsigned getRowSize() const;
    double get_offset() const;
    double get_scaling() const;
    image_dtype get_dtype() const;
    void set_offset(double val);
    void set_scaling(double val);
};

image_any create_image_any(int width,
                int height,
                image_dtype type = image_dtype_rgba8,
                bool initialize = true,
                bool premultiplied = false,
                bool painted = false);

} // end mapnik ns

#endif // MAPNIK_IMAGE_ANY_HPP
<commit_msg>Possibly fixing windows issues<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2014 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_IMAGE_ANY_HPP
#define MAPNIK_IMAGE_ANY_HPP

#include <mapnik/image.hpp>
#include <mapnik/image_null.hpp>
#include <mapnik/util/variant.hpp>

namespace mapnik {

using image_base = util::variant<image_null,
                                      image_rgba8,
                                      image_gray8,
                                      image_gray8s,
                                      image_gray16,
                                      image_gray16s,
                                      image_gray32,
                                      image_gray32s,
                                      image_gray32f,
                                      image_gray64,
                                      image_gray64s,
                                      image_gray64f>;

struct MAPNIK_DECL image_any : image_base
{
    image_any() = default;

    image_any(int width,
              int height,
              image_dtype type = image_dtype_rgba8,
              bool initialize = true,
              bool premultiplied = false,
              bool painted = false);

    template <typename T>
    image_any(T && data) noexcept
    : image_base(std::move(data)) {}

    unsigned char const* getBytes() const;
    unsigned char* getBytes();
    std::size_t width() const;
    std::size_t height() const;
    bool get_premultiplied() const;
    bool painted() const;
    unsigned getSize() const;
    unsigned getRowSize() const;
    double get_offset() const;
    double get_scaling() const;
    image_dtype get_dtype() const;
    void set_offset(double val);
    void set_scaling(double val);
};

MAPNIK_DECL image_any create_image_any(int width,
                int height,
                image_dtype type = image_dtype_rgba8,
                bool initialize = true,
                bool premultiplied = false,
                bool painted = false);

} // end mapnik ns

#endif // MAPNIK_IMAGE_ANY_HPP
<|endoftext|>


<commit_before>/*
 * MyManageType.cpp
 *
 *  Created on: 2015年12月27日
 *      Author: moss
 */

#include "MyManageType.h"
#include "MyParseKey.h"
MyManageType::MyManageType() {

}

MyManageType::~MyManageType() {

}
const std::string& MyManageType::getObjectTypeName() {
	static std::string typeStr(MY_MANAGE_TYPE);
	return typeStr;
}
bool MyManageType::onGetIDByType(khala::InfoNodePtr& infoNodePtr,
		Json::Value& msg, khala::Timestamp time) {
	std::vector<uint> v = this->getNodeManager()->getNodeIDs(
			infoNodePtr->getNodeType());
	std::stringstream ss;
	ss << "Get ID By Type:Ask type:" << infoNodePtr->getNodeType()
			<< " . Get ID:";
	for (std::vector<uint>::iterator it = v.begin(); it != v.end(); ++it) {
		ss << *it << " ";
	}
	infoNodePtr->send(ss.str());
	return true;
}
bool MyManageType::onGetIDByObject(khala::InfoNodePtr& infoNodePtr,
		Json::Value& msg, khala::Timestamp time) {
	MyManageType* tmp = new MyManageType();
	std::vector<uint> v = this->getNodeManager()->getNodeIDs(tmp);
	std::stringstream ss;
	ss << "Get ID By Object:Ask Object type:" << tmp->getObjectTypeName()
			<< " . Get ID:";
	for (std::vector<uint>::iterator it = v.begin(); it != v.end(); ++it) {
		ss << *it << " ";
	}
	infoNodePtr->send(ss.str());
	delete tmp;
	return true;
}
bool MyManageType::onGetAllIDByObject(khala::InfoNodePtr& infoNodePtr,
		Json::Value& msg, khala::Timestamp time) {
	NodeType* tmp = new NodeType();
	//parameter is NodeType Object
	std::vector<uint> v = this->getNodeManager()->getAllNodeIDs(*tmp);
	std::stringstream ss;
	ss << "Get All ID By Object:Ask Object type:" << tmp->getObjectTypeName()
			<< " . Get ID:";
	for (std::vector<uint>::iterator it = v.begin(); it != v.end(); ++it) {
		ss << *it << " ";
	}
	infoNodePtr->send(ss.str());
	delete tmp;
	return true;
}
bool MyManageType::onGetAllIDByObjectPtr(khala::InfoNodePtr& infoNodePtr,
		Json::Value& msg, khala::Timestamp time) {
	NodeType* tmp = new NodeType();
	//parameter is NodeType Object pointor
	std::vector<uint> v = this->getNodeManager()->getAllNodeIDs(tmp);
	std::stringstream ss;
	ss << "Get All ID By Object ptr:Ask Object type:"
			<< tmp->getObjectTypeName() << " . Get ID:";
	for (std::vector<uint>::iterator it = v.begin(); it != v.end(); ++it) {
		ss << *it << " ";
	}
	infoNodePtr->send(ss.str());
	delete tmp;
	return true;
}
bool MyManageType::onAskLogin(khala::InfoNodePtr& infoNodePtr, Json::Value& msg,
		khala::Timestamp time){
	uint friendId = msg[KEY_FRIEND_ID].asUInt();
	std::stringstream ss;
	ss<<"Node ID:"<<friendId;
	if(this->getNodeManager()->hasNode(friendId)){
		ss<<" is login!";
	}else{
		ss<<" is not login!";
	}
	infoNodePtr->send(ss.str());
	return true;
}
bool MyManageType::onSendtoNode(khala::InfoNodePtr& infoNodePtr,
		Json::Value& msg, khala::Timestamp time){
	uint myId = infoNodePtr->getId();
	khala::InfoNodePtr myInfoNodePtr;
	if(this->getNodeManager()->find(myId, myInfoNodePtr)){
		myInfoNodePtr->send("test manager find success");
	}
	return true;
}
void MyManageType::setRegisterMsg(khala::RegisterHandler& handler){
	NodeType::setRegisterMsg(handler);
	handler.setRegisterMsg(ID_BY_TYPE,
					boost::bind(&MyManageType::onGetIDByType, this, _1, _2, _3));
	handler.setRegisterMsg(ID_BY_OBJECT,
			boost::bind(&MyManageType::onGetIDByObject, this, _1, _2, _3));
	handler.setRegisterMsg(ALL_ID_BY_OBJECT,
				boost::bind(&MyManageType::onGetAllIDByObject, this, _1, _2, _3));
	handler.setRegisterMsg(ALL_ID_BY_OBJECT_PTR,
				boost::bind(&MyManageType::onGetAllIDByObjectPtr, this, _1, _2, _3));
	handler.setRegisterMsg(ASK_LOGIN,
				boost::bind(&MyManageType::onAskLogin, this, _1, _2, _3));
	handler.setRegisterMsg(SEND_MSG,
					boost::bind(&MyManageType::onSendtoNode, this, _1, _2, _3));
}
<commit_msg>添加<sstream>头文件<commit_after>/*
 * MyManageType.cpp
 *
 *  Created on: 2015年12月27日
 *      Author: moss
 */

#include "MyManageType.h"
#include "MyParseKey.h"
#include <sstream>
MyManageType::MyManageType() {

}

MyManageType::~MyManageType() {

}
const std::string& MyManageType::getObjectTypeName() {
	static std::string typeStr(MY_MANAGE_TYPE);
	return typeStr;
}
bool MyManageType::onGetIDByType(khala::InfoNodePtr& infoNodePtr,
		Json::Value& msg, khala::Timestamp time) {
	std::vector<uint> v = this->getNodeManager()->getNodeIDs(
			infoNodePtr->getNodeType());
	std::stringstream ss;
	ss << "Get ID By Type:Ask type:" << infoNodePtr->getNodeType()
			<< " . Get ID:";
	for (std::vector<uint>::iterator it = v.begin(); it != v.end(); ++it) {
		ss << *it << " ";
	}
	infoNodePtr->send(ss.str());
	return true;
}
bool MyManageType::onGetIDByObject(khala::InfoNodePtr& infoNodePtr,
		Json::Value& msg, khala::Timestamp time) {
	MyManageType* tmp = new MyManageType();
	std::vector<uint> v = this->getNodeManager()->getNodeIDs(tmp);
	std::stringstream ss;
	ss << "Get ID By Object:Ask Object type:" << tmp->getObjectTypeName()
			<< " . Get ID:";
	for (std::vector<uint>::iterator it = v.begin(); it != v.end(); ++it) {
		ss << *it << " ";
	}
	infoNodePtr->send(ss.str());
	delete tmp;
	return true;
}
bool MyManageType::onGetAllIDByObject(khala::InfoNodePtr& infoNodePtr,
		Json::Value& msg, khala::Timestamp time) {
	NodeType* tmp = new NodeType();
	//parameter is NodeType Object
	std::vector<uint> v = this->getNodeManager()->getAllNodeIDs(*tmp);
	std::stringstream ss;
	ss << "Get All ID By Object:Ask Object type:" << tmp->getObjectTypeName()
			<< " . Get ID:";
	for (std::vector<uint>::iterator it = v.begin(); it != v.end(); ++it) {
		ss << *it << " ";
	}
	infoNodePtr->send(ss.str());
	delete tmp;
	return true;
}
bool MyManageType::onGetAllIDByObjectPtr(khala::InfoNodePtr& infoNodePtr,
		Json::Value& msg, khala::Timestamp time) {
	NodeType* tmp = new NodeType();
	//parameter is NodeType Object pointor
	std::vector<uint> v = this->getNodeManager()->getAllNodeIDs(tmp);
	std::stringstream ss;
	ss << "Get All ID By Object ptr:Ask Object type:"
			<< tmp->getObjectTypeName() << " . Get ID:";
	for (std::vector<uint>::iterator it = v.begin(); it != v.end(); ++it) {
		ss << *it << " ";
	}
	infoNodePtr->send(ss.str());
	delete tmp;
	return true;
}
bool MyManageType::onAskLogin(khala::InfoNodePtr& infoNodePtr, Json::Value& msg,
		khala::Timestamp time){
	uint friendId = msg[KEY_FRIEND_ID].asUInt();
	std::stringstream ss;
	ss<<"Node ID:"<<friendId;
	if(this->getNodeManager()->hasNode(friendId)){
		ss<<" is login!";
	}else{
		ss<<" is not login!";
	}
	infoNodePtr->send(ss.str());
	return true;
}
bool MyManageType::onSendtoNode(khala::InfoNodePtr& infoNodePtr,
		Json::Value& msg, khala::Timestamp time){
	uint myId = infoNodePtr->getId();
	khala::InfoNodePtr myInfoNodePtr;
	if(this->getNodeManager()->find(myId, myInfoNodePtr)){
		myInfoNodePtr->send("test manager find success");
	}
	return true;
}
void MyManageType::setRegisterMsg(khala::RegisterHandler& handler){
	NodeType::setRegisterMsg(handler);
	handler.setRegisterMsg(ID_BY_TYPE,
					boost::bind(&MyManageType::onGetIDByType, this, _1, _2, _3));
	handler.setRegisterMsg(ID_BY_OBJECT,
			boost::bind(&MyManageType::onGetIDByObject, this, _1, _2, _3));
	handler.setRegisterMsg(ALL_ID_BY_OBJECT,
				boost::bind(&MyManageType::onGetAllIDByObject, this, _1, _2, _3));
	handler.setRegisterMsg(ALL_ID_BY_OBJECT_PTR,
				boost::bind(&MyManageType::onGetAllIDByObjectPtr, this, _1, _2, _3));
	handler.setRegisterMsg(ASK_LOGIN,
				boost::bind(&MyManageType::onAskLogin, this, _1, _2, _3));
	handler.setRegisterMsg(SEND_MSG,
					boost::bind(&MyManageType::onSendtoNode, this, _1, _2, _3));
}
<|endoftext|>


<commit_before>// Copyright 2016-2017 Francesco Biscani (bluescarni@gmail.com)
//
// This file is part of the mp++ library.
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef MPPP_DETAIL_MPFR_HPP
#define MPPP_DETAIL_MPFR_HPP

#include <mp++/config.hpp>

#if defined(MPPP_WITH_MPFR)

#include <limits>
#include <mpfr.h>
#include <type_traits>

#include <mp++/detail/gmp.hpp>

#if MPFR_VERSION_MAJOR < 3

#error Minimum supported MPFR version is 3.

#endif

namespace mppp
{

inline namespace detail
{

// mpfr_t is an array of some struct.
using mpfr_struct_t = std::remove_extent<::mpfr_t>::type;

// Simple RAII holder for MPFR floats.
struct mpfr_raii {
    mpfr_raii(::mpfr_prec_t prec)
    {
        ::mpfr_init2(&m_mpfr, prec);
    }
    ~mpfr_raii()
    {
        ::mpfr_clear(&m_mpfr);
    }
    mpfr_struct_t m_mpfr;
};
}

// A couple of sanity checks when constructing temporary mpfrs/mpfs from long double.
static_assert(std::numeric_limits<long double>::digits10 < std::numeric_limits<int>::max() / 4, "Overflow error.");
static_assert(std::numeric_limits<long double>::digits10 * 4 < std::numeric_limits<::mpfr_prec_t>::max(),
              "Overflow error.");
static_assert(std::numeric_limits<long double>::digits10 * 4 < std::numeric_limits<::mp_bitcnt_t>::max(),
              "Overflow error.");
}

#else

#error The 'mpfr.hpp' header was included but mp++ was not installed with MPFR support.

#endif

#endif
<commit_msg>Implement the auto-cleanup mechanism for MPFR.<commit_after>// Copyright 2016-2017 Francesco Biscani (bluescarni@gmail.com)
//
// This file is part of the mp++ library.
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef MPPP_DETAIL_MPFR_HPP
#define MPPP_DETAIL_MPFR_HPP

#include <cstdlib>
#include <limits>
#include <memory>
#include <mpfr.h>
#include <type_traits>

#include <mp++/detail/gmp.hpp>

#if MPFR_VERSION_MAJOR < 3

#error Minimum supported MPFR version is 3.

#endif

namespace mppp
{

inline namespace detail
{

// mpfr_t is an array of some struct.
using mpfr_struct_t = std::remove_extent<::mpfr_t>::type;

// Simple RAII holder for MPFR floats.
struct mpfr_raii {
    mpfr_raii(::mpfr_prec_t prec)
    {
        ::mpfr_init2(&m_mpfr, prec);
    }
    ~mpfr_raii()
    {
        ::mpfr_clear(&m_mpfr);
    }
    mpfr_struct_t m_mpfr;
};

// Smart pointer to handle the string output from mpfr.
using smart_mpfr_str = std::unique_ptr<char, void (*)(char *)>;

// A couple of sanity checks when constructing temporary mpfrs/mpfs from long double.
static_assert(std::numeric_limits<long double>::digits10 < std::numeric_limits<int>::max() / 4, "Overflow error.");
static_assert(std::numeric_limits<long double>::digits10 * 4 < std::numeric_limits<::mpfr_prec_t>::max(),
              "Overflow error.");
static_assert(std::numeric_limits<long double>::digits10 * 4 < std::numeric_limits<::mp_bitcnt_t>::max(),
              "Overflow error.");

// Machinery to call automatically mpfr_free_cache() at program shutdown,
// if this header is included.
struct mpfr_cleanup {
    mpfr_cleanup()
    {
        std::atexit(::mpfr_free_cache);
    }
};

template <typename = void>
struct mpfr_cleanup_holder {
    static mpfr_cleanup s_cleanup;
};

template <typename T>
mpfr_cleanup mpfr_cleanup_holder<T>::s_cleanup;

inline void inst_mpfr_cleanup()
{
    auto ptr = &mpfr_cleanup_holder<>::s_cleanup;
    (void)ptr;
}
}
}

#endif
<|endoftext|>