<commit_before>//===- ValueMapper.cpp - Interface shared by lib/Transforms/Utils ---------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MapValue function, which is shared by various parts of
// the lib/Transforms/Utils library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
using namespace llvm;

// Out of line method to get vtable etc for class.
void ValueMapTypeRemapper::anchor() {}
void ValueMaterializer::anchor() {}

Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags,
                      ValueMapTypeRemapper *TypeMapper,
                      ValueMaterializer *Materializer) {
  ValueToValueMapTy::iterator I = VM.find(V);

  // If the value already exists in the map, use it.
  if (I != VM.end() && I->second) return I->second;

  // If we have a materializer and it can materialize a value, use that.
  if (Materializer) {
    if (Value *NewV = Materializer->materializeValueFor(const_cast<Value*>(V)))
      return VM[V] = NewV;
  }

  // Global values do not need to be seeded into the VM if they
  // are using the identity mapping.
  if (isa<GlobalValue>(V))
    return VM[V] = const_cast<Value*>(V);

  if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
    // Inline asm may need *type* remapping.
    FunctionType *NewTy = IA->getFunctionType();
    if (TypeMapper) {
      NewTy = cast<FunctionType>(TypeMapper->remapType(NewTy));

      if (NewTy != IA->getFunctionType())
        V = InlineAsm::get(NewTy, IA->getAsmString(), IA->getConstraintString(),
                           IA->hasSideEffects(), IA->isAlignStack());
    }

    return VM[V] = const_cast<Value*>(V);
  }

  if (const auto *MDV = dyn_cast<MetadataAsValue>(V)) {
    const Metadata *MD = MDV->getMetadata();
    // If this is a module-level metadata and we know that nothing at the module
    // level is changing, then use an identity mapping.
    if (!isa<LocalAsMetadata>(MD) && (Flags & RF_NoModuleLevelChanges))
      return VM[V] = const_cast<Value *>(V);

    auto *MappedMD = MapMetadata(MD, VM, Flags, TypeMapper, Materializer);
    if (MD == MappedMD || (!MappedMD && (Flags & RF_IgnoreMissingEntries)))
      return VM[V] = const_cast<Value *>(V);

    // FIXME: This assert crashes during bootstrap, but I think it should be
    // correct.  For now, just match behaviour from before the metadata/value
    // split.
    //
    //    assert(MappedMD && "Referenced metadata value not in value map");
    return VM[V] = MetadataAsValue::get(V->getContext(), MappedMD);
  }

  // Okay, this either must be a constant (which may or may not be mappable) or
  // is something that is not in the mapping table.
  Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));
  if (!C)
    return nullptr;

  if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
    Function *F =
      cast<Function>(MapValue(BA->getFunction(), VM, Flags, TypeMapper, Materializer));
    BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(), VM,
                                                       Flags, TypeMapper, Materializer));
    return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
  }

  // Otherwise, we have some other constant to remap.  Start by checking to see
  // if all operands have an identity remapping.
  unsigned OpNo = 0, NumOperands = C->getNumOperands();
  Value *Mapped = nullptr;
  for (; OpNo != NumOperands; ++OpNo) {
    Value *Op = C->getOperand(OpNo);
    Mapped = MapValue(Op, VM, Flags, TypeMapper, Materializer);
    if (Mapped != C) break;
  }

  // See if the type mapper wants to remap the type as well.
  Type *NewTy = C->getType();
  if (TypeMapper)
    NewTy = TypeMapper->remapType(NewTy);

  // If the result type and all operands match up, then just insert an identity
  // mapping.
  if (OpNo == NumOperands && NewTy == C->getType())
    return VM[V] = C;

  // Okay, we need to create a new constant.  We've already processed some or
  // all of the operands, set them all up now.
  SmallVector<Constant*, 8> Ops;
  Ops.reserve(NumOperands);
  for (unsigned j = 0; j != OpNo; ++j)
    Ops.push_back(cast<Constant>(C->getOperand(j)));

  // If one of the operands mismatch, push it and the other mapped operands.
  if (OpNo != NumOperands) {
    Ops.push_back(cast<Constant>(Mapped));

    // Map the rest of the operands that aren't processed yet.
    for (++OpNo; OpNo != NumOperands; ++OpNo)
      Ops.push_back(MapValue(cast<Constant>(C->getOperand(OpNo)), VM,
                             Flags, TypeMapper, Materializer));
  }

  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
    return VM[V] = CE->getWithOperands(Ops, NewTy);
  if (isa<ConstantArray>(C))
    return VM[V] = ConstantArray::get(cast<ArrayType>(NewTy), Ops);
  if (isa<ConstantStruct>(C))
    return VM[V] = ConstantStruct::get(cast<StructType>(NewTy), Ops);
  if (isa<ConstantVector>(C))
    return VM[V] = ConstantVector::get(Ops);
  // If this is a no-operand constant, it must be because the type was remapped.
  if (isa<UndefValue>(C))
    return VM[V] = UndefValue::get(NewTy);
  if (isa<ConstantAggregateZero>(C))
    return VM[V] = ConstantAggregateZero::get(NewTy);
  assert(isa<ConstantPointerNull>(C));
  return VM[V] = ConstantPointerNull::get(cast<PointerType>(NewTy));
}

static Metadata *mapToMetadata(ValueToValueMapTy &VM, const Metadata *Key,
                     Metadata *Val) {
  VM.MD()[Key].reset(Val);
  return Val;
}

static Metadata *mapToSelf(ValueToValueMapTy &VM, const Metadata *MD) {
  return mapToMetadata(VM, MD, const_cast<Metadata *>(MD));
}

static Metadata *MapMetadataImpl(const Metadata *MD, ValueToValueMapTy &VM,
                                 RemapFlags Flags,
                                 ValueMapTypeRemapper *TypeMapper,
                                 ValueMaterializer *Materializer);

static Metadata *mapMetadataOp(Metadata *Op, ValueToValueMapTy &VM,
                               RemapFlags Flags,
                               ValueMapTypeRemapper *TypeMapper,
                               ValueMaterializer *Materializer) {
  if (!Op)
    return nullptr;
  if (Metadata *MappedOp =
          MapMetadataImpl(Op, VM, Flags, TypeMapper, Materializer))
    return MappedOp;
  // Use identity map if MappedOp is null and we can ignore missing entries.
  if (Flags & RF_IgnoreMissingEntries)
    return Op;

  // FIXME: This assert crashes during bootstrap, but I think it should be
  // correct.  For now, just match behaviour from before the metadata/value
  // split.
  //
  //    llvm_unreachable("Referenced metadata not in value map!");
  return nullptr;
}

static TempMDTuple cloneMDTuple(const MDTuple *Node) {
  SmallVector<Metadata *, 4> Elts;
  Elts.append(Node->op_begin(), Node->op_end());
  return MDTuple::getTemporary(Node->getContext(), Elts);
}

static TempMDLocation cloneMDLocation(const MDLocation *Node) {
  return MDLocation::getTemporary(Node->getContext(), Node->getLine(),
                                  Node->getColumn(), Node->getScope(),
                                  Node->getInlinedAt());
}

static TempUniquableMDNode cloneMDNode(const UniquableMDNode *Node) {
  switch (Node->getMetadataID()) {
  default:
    llvm_unreachable("Invalid UniquableMDNode subclass");
#define HANDLE_UNIQUABLE_LEAF(CLASS)                                           \
  case Metadata::CLASS##Kind:                                                  \
    return clone##CLASS(cast<CLASS>(Node));
#include "llvm/IR/Metadata.def"
  }
}

/// \brief Map a distinct MDNode.
///
/// Distinct nodes are not uniqued, so they must always recreated.
static Metadata *mapDistinctNode(const UniquableMDNode *Node,
                                 ValueToValueMapTy &VM, RemapFlags Flags,
                                 ValueMapTypeRemapper *TypeMapper,
                                 ValueMaterializer *Materializer) {
  assert(Node->isDistinct() && "Expected distinct node");

  // Create the node first so it's available for cyclical references.
  MDNode *NewMD = MDNode::replaceWithDistinct(cloneMDNode(Node));
  mapToMetadata(VM, Node, NewMD);

  // Fix the operands.
  for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I)
    NewMD->replaceOperandWith(I, mapMetadataOp(Node->getOperand(I), VM, Flags,
                                               TypeMapper, Materializer));

  return NewMD;
}

/// \brief Map a uniqued MDNode.
///
/// Uniqued nodes may not need to be recreated (they may map to themselves).
static Metadata *mapUniquedNode(const UniquableMDNode *Node,
                                 ValueToValueMapTy &VM, RemapFlags Flags,
                                 ValueMapTypeRemapper *TypeMapper,
                                 ValueMaterializer *Materializer) {
  assert(Node->isUniqued() && "Expected uniqued node");

  // Create a temporary node upfront in case we have a metadata cycle.
  auto ClonedMD = cloneMDNode(Node);
  mapToMetadata(VM, Node, ClonedMD.get());

  // Remap the operands, keeping track of whether any changed.
  bool AnyChanged = false;
  for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I) {
    Metadata *Old = Node->getOperand(I);
    Metadata *New = mapMetadataOp(Old, VM, Flags, TypeMapper, Materializer);
    if (Old != New) {
      ClonedMD->replaceOperandWith(I, New);
      AnyChanged = true;
    }
  }

  if (!AnyChanged)
    // Use an identity mapping.
    return mapToSelf(VM, Node);

  // At least one operand has changed, so uniquify the cloned node.
  return mapToMetadata(VM, Node,
                       MDNode::replaceWithUniqued(std::move(ClonedMD)));
}

static Metadata *MapMetadataImpl(const Metadata *MD, ValueToValueMapTy &VM,
                                 RemapFlags Flags,
                                 ValueMapTypeRemapper *TypeMapper,
                                 ValueMaterializer *Materializer) {
  // If the value already exists in the map, use it.
  if (Metadata *NewMD = VM.MD().lookup(MD).get())
    return NewMD;

  if (isa<MDString>(MD))
    return mapToSelf(VM, MD);

  if (isa<ConstantAsMetadata>(MD))
    if ((Flags & RF_NoModuleLevelChanges))
      return mapToSelf(VM, MD);

  if (const auto *VMD = dyn_cast<ValueAsMetadata>(MD)) {
    Value *MappedV =
        MapValue(VMD->getValue(), VM, Flags, TypeMapper, Materializer);
    if (VMD->getValue() == MappedV ||
        (!MappedV && (Flags & RF_IgnoreMissingEntries)))
      return mapToSelf(VM, MD);

    // FIXME: This assert crashes during bootstrap, but I think it should be
    // correct.  For now, just match behaviour from before the metadata/value
    // split.
    //
    //    assert(MappedV && "Referenced metadata not in value map!");
    if (MappedV)
      return mapToMetadata(VM, MD, ValueAsMetadata::get(MappedV));
    return nullptr;
  }

  const UniquableMDNode *Node = cast<UniquableMDNode>(MD);
  assert(Node->isResolved() && "Unexpected unresolved node");

  // If this is a module-level metadata and we know that nothing at the
  // module level is changing, then use an identity mapping.
  if (Flags & RF_NoModuleLevelChanges)
    return mapToSelf(VM, MD);

  if (Node->isDistinct())
    return mapDistinctNode(Node, VM, Flags, TypeMapper, Materializer);

  return mapUniquedNode(Node, VM, Flags, TypeMapper, Materializer);
}

Metadata *llvm::MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
                            RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
                            ValueMaterializer *Materializer) {
  Metadata *NewMD = MapMetadataImpl(MD, VM, Flags, TypeMapper, Materializer);
  if (NewMD && NewMD != MD)
    if (auto *N = dyn_cast<UniquableMDNode>(NewMD))
      N->resolveCycles();
  return NewMD;
}

MDNode *llvm::MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
                          RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
                          ValueMaterializer *Materializer) {
  return cast<MDNode>(MapMetadata(static_cast<const Metadata *>(MD), VM, Flags,
                                  TypeMapper, Materializer));
}

/// RemapInstruction - Convert the instruction operands from referencing the
/// current values into those specified by VMap.
///
void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap,
                            RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
                            ValueMaterializer *Materializer){
  // Remap operands.
  for (User::op_iterator op = I->op_begin(), E = I->op_end(); op != E; ++op) {
    Value *V = MapValue(*op, VMap, Flags, TypeMapper, Materializer);
    // If we aren't ignoring missing entries, assert that something happened.
    if (V)
      *op = V;
    else
      assert((Flags & RF_IgnoreMissingEntries) &&
             "Referenced value not in value map!");
  }

  // Remap phi nodes' incoming blocks.
  if (PHINode *PN = dyn_cast<PHINode>(I)) {
    for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
      Value *V = MapValue(PN->getIncomingBlock(i), VMap, Flags);
      // If we aren't ignoring missing entries, assert that something happened.
      if (V)
        PN->setIncomingBlock(i, cast<BasicBlock>(V));
      else
        assert((Flags & RF_IgnoreMissingEntries) &&
               "Referenced block not in value map!");
    }
  }

  // Remap attached metadata.
  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
  I->getAllMetadata(MDs);
  for (SmallVectorImpl<std::pair<unsigned, MDNode *>>::iterator
           MI = MDs.begin(),
           ME = MDs.end();
       MI != ME; ++MI) {
    MDNode *Old = MI->second;
    MDNode *New = MapMetadata(Old, VMap, Flags, TypeMapper, Materializer);
    if (New != Old)
      I->setMetadata(MI->first, New);
  }

  // If the instruction's type is being remapped, do so now.
  if (TypeMapper)
    I->mutateType(TypeMapper->remapType(I->getType()));
}
<commit_msg>Fix whitespace, NFC<commit_after>//===- ValueMapper.cpp - Interface shared by lib/Transforms/Utils ---------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the MapValue function, which is shared by various parts of
// the lib/Transforms/Utils library.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Metadata.h"
using namespace llvm;

// Out of line method to get vtable etc for class.
void ValueMapTypeRemapper::anchor() {}
void ValueMaterializer::anchor() {}

Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags,
                      ValueMapTypeRemapper *TypeMapper,
                      ValueMaterializer *Materializer) {
  ValueToValueMapTy::iterator I = VM.find(V);

  // If the value already exists in the map, use it.
  if (I != VM.end() && I->second) return I->second;

  // If we have a materializer and it can materialize a value, use that.
  if (Materializer) {
    if (Value *NewV = Materializer->materializeValueFor(const_cast<Value*>(V)))
      return VM[V] = NewV;
  }

  // Global values do not need to be seeded into the VM if they
  // are using the identity mapping.
  if (isa<GlobalValue>(V))
    return VM[V] = const_cast<Value*>(V);

  if (const InlineAsm *IA = dyn_cast<InlineAsm>(V)) {
    // Inline asm may need *type* remapping.
    FunctionType *NewTy = IA->getFunctionType();
    if (TypeMapper) {
      NewTy = cast<FunctionType>(TypeMapper->remapType(NewTy));

      if (NewTy != IA->getFunctionType())
        V = InlineAsm::get(NewTy, IA->getAsmString(), IA->getConstraintString(),
                           IA->hasSideEffects(), IA->isAlignStack());
    }

    return VM[V] = const_cast<Value*>(V);
  }

  if (const auto *MDV = dyn_cast<MetadataAsValue>(V)) {
    const Metadata *MD = MDV->getMetadata();
    // If this is a module-level metadata and we know that nothing at the module
    // level is changing, then use an identity mapping.
    if (!isa<LocalAsMetadata>(MD) && (Flags & RF_NoModuleLevelChanges))
      return VM[V] = const_cast<Value *>(V);

    auto *MappedMD = MapMetadata(MD, VM, Flags, TypeMapper, Materializer);
    if (MD == MappedMD || (!MappedMD && (Flags & RF_IgnoreMissingEntries)))
      return VM[V] = const_cast<Value *>(V);

    // FIXME: This assert crashes during bootstrap, but I think it should be
    // correct.  For now, just match behaviour from before the metadata/value
    // split.
    //
    //    assert(MappedMD && "Referenced metadata value not in value map");
    return VM[V] = MetadataAsValue::get(V->getContext(), MappedMD);
  }

  // Okay, this either must be a constant (which may or may not be mappable) or
  // is something that is not in the mapping table.
  Constant *C = const_cast<Constant*>(dyn_cast<Constant>(V));
  if (!C)
    return nullptr;

  if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
    Function *F =
      cast<Function>(MapValue(BA->getFunction(), VM, Flags, TypeMapper, Materializer));
    BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(), VM,
                                                       Flags, TypeMapper, Materializer));
    return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
  }

  // Otherwise, we have some other constant to remap.  Start by checking to see
  // if all operands have an identity remapping.
  unsigned OpNo = 0, NumOperands = C->getNumOperands();
  Value *Mapped = nullptr;
  for (; OpNo != NumOperands; ++OpNo) {
    Value *Op = C->getOperand(OpNo);
    Mapped = MapValue(Op, VM, Flags, TypeMapper, Materializer);
    if (Mapped != C) break;
  }

  // See if the type mapper wants to remap the type as well.
  Type *NewTy = C->getType();
  if (TypeMapper)
    NewTy = TypeMapper->remapType(NewTy);

  // If the result type and all operands match up, then just insert an identity
  // mapping.
  if (OpNo == NumOperands && NewTy == C->getType())
    return VM[V] = C;

  // Okay, we need to create a new constant.  We've already processed some or
  // all of the operands, set them all up now.
  SmallVector<Constant*, 8> Ops;
  Ops.reserve(NumOperands);
  for (unsigned j = 0; j != OpNo; ++j)
    Ops.push_back(cast<Constant>(C->getOperand(j)));

  // If one of the operands mismatch, push it and the other mapped operands.
  if (OpNo != NumOperands) {
    Ops.push_back(cast<Constant>(Mapped));

    // Map the rest of the operands that aren't processed yet.
    for (++OpNo; OpNo != NumOperands; ++OpNo)
      Ops.push_back(MapValue(cast<Constant>(C->getOperand(OpNo)), VM,
                             Flags, TypeMapper, Materializer));
  }

  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
    return VM[V] = CE->getWithOperands(Ops, NewTy);
  if (isa<ConstantArray>(C))
    return VM[V] = ConstantArray::get(cast<ArrayType>(NewTy), Ops);
  if (isa<ConstantStruct>(C))
    return VM[V] = ConstantStruct::get(cast<StructType>(NewTy), Ops);
  if (isa<ConstantVector>(C))
    return VM[V] = ConstantVector::get(Ops);
  // If this is a no-operand constant, it must be because the type was remapped.
  if (isa<UndefValue>(C))
    return VM[V] = UndefValue::get(NewTy);
  if (isa<ConstantAggregateZero>(C))
    return VM[V] = ConstantAggregateZero::get(NewTy);
  assert(isa<ConstantPointerNull>(C));
  return VM[V] = ConstantPointerNull::get(cast<PointerType>(NewTy));
}

static Metadata *mapToMetadata(ValueToValueMapTy &VM, const Metadata *Key,
                     Metadata *Val) {
  VM.MD()[Key].reset(Val);
  return Val;
}

static Metadata *mapToSelf(ValueToValueMapTy &VM, const Metadata *MD) {
  return mapToMetadata(VM, MD, const_cast<Metadata *>(MD));
}

static Metadata *MapMetadataImpl(const Metadata *MD, ValueToValueMapTy &VM,
                                 RemapFlags Flags,
                                 ValueMapTypeRemapper *TypeMapper,
                                 ValueMaterializer *Materializer);

static Metadata *mapMetadataOp(Metadata *Op, ValueToValueMapTy &VM,
                               RemapFlags Flags,
                               ValueMapTypeRemapper *TypeMapper,
                               ValueMaterializer *Materializer) {
  if (!Op)
    return nullptr;
  if (Metadata *MappedOp =
          MapMetadataImpl(Op, VM, Flags, TypeMapper, Materializer))
    return MappedOp;
  // Use identity map if MappedOp is null and we can ignore missing entries.
  if (Flags & RF_IgnoreMissingEntries)
    return Op;

  // FIXME: This assert crashes during bootstrap, but I think it should be
  // correct.  For now, just match behaviour from before the metadata/value
  // split.
  //
  //    llvm_unreachable("Referenced metadata not in value map!");
  return nullptr;
}

static TempMDTuple cloneMDTuple(const MDTuple *Node) {
  SmallVector<Metadata *, 4> Elts;
  Elts.append(Node->op_begin(), Node->op_end());
  return MDTuple::getTemporary(Node->getContext(), Elts);
}

static TempMDLocation cloneMDLocation(const MDLocation *Node) {
  return MDLocation::getTemporary(Node->getContext(), Node->getLine(),
                                  Node->getColumn(), Node->getScope(),
                                  Node->getInlinedAt());
}

static TempUniquableMDNode cloneMDNode(const UniquableMDNode *Node) {
  switch (Node->getMetadataID()) {
  default:
    llvm_unreachable("Invalid UniquableMDNode subclass");
#define HANDLE_UNIQUABLE_LEAF(CLASS)                                           \
  case Metadata::CLASS##Kind:                                                  \
    return clone##CLASS(cast<CLASS>(Node));
#include "llvm/IR/Metadata.def"
  }
}

/// \brief Map a distinct MDNode.
///
/// Distinct nodes are not uniqued, so they must always recreated.
static Metadata *mapDistinctNode(const UniquableMDNode *Node,
                                 ValueToValueMapTy &VM, RemapFlags Flags,
                                 ValueMapTypeRemapper *TypeMapper,
                                 ValueMaterializer *Materializer) {
  assert(Node->isDistinct() && "Expected distinct node");

  // Create the node first so it's available for cyclical references.
  MDNode *NewMD = MDNode::replaceWithDistinct(cloneMDNode(Node));
  mapToMetadata(VM, Node, NewMD);

  // Fix the operands.
  for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I)
    NewMD->replaceOperandWith(I, mapMetadataOp(Node->getOperand(I), VM, Flags,
                                               TypeMapper, Materializer));

  return NewMD;
}

/// \brief Map a uniqued MDNode.
///
/// Uniqued nodes may not need to be recreated (they may map to themselves).
static Metadata *mapUniquedNode(const UniquableMDNode *Node,
                                ValueToValueMapTy &VM, RemapFlags Flags,
                                ValueMapTypeRemapper *TypeMapper,
                                ValueMaterializer *Materializer) {
  assert(Node->isUniqued() && "Expected uniqued node");

  // Create a temporary node upfront in case we have a metadata cycle.
  auto ClonedMD = cloneMDNode(Node);
  mapToMetadata(VM, Node, ClonedMD.get());

  // Remap the operands, keeping track of whether any changed.
  bool AnyChanged = false;
  for (unsigned I = 0, E = Node->getNumOperands(); I != E; ++I) {
    Metadata *Old = Node->getOperand(I);
    Metadata *New = mapMetadataOp(Old, VM, Flags, TypeMapper, Materializer);
    if (Old != New) {
      ClonedMD->replaceOperandWith(I, New);
      AnyChanged = true;
    }
  }

  if (!AnyChanged)
    // Use an identity mapping.
    return mapToSelf(VM, Node);

  // At least one operand has changed, so uniquify the cloned node.
  return mapToMetadata(VM, Node,
                       MDNode::replaceWithUniqued(std::move(ClonedMD)));
}

static Metadata *MapMetadataImpl(const Metadata *MD, ValueToValueMapTy &VM,
                                 RemapFlags Flags,
                                 ValueMapTypeRemapper *TypeMapper,
                                 ValueMaterializer *Materializer) {
  // If the value already exists in the map, use it.
  if (Metadata *NewMD = VM.MD().lookup(MD).get())
    return NewMD;

  if (isa<MDString>(MD))
    return mapToSelf(VM, MD);

  if (isa<ConstantAsMetadata>(MD))
    if ((Flags & RF_NoModuleLevelChanges))
      return mapToSelf(VM, MD);

  if (const auto *VMD = dyn_cast<ValueAsMetadata>(MD)) {
    Value *MappedV =
        MapValue(VMD->getValue(), VM, Flags, TypeMapper, Materializer);
    if (VMD->getValue() == MappedV ||
        (!MappedV && (Flags & RF_IgnoreMissingEntries)))
      return mapToSelf(VM, MD);

    // FIXME: This assert crashes during bootstrap, but I think it should be
    // correct.  For now, just match behaviour from before the metadata/value
    // split.
    //
    //    assert(MappedV && "Referenced metadata not in value map!");
    if (MappedV)
      return mapToMetadata(VM, MD, ValueAsMetadata::get(MappedV));
    return nullptr;
  }

  const UniquableMDNode *Node = cast<UniquableMDNode>(MD);
  assert(Node->isResolved() && "Unexpected unresolved node");

  // If this is a module-level metadata and we know that nothing at the
  // module level is changing, then use an identity mapping.
  if (Flags & RF_NoModuleLevelChanges)
    return mapToSelf(VM, MD);

  if (Node->isDistinct())
    return mapDistinctNode(Node, VM, Flags, TypeMapper, Materializer);

  return mapUniquedNode(Node, VM, Flags, TypeMapper, Materializer);
}

Metadata *llvm::MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
                            RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
                            ValueMaterializer *Materializer) {
  Metadata *NewMD = MapMetadataImpl(MD, VM, Flags, TypeMapper, Materializer);
  if (NewMD && NewMD != MD)
    if (auto *N = dyn_cast<UniquableMDNode>(NewMD))
      N->resolveCycles();
  return NewMD;
}

MDNode *llvm::MapMetadata(const MDNode *MD, ValueToValueMapTy &VM,
                          RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
                          ValueMaterializer *Materializer) {
  return cast<MDNode>(MapMetadata(static_cast<const Metadata *>(MD), VM, Flags,
                                  TypeMapper, Materializer));
}

/// RemapInstruction - Convert the instruction operands from referencing the
/// current values into those specified by VMap.
///
void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap,
                            RemapFlags Flags, ValueMapTypeRemapper *TypeMapper,
                            ValueMaterializer *Materializer){
  // Remap operands.
  for (User::op_iterator op = I->op_begin(), E = I->op_end(); op != E; ++op) {
    Value *V = MapValue(*op, VMap, Flags, TypeMapper, Materializer);
    // If we aren't ignoring missing entries, assert that something happened.
    if (V)
      *op = V;
    else
      assert((Flags & RF_IgnoreMissingEntries) &&
             "Referenced value not in value map!");
  }

  // Remap phi nodes' incoming blocks.
  if (PHINode *PN = dyn_cast<PHINode>(I)) {
    for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
      Value *V = MapValue(PN->getIncomingBlock(i), VMap, Flags);
      // If we aren't ignoring missing entries, assert that something happened.
      if (V)
        PN->setIncomingBlock(i, cast<BasicBlock>(V));
      else
        assert((Flags & RF_IgnoreMissingEntries) &&
               "Referenced block not in value map!");
    }
  }

  // Remap attached metadata.
  SmallVector<std::pair<unsigned, MDNode *>, 4> MDs;
  I->getAllMetadata(MDs);
  for (SmallVectorImpl<std::pair<unsigned, MDNode *>>::iterator
           MI = MDs.begin(),
           ME = MDs.end();
       MI != ME; ++MI) {
    MDNode *Old = MI->second;
    MDNode *New = MapMetadata(Old, VMap, Flags, TypeMapper, Materializer);
    if (New != Old)
      I->setMetadata(MI->first, New);
  }

  // If the instruction's type is being remapped, do so now.
  if (TypeMapper)
    I->mutateType(TypeMapper->remapType(I->getType()));
}
<|endoftext|>


<commit_before>/*
    pluginloader.cpp - Kopete Plugin Loader

    Copyright (c) 2002      by Duncan Mac-Vicar Prett <duncan@kde.org>
    Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>

    Portions of this code based in Noatun plugin code:
    Copyright (c) 2000-2002 The Noatun Developers

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "pluginloader.h"

#include <qapplication.h>
#include <qdir.h>
#include <qfile.h>

#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <knotifyclient.h>
#include <kparts/componentfactory.h>
#include <ksimpleconfig.h>
#include <kstaticdeleter.h>
#include <kstandarddirs.h>
#include <kurl.h>

#include "kopeteplugin.h"

class KopeteLibraryInfo;

// Put the static deleter in its anonymous namespace
namespace
{
	KStaticDeleter<LibraryLoader> sd;
}

bool operator ==(const KopeteLibraryInfo &a, const KopeteLibraryInfo &b)
{
	// Feels like cheating, doesn't it?
	return a.specfile == b.specfile;
}

LibraryLoader* LibraryLoader::s_pluginLoader = 0L;

LibraryLoader* LibraryLoader::pluginLoader()
{
	if( !s_pluginLoader )
		sd.setObject( s_pluginLoader, new LibraryLoader() );

	return s_pluginLoader;
}

LibraryLoader::LibraryLoader()
: QObject( qApp )
{
}

LibraryLoader::~LibraryLoader()
{
	QDictIterator<KopetePlugin> i( mLibHash );
	while( i.current() )
	{
		// Remove causes the iterator to auto-increment, so
		// only increment explicitly when not removing
		if( getInfo( i.currentKey() ).type != QString::fromLatin1( "Kopete/Protocol" ) )
			remove( i.current() );
		else
			++i;
	}
	i.toFirst();
	while( i.current() )
		remove( i.current() );

	kdDebug(14010) << "LibraryLoader::~LibraryLoader(): all plugins removed" << endl;
}

QPtrList<KopetePlugin> LibraryLoader::plugins() const
{
	QPtrList<KopetePlugin> list;
	QDictIterator<KopetePlugin> i( mLibHash );
	for( ; i.current(); ++i )
		list.append( i.current() );

	return list;
}

QValueList<KopeteLibraryInfo> LibraryLoader::loaded() const
{
	QValueList<KopeteLibraryInfo> items;

	QDictIterator<KopetePlugin> i( mLibHash );
	for( ; i.current(); ++i )
	{
		if( mLibHash[ i.currentKey() ] )
			items.append( getInfo( i.currentKey() ) );
	}

	return items;
}

bool LibraryLoader::loadAll()
{
	KConfig *config=KGlobal::config();
	config->setGroup("");
	QStringList modules = config->readListEntry("Plugins");

	// Session management...
/*
	for(QStringList::ConstIterator i=modules.begin(); i!=modules.end(); ++i)
	{
		KopeteLibraryInfo info=getInfo(*i);
		if (!info.type.contains("sm"))
			continue;
		loadPlugin( *i );
	}
*/
	// load all the protocols in the first
	for(QStringList::ConstIterator i=modules.begin(); i!=modules.end(); ++i)
	{
		KopeteLibraryInfo info=getInfo(*i);
		if( !info.type.contains( QString::fromLatin1( "Kopete/Protocol" ) ) )
			continue;

		if ( !loadPlugin( *i ) )
			kdDebug(14010) << "[LibraryLoader] loading " << (*i) << " failed!" << endl;
	}

	// load all misc plugins
	for(QStringList::ConstIterator i=modules.begin(); i!=modules.end(); ++i)
	{
		KopeteLibraryInfo info=getInfo(*i);
		if( !info.type.contains( QString::fromLatin1( "Kopete/Plugin" ) ) )
			continue;

		if ( !loadPlugin( *i ) )
			kdDebug(14010) << "[LibraryLoader] loading " << (*i) << " failed!" << endl;
	}

	return true;
}

KopeteLibraryInfo LibraryLoader::getInfo(const QString &spec) const
{
	QMap<QString, KopeteLibraryInfo>::iterator cached = m_cachedInfo.find(spec);
	if (cached != m_cachedInfo.end() )
		return *cached;

	KopeteLibraryInfo info;
	QString specPath = ( spec[ 0 ] == '/' ) ? spec : KGlobal::dirs()->findResource( "appdata", spec );
	if( !QFile::exists( specPath ) )
		return info;

	KSimpleConfig file( specPath );
	if( spec.find( '/' ) >= 0 )
		info.specfile = KURL( spec ).fileName();
	else
		info.specfile = spec;

	file.setGroup( QString::fromLatin1( "Desktop Entry" ) );

	info.filename = file.readEntry( "X-KDE-Library" );
	info.author   = file.readEntry( "X-Kopete-Author" );
	info.site     = file.readEntry( "X-Kopete-Site" );
	info.email    = file.readEntry( "X-Kopete-Email" );
	info.type     = file.readEntry( "ServiceTypes" );
	info.name     = file.readEntry( "Name" );
	info.comment  = file.readEntry( "Comment" );
	info.license  = file.readEntry( "X-Kopete-License" );
	info.icon     = file.readEntry( "Icon" );

	m_cachedInfo[ spec ] = info;
	return info;
}

bool LibraryLoader::isLoaded( const QString &spec ) const
{
	KopetePlugin *p = mLibHash[ spec ];
	return p;
}

void LibraryLoader::setModules(const QStringList &mods)
{
	KConfig *config=KGlobal::config();
	config->setGroup("");
	config->writeEntry("Plugins", mods);
	KGlobal::config()->sync();
}

QValueList<KopeteLibraryInfo> LibraryLoader::available() const
{
	QValueList<KopeteLibraryInfo> items;
	QStringList files = KGlobal::dirs()->findAllResources( "appdata", QString::fromLatin1( "*.desktop" ), false, true );
	for( QStringList::Iterator i=files.begin(); i!=files.end(); ++i )
		items.append(getInfo(*i));

	return items;
}

bool LibraryLoader::loadPlugin( const QString &spec )
{
	KopetePlugin *plugin = mLibHash[ spec ];
	if( !plugin )
	{
		KopeteLibraryInfo info = getInfo( spec );
		if( info.specfile != spec )
			return false;

		// Get the library loader instance
		KLibLoader *loader = KLibLoader::self();

		KLibrary *lib = loader->library( QFile::encodeName( info.filename) );
		if( !lib )
		{
			kdDebug(14010) << "LibraryLoader::loadPlugin: Error while loading plugin: " << loader->lastErrorMessage() << endl;
			return false;
		}
		plugin = KParts::ComponentFactory::createInstanceFromFactory<KopetePlugin> ( lib->factory(), this );
		mLibHash.insert( spec, plugin );

		connect( plugin, SIGNAL( destroyed( QObject * ) ),
			SLOT( slotPluginDestroyed( QObject * ) ) );

		// Automatically load the i18n catalogue for the plugin
		KGlobal::locale()->insertCatalogue( info.filename );

		plugin->init();

		m_addressBookFields.insert( plugin, plugin->addressBookFields() );

		kdDebug(14010) << "LibraryLoader::loadPlugin: Successfully loaded plugin '" << spec << "'."<< endl;
		emit pluginLoaded( plugin );
		return true;
	}
	else
	{
		kdDebug(14010) << "LibraryLoader::loadPlugin: Plugin '" << spec << "' is already loaded!" << endl;
		return false;
	}
}

bool LibraryLoader::remove( const QString &spec )
{
	KopetePlugin *plugin = mLibHash[ spec ];
	if( !plugin )
		return false;

	remove( plugin );
	return true;
}

bool LibraryLoader::remove( KopetePlugin *p )
{
	if( !p )
		return false;

	kdDebug(14010) << "LibraryLoader::remove: Removing plugin: " << p->pluginId() << endl;

	// Added by Duncan 20/01/2002
	// We need to call unload function for the plugin
	p->unload();
	delete p;

	return true;
}

void LibraryLoader::slotPluginDestroyed( QObject *o )
{
	m_addressBookFields.remove( static_cast<KopetePlugin *>( o ) );

	QDictIterator<KopetePlugin> it( mLibHash );
	for( ; it.current() ; ++it )
	{
		if( it.current() == o )
		{
			mLibHash.remove( it.currentKey() );
			break;
		}
	}

	// FIXME: Most likely most data structures here leak and are bound
	// to cause crashes. Find and identify those.
}

QStringList LibraryLoader::addressBookFields( KopetePlugin *p ) const
{
	if( m_addressBookFields.contains( p ) )
		return m_addressBookFields[ p ];
	else
		return QStringList();
}

KopetePlugin * LibraryLoader::searchByName(const QString &name)
{
	for( QDictIterator<KopetePlugin> i( mLibHash ); i.current(); ++i )
	{
		if (getInfo(i.currentKey()).name==name)
			return (*i);
	}
	return 0L;
}

KopetePlugin* LibraryLoader::searchByID( const QString &Id )
{
	QValueList<KopeteLibraryInfo> l = loaded();

	for ( QValueList<KopeteLibraryInfo>::Iterator i = l.begin(); i != l.end(); ++i )
	{
		KopetePlugin *tmp_plug = mLibHash[ ( *i ).specfile ];
		if( QString::fromLatin1( tmp_plug->pluginId() ) == Id )
			return tmp_plug;
	}
	return NULL;
}

QString LibraryLoader::pluginName(KopetePlugin *plugin)
{
	for( QDictIterator<KopetePlugin> i( mLibHash ); i.current(); ++i )
	{
		if (i.current() == plugin)
			return getInfo(i.currentKey()).name;
	}
	return QString::fromLatin1( "ERROR plugin unknown" );
}

QString LibraryLoader::pluginIcon( const QString &pluginId ) const
{
	QDictIterator<KopetePlugin> i( mLibHash );
	for( ; i.current(); ++i )
	{
		if( i.currentKey() == pluginId );
			return getInfo( i.currentKey() ).icon;
	}

	return QString::null;
}

#include <pluginloader.moc>

// vim: set noet ts=4 sts=4 sw=4:

<commit_msg>Reverting bad change. Can't find the damn bug :/<commit_after>/*
    pluginloader.cpp - Kopete Plugin Loader

    Copyright (c) 2002      by Duncan Mac-Vicar Prett <duncan@kde.org>
    Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>

    Portions of this code based in Noatun plugin code:
    Copyright (c) 2000-2002 The Noatun Developers

    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>

    *************************************************************************
    *                                                                       *
    * This program is free software; you can redistribute it and/or modify  *
    * it under the terms of the GNU General Public License as published by  *
    * the Free Software Foundation; either version 2 of the License, or     *
    * (at your option) any later version.                                   *
    *                                                                       *
    *************************************************************************
*/

#include "pluginloader.h"

#include <qapplication.h>
#include <qdir.h>
#include <qfile.h>

#include <kdebug.h>
#include <kglobal.h>
#include <klocale.h>
#include <knotifyclient.h>
#include <kparts/componentfactory.h>
#include <ksimpleconfig.h>
#include <kstaticdeleter.h>
#include <kstandarddirs.h>
#include <kurl.h>

#include "kopeteplugin.h"

class KopeteLibraryInfo;

// Put the static deleter in its anonymous namespace
namespace
{
	KStaticDeleter<LibraryLoader> sd;
}

bool operator ==(const KopeteLibraryInfo &a, const KopeteLibraryInfo &b)
{
	// Feels like cheating, doesn't it?
	return a.specfile == b.specfile;
}

LibraryLoader* LibraryLoader::s_pluginLoader = 0L;

LibraryLoader* LibraryLoader::pluginLoader()
{
	if( !s_pluginLoader )
		sd.setObject( s_pluginLoader, new LibraryLoader() );

	return s_pluginLoader;
}

LibraryLoader::LibraryLoader()
: QObject( qApp )
{
}

LibraryLoader::~LibraryLoader()
{
	QDictIterator<KopetePlugin> i( mLibHash );
	while( i.current() )
	{
		// Remove causes the iterator to auto-increment, so
		// only increment explicitly when not removing
		if( getInfo( i.currentKey() ).type != QString::fromLatin1( "Kopete/Protocol" ) )
			remove( i.current() );
		else
			++i;
	}
	i.toFirst();
	while( i.current() )
		remove( i.current() );

	kdDebug(14010) << "LibraryLoader::~LibraryLoader(): all plugins removed" << endl;
}

QPtrList<KopetePlugin> LibraryLoader::plugins() const
{
	QPtrList<KopetePlugin> list;
	QDictIterator<KopetePlugin> i( mLibHash );
	for( ; i.current(); ++i )
		list.append( i.current() );

	return list;
}

QValueList<KopeteLibraryInfo> LibraryLoader::loaded() const
{
	QValueList<KopeteLibraryInfo> items;

	QDictIterator<KopetePlugin> i( mLibHash );
	for( ; i.current(); ++i )
	{
		if( mLibHash[ i.currentKey() ] )
			items.append( getInfo( i.currentKey() ) );
	}

	return items;
}

bool LibraryLoader::loadAll()
{
	KConfig *config=KGlobal::config();
	config->setGroup("");
	QStringList modules = config->readListEntry("Plugins");

	// Session management...
/*
	for(QStringList::ConstIterator i=modules.begin(); i!=modules.end(); ++i)
	{
		KopeteLibraryInfo info=getInfo(*i);
		if (!info.type.contains("sm"))
			continue;
		loadPlugin( *i );
	}
*/
	// load all the protocols in the first
	for(QStringList::ConstIterator i=modules.begin(); i!=modules.end(); ++i)
	{
		KopeteLibraryInfo info=getInfo(*i);
		if( !info.type.contains( QString::fromLatin1( "Kopete/Protocol" ) ) )
			continue;

		if ( !loadPlugin( *i ) )
			kdDebug(14010) << "[LibraryLoader] loading " << (*i) << " failed!" << endl;
	}

	// load all misc plugins
	for(QStringList::ConstIterator i=modules.begin(); i!=modules.end(); ++i)
	{
		KopeteLibraryInfo info=getInfo(*i);
		if( !info.type.contains( QString::fromLatin1( "Kopete/Plugin" ) ) )
			continue;

		if ( !loadPlugin( *i ) )
			kdDebug(14010) << "[LibraryLoader] loading " << (*i) << " failed!" << endl;
	}

	return true;
}

KopeteLibraryInfo LibraryLoader::getInfo(const QString &spec) const
{
	QMap<QString, KopeteLibraryInfo>::iterator cached = m_cachedInfo.find(spec);
	if (cached != m_cachedInfo.end() )
		return *cached;

	KopeteLibraryInfo info;
	QString specPath = ( spec[ 0 ] == '/' ) ? spec : KGlobal::dirs()->findResource( "appdata", spec );
	if( !QFile::exists( specPath ) )
		return info;

	KSimpleConfig file( specPath );
	if( spec.find( '/' ) >= 0 )
		info.specfile = KURL( spec ).fileName();
	else
		info.specfile = spec;

	file.setGroup( QString::fromLatin1( "Desktop Entry" ) );

	info.filename = file.readEntry( "X-KDE-Library" );
	info.author   = file.readEntry( "X-Kopete-Author" );
	info.site     = file.readEntry( "X-Kopete-Site" );
	info.email    = file.readEntry( "X-Kopete-Email" );
	info.type     = file.readEntry( "ServiceTypes" );
	info.name     = file.readEntry( "Name" );
	info.comment  = file.readEntry( "Comment" );
	info.license  = file.readEntry( "X-Kopete-License" );
	info.icon     = file.readEntry( "Icon" );

	m_cachedInfo[ spec ] = info;
	return info;
}

bool LibraryLoader::isLoaded( const QString &spec ) const
{
	KopetePlugin *p = mLibHash[ spec ];
	return p;
}

void LibraryLoader::setModules(const QStringList &mods)
{
	KConfig *config=KGlobal::config();
	config->setGroup("");
	config->writeEntry("Plugins", mods);
	KGlobal::config()->sync();
}

QValueList<KopeteLibraryInfo> LibraryLoader::available() const
{
	QValueList<KopeteLibraryInfo> items;
	QStringList files = KGlobal::dirs()->findAllResources( "appdata", QString::fromLatin1( "*.desktop" ), false, true );
	for( QStringList::Iterator i=files.begin(); i!=files.end(); ++i )
		items.append(getInfo(*i));

	return items;
}

bool LibraryLoader::loadPlugin( const QString &spec )
{
	KopetePlugin *plugin = mLibHash[ spec ];
	if( !plugin )
	{
		KopeteLibraryInfo info = getInfo( spec );
		if( info.specfile != spec )
			return false;

		// Get the library loader instance
		KLibLoader *loader = KLibLoader::self();

		KLibrary *lib = loader->library( QFile::encodeName( info.filename) );
		if( !lib )
		{
			kdDebug(14010) << "LibraryLoader::loadPlugin: Error while loading plugin: " << loader->lastErrorMessage() << endl;
			return false;
		}
		plugin = KParts::ComponentFactory::createInstanceFromFactory<KopetePlugin> ( lib->factory(), this );
		mLibHash.insert( spec, plugin );

		connect( plugin, SIGNAL( destroyed( QObject * ) ),
			SLOT( slotPluginDestroyed( QObject * ) ) );

		// Automatically load the i18n catalogue for the plugin
		KGlobal::locale()->insertCatalogue( info.filename );

		plugin->init();

		m_addressBookFields.insert( plugin, plugin->addressBookFields() );

		kdDebug(14010) << "LibraryLoader::loadPlugin: Successfully loaded plugin '" << spec << "'."<< endl;
		emit pluginLoaded( plugin );
		return true;
	}
	else
	{
		kdDebug(14010) << "LibraryLoader::loadPlugin: Plugin '" << spec << "' is already loaded!" << endl;
		return false;
	}
}

bool LibraryLoader::remove( const QString &spec )
{
	KopetePlugin *plugin = mLibHash[ spec ];
	if( !plugin )
		return false;

	remove( plugin );
	return true;
}

bool LibraryLoader::remove( KopetePlugin *p )
{
	if( !p )
		return false;

	kdDebug(14010) << "LibraryLoader::remove: Removing plugin: " << p->pluginId() << endl;

	// Added by Duncan 20/01/2002
	// We need to call unload function for the plugin
	p->unload();

	delete p;

	return true;
}

void LibraryLoader::slotPluginDestroyed( QObject *o )
{
	m_addressBookFields.remove( static_cast<KopetePlugin *>( o ) );

	QDictIterator<KopetePlugin> it( mLibHash );
	for( ; it.current() ; ++it )
	{
		if( it.current() == o )
		{
			mLibHash.remove( it.currentKey() );
			break;
		}
	}

	// FIXME: Most likely most data structures here leak and are bound
	// to cause crashes. Find and identify those.
}

QStringList LibraryLoader::addressBookFields( KopetePlugin *p ) const
{
	if( m_addressBookFields.contains( p ) )
		return m_addressBookFields[ p ];
	else
		return QStringList();
}

KopetePlugin * LibraryLoader::searchByName(const QString &name)
{
	for( QDictIterator<KopetePlugin> i( mLibHash ); i.current(); ++i )
	{
		if (getInfo(i.currentKey()).name==name)
			return (*i);
	}
	return 0L;
}

KopetePlugin* LibraryLoader::searchByID( const QString &Id )
{
	QValueList<KopeteLibraryInfo> l = loaded();

	for ( QValueList<KopeteLibraryInfo>::Iterator i = l.begin(); i != l.end(); ++i )
	{
		KopetePlugin *tmp_plug = mLibHash[ ( *i ).specfile ];
		if( QString::fromLatin1( tmp_plug->pluginId() ) == Id )
			return tmp_plug;
	}
	return NULL;
}

QString LibraryLoader::pluginName(KopetePlugin *plugin)
{
	for( QDictIterator<KopetePlugin> i( mLibHash ); i.current(); ++i )
	{
		if (i.current() == plugin)
			return getInfo(i.currentKey()).name;
	}
	return QString::fromLatin1( "ERROR plugin unknown" );
}

QString LibraryLoader::pluginIcon( const QString &pluginId ) const
{
	QDictIterator<KopetePlugin> i( mLibHash );
	for( ; i.current(); ++i )
	{
		if( i.currentKey() == pluginId );
			return getInfo( i.currentKey() ).icon;
	}

	return QString::null;
}

#include <pluginloader.moc>

// vim: set noet ts=4 sts=4 sw=4:

<|endoftext|>


<commit_before>#include "calculation_thread.h"

std::vector<CalculationThread::StandardDeck> CalculationThread::GetDecks() {
	QMutexLocker locker(&accessDecks);
	return allDecks;
}

CalculationThread::CalculationThread(const DeckSelectors& selectors) : QThread(),
	deckSelectors(selectors), interrupt(false)
{
}

void CalculationThread::Interrupt() {
	interrupt = true;
}

void CalculationThread::run() {
	StandardDeck deck;
	while(!interrupt) {
		medici::Patience::PatienceInfo info;
		StandardMixer mixer;
		medici::generator::Generate(deck, info, mixer, interrupt, deckSelectors);
		if (!interrupt || deckSelectors(deck)) {
			QMutexLocker locker(&accessDecks);
			allDecks.push_back(deck);
		}
	}
}

<commit_msg>Initializing deck<commit_after>#include "calculation_thread.h"

std::vector<CalculationThread::StandardDeck> CalculationThread::GetDecks() {
	QMutexLocker locker(&accessDecks);
	return allDecks;
}

CalculationThread::CalculationThread(const DeckSelectors& selectors) : QThread(),
	deckSelectors(selectors), interrupt(false)
{
}

void CalculationThread::Interrupt() {
	interrupt = true;
}

void CalculationThread::run() {
	auto deck = StandardDeckType::cards;
	while(!interrupt) {
		medici::Patience::PatienceInfo info;
		StandardMixer mixer;
		medici::generator::Generate(deck, info, mixer, interrupt, deckSelectors);
		if (!interrupt || deckSelectors(deck)) {
			QMutexLocker locker(&accessDecks);
			allDecks.push_back(deck);
		}
	}
}

<|endoftext|>


<commit_before><commit_msg>Fix release build by including windows.h which was removed from a header file.<commit_after><|endoftext|>


<commit_before>// ==========================================================================
//                 SeqAn - The Library for Sequence Analysis
// ==========================================================================
// Copyright (c) 2006-2010, Knut Reinert, FU Berlin
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * 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.
//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
//       its contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 <COPYRIGHT HOLDER> 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.
//
// ==========================================================================
// Author: Manuel Holtgrewe <manuel.holtgrew@fu-berlin.de>
// ==========================================================================
// Tests for the module parallel.
// ==========================================================================

#include <seqan/basic.h>     // Testing infrastructure.
#include <seqan/file.h>      // Required to print strings in tests.
#include <seqan/parallel.h>  // Header under test.

#if defined(_OPENMP)
#include <omp.h>
#endif  // #if defined(_OPENMP)

#include "test_parallel_atomic_primitives.h"
#include "test_parallel_atomic_misc.h"

SEQAN_BEGIN_TESTSUITE(test_parallel) {
#if defined(_OPENMP)
    // Set number of threads to >=2 so there actually is parallelism.
    if (omp_get_max_threads() < 2)
        omp_set_num_threads(2);
#endif  // #if defined(_OPENMP)

    // Tests for atomic primitives.
    SEQAN_CALL_TEST(test_parallel_atomic_inc);
    SEQAN_CALL_TEST(test_parallel_atomic_dec);
    SEQAN_CALL_TEST(test_parallel_atomic_add);
    SEQAN_CALL_TEST(test_parallel_atomic_or);
    SEQAN_CALL_TEST(test_parallel_atomic_xor);
    SEQAN_CALL_TEST(test_parallel_atomic_cas);

    // Tests for misc simpmle atomic operations.
    SEQAN_CALL_TEST(test_parallel_atomic_min);
    SEQAN_CALL_TEST(test_parallel_atomic_max);
}
SEQAN_END_TESTSUITE
<commit_msg>Disabling test_parallel tests in LLVM, broken as of now. There is a TODO to re-enable these tests when this bug is fixed.<commit_after>// ==========================================================================
//                 SeqAn - The Library for Sequence Analysis
// ==========================================================================
// Copyright (c) 2006-2010, Knut Reinert, FU Berlin
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * 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.
//     * Neither the name of Knut Reinert or the FU Berlin nor the names of
//       its contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 <COPYRIGHT HOLDER> 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.
//
// ==========================================================================
// Author: Manuel Holtgrewe <manuel.holtgrew@fu-berlin.de>
// ==========================================================================
// Tests for the module parallel.
// ==========================================================================

#include <seqan/basic.h>     // Testing infrastructure.
#include <seqan/file.h>      // Required to print strings in tests.
#include <seqan/parallel.h>  // Header under test.

#if defined(_OPENMP)
#include <omp.h>
#endif  // #if defined(_OPENMP)

#include "test_parallel_atomic_primitives.h"
#include "test_parallel_atomic_misc.h"

SEQAN_BEGIN_TESTSUITE(test_parallel) {
#if defined(_OPENMP)
    // Set number of threads to >=2 so there actually is parallelism.
    if (omp_get_max_threads() < 2)
        omp_set_num_threads(2);
#endif  // #if defined(_OPENMP)

    // TODO(holtgrew): Re-enable tests on LLVM when bug 9041 is fixed.
    // LLVM has problems with atomic operation builtins, re-enable when
    // this problem is fixed. See http://llvm.org/bugs/show_bug.cgi?id=9041
#ifndef __llvm__
    // Tests for atomic primitives.
    SEQAN_CALL_TEST(test_parallel_atomic_inc);
    SEQAN_CALL_TEST(test_parallel_atomic_dec);
    SEQAN_CALL_TEST(test_parallel_atomic_add);
    SEQAN_CALL_TEST(test_parallel_atomic_or);
    SEQAN_CALL_TEST(test_parallel_atomic_xor);
    SEQAN_CALL_TEST(test_parallel_atomic_cas);

    // Tests for misc simpmle atomic operations.
    SEQAN_CALL_TEST(test_parallel_atomic_min);
    SEQAN_CALL_TEST(test_parallel_atomic_max);
#endif  // #ifndef __llvm__
}
SEQAN_END_TESTSUITE
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2012, Jochen Sprickerhof
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * 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.
 *   * Neither the name of the copyright holder(s) nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "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 THE
 *  COPYRIGHT OWNER 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.
 *
 * $Id$
 *
 */

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/transforms.h>
#include <pcl/registration/lum.h>
#include <pcl/registration/correspondence_estimation.h>

#include <iostream>
#include <string>

#include <vector>

typedef pcl::PointXYZ PointType;
typedef pcl::PointCloud<PointType> Cloud;
typedef Cloud::ConstPtr CloudConstPtr;
typedef Cloud::Ptr CloudPtr;
typedef std::pair<std::string, CloudPtr> CloudPair;
typedef std::vector<CloudPair> CloudVector;

int
main (int argc, char **argv)
{
  pcl::registration::LUM<PointType> lum;
  lum.setMaxIterations (1);
  lum.setConvergenceThreshold (0.001f);

  CloudVector clouds;
  for (int i = 1; i < argc; i++)
  {
    CloudPtr pc (new Cloud);
    pcl::io::loadPCDFile (argv[i], *pc);
    clouds.push_back (CloudPair (argv[i], pc));
    //std::cout << "loading file: " << argv[i] << " size: " << pc->size () << std::endl;
    lum.addPointCloud (clouds[i-1].second);
  }

  for (int i = 0; i < 10; i++)
  {
    for (size_t i = 1; i < clouds.size (); i++)
      for (size_t j = 0; j < i; j++)
      {
        Eigen::Vector4f ci, cj;
        pcl::compute3DCentroid (*(clouds[i].second), ci);
        pcl::compute3DCentroid (*(clouds[j].second), cj);
        Eigen::Vector4f diff = ci - cj;

        //std::cout << i << " " << j << " " << diff.norm () << std::endl;

        if(diff.norm () < 5.0 && (i - j == 1 || i - j > 20))
        {
          if(i - j > 20)
            std::cout << "add connection between " << i << " (" << clouds[i].first << ") and " << j << " (" << clouds[j].first << ")" << std::endl;
          pcl::registration::CorrespondenceEstimation<PointType, PointType> ce;
          ce.setInputTarget (clouds[i].second);
          ce.setInputCloud (clouds[j].second);
          pcl::CorrespondencesPtr corr (new pcl::Correspondences);
          ce.determineCorrespondences (*corr, 2.5f);
          if (corr->size () > 2)
            lum.setCorrespondences (j, i, corr);
        }
      }

    lum.compute ();

    for(int i = 0; i < lum.getNumVertices (); i++)
    {
      //std::cout << i << ": " << lum.getTransformation (i) (0, 3) << " " << lum.getTransformation (i) (1, 3) << " " << lum.getTransformation (i) (2, 3) << std::endl;
      clouds[i].second = lum.getTransformedCloud (i);
    }
  }

  for(int i = 0; i < lum.getNumVertices (); i++)
  {
    std::string result_filename (clouds[i].first);
    result_filename = result_filename.substr (result_filename.rfind ("/") + 1);
    pcl::io::savePCDFileBinary (result_filename.c_str (), *(clouds[i].second));
    //std::cout << "saving result to " << result_filename << std::endl;
  }

  return 0;
}
<commit_msg>Change setInputCloud to setInputSource in lum.cpp<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Point Cloud Library (PCL) - www.pointclouds.org
 *  Copyright (c) 2012, Jochen Sprickerhof
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * 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.
 *   * Neither the name of the copyright holder(s) nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "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 THE
 *  COPYRIGHT OWNER 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.
 *
 * $Id$
 *
 */

#include <pcl/io/pcd_io.h>
#include <pcl/point_types.h>
#include <pcl/common/transforms.h>
#include <pcl/registration/lum.h>
#include <pcl/registration/correspondence_estimation.h>

#include <iostream>
#include <string>

#include <vector>

typedef pcl::PointXYZ PointType;
typedef pcl::PointCloud<PointType> Cloud;
typedef Cloud::ConstPtr CloudConstPtr;
typedef Cloud::Ptr CloudPtr;
typedef std::pair<std::string, CloudPtr> CloudPair;
typedef std::vector<CloudPair> CloudVector;

int
main (int argc, char **argv)
{
  pcl::registration::LUM<PointType> lum;
  lum.setMaxIterations (1);
  lum.setConvergenceThreshold (0.001f);

  CloudVector clouds;
  for (int i = 1; i < argc; i++)
  {
    CloudPtr pc (new Cloud);
    pcl::io::loadPCDFile (argv[i], *pc);
    clouds.push_back (CloudPair (argv[i], pc));
    //std::cout << "loading file: " << argv[i] << " size: " << pc->size () << std::endl;
    lum.addPointCloud (clouds[i-1].second);
  }

  for (int i = 0; i < 10; i++)
  {
    for (size_t i = 1; i < clouds.size (); i++)
      for (size_t j = 0; j < i; j++)
      {
        Eigen::Vector4f ci, cj;
        pcl::compute3DCentroid (*(clouds[i].second), ci);
        pcl::compute3DCentroid (*(clouds[j].second), cj);
        Eigen::Vector4f diff = ci - cj;

        //std::cout << i << " " << j << " " << diff.norm () << std::endl;

        if(diff.norm () < 5.0 && (i - j == 1 || i - j > 20))
        {
          if(i - j > 20)
            std::cout << "add connection between " << i << " (" << clouds[i].first << ") and " << j << " (" << clouds[j].first << ")" << std::endl;
          pcl::registration::CorrespondenceEstimation<PointType, PointType> ce;
          ce.setInputTarget (clouds[i].second);
          ce.setInputSource (clouds[j].second);
          pcl::CorrespondencesPtr corr (new pcl::Correspondences);
          ce.determineCorrespondences (*corr, 2.5f);
          if (corr->size () > 2)
            lum.setCorrespondences (j, i, corr);
        }
      }

    lum.compute ();

    for(int i = 0; i < lum.getNumVertices (); i++)
    {
      //std::cout << i << ": " << lum.getTransformation (i) (0, 3) << " " << lum.getTransformation (i) (1, 3) << " " << lum.getTransformation (i) (2, 3) << std::endl;
      clouds[i].second = lum.getTransformedCloud (i);
    }
  }

  for(int i = 0; i < lum.getNumVertices (); i++)
  {
    std::string result_filename (clouds[i].first);
    result_filename = result_filename.substr (result_filename.rfind ("/") + 1);
    pcl::io::savePCDFileBinary (result_filename.c_str (), *(clouds[i].second));
    //std::cout << "saving result to " << result_filename << std::endl;
  }

  return 0;
}
<|endoftext|>


<commit_before>// Test to make sure basic initialization order errors are caught.

// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t
// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 \
// RUN:    | %symbolize | FileCheck %s
// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t
// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 \
// RUN:     | %symbolize | FileCheck %s

// Do not test with optimization -- the error may be optimized away.

#include <cstdio>

// The structure of the test is:
// "x", "y", "z" are dynamically initialized globals.
// Value of "x" depends on "y", value of "y" depends on "z".
// "x" and "z" are defined in this TU, "y" is defined in another one.
// Thus we shoud stably report initialization order fiasco independently of
// the translation unit order.

int initZ() {
  return 5;
}
int z = initZ();

// 'y' is a dynamically initialized global residing in a different TU.  This
// dynamic initializer will read the value of 'y' before main starts.  The
// result is undefined behavior, which should be caught by initialization order
// checking.
extern int y;
int __attribute__((noinline)) initX() {
  return y + 1;
  // CHECK: {{AddressSanitizer: initialization-order-fiasco}}
  // CHECK: {{READ of size .* at 0x.* thread T0}}
  // CHECK: {{0x.* is located 0 bytes inside of global variable .*(y|z).*}}
}

// This initializer begins our initialization order problems.
static int x = initX();

int main() {
  // ASan should have caused an exit before main runs.
  printf("PASS\n");
  // CHECK-NOT: PASS
  return 0;
}
<commit_msg>[ASan] Mark init-order test as XFAIL on Darwin<commit_after>// Test to make sure basic initialization order errors are caught.

// RUN: %clangxx_asan -m64 -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t
// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 \
// RUN:    | %symbolize | FileCheck %s
// RUN: %clangxx_asan -m32 -O0 %s %p/Helpers/initialization-bug-extra2.cc -o %t
// RUN: ASAN_OPTIONS=check_initialization_order=true %t 2>&1 \
// RUN:     | %symbolize | FileCheck %s

// Do not test with optimization -- the error may be optimized away.

// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=186
// XFAIL: darwin

#include <cstdio>

// The structure of the test is:
// "x", "y", "z" are dynamically initialized globals.
// Value of "x" depends on "y", value of "y" depends on "z".
// "x" and "z" are defined in this TU, "y" is defined in another one.
// Thus we shoud stably report initialization order fiasco independently of
// the translation unit order.

int initZ() {
  return 5;
}
int z = initZ();

// 'y' is a dynamically initialized global residing in a different TU.  This
// dynamic initializer will read the value of 'y' before main starts.  The
// result is undefined behavior, which should be caught by initialization order
// checking.
extern int y;
int __attribute__((noinline)) initX() {
  return y + 1;
  // CHECK: {{AddressSanitizer: initialization-order-fiasco}}
  // CHECK: {{READ of size .* at 0x.* thread T0}}
  // CHECK: {{0x.* is located 0 bytes inside of global variable .*(y|z).*}}
}

// This initializer begins our initialization order problems.
static int x = initX();

int main() {
  // ASan should have caused an exit before main runs.
  printf("PASS\n");
  // CHECK-NOT: PASS
  return 0;
}
<|endoftext|>


<commit_before>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include "common/RhoDefs.h"

#ifdef OS_WINDOWS_DESKTOP

#include "common/RhoPort.h"
#include "RhoThreadImpl.h"

using namespace rho::common;

IMPLEMENT_LOGCLASS(CRhoThreadImpl,"RhoThread");

CRhoThreadImpl::CRhoThreadImpl(): m_Thread(0), m_waitThread(0) {}

CRhoThreadImpl::~CRhoThreadImpl()
{
    if (m_Thread) delete m_Thread;
    if (m_waitThread) delete m_waitThread;
}

void CRhoThreadImpl::start(IRhoRunnable* pRunnable, IRhoRunnable::EPriority ePriority)
{
    if (m_Thread)
        stop(0);
    m_Thread = new QRhoThread(pRunnable);
    m_Thread->start();
    setThreadPriority(ePriority);
}

void CRhoThreadImpl::setThreadPriority(IRhoRunnable::EPriority ePriority)
{
    QThread::Priority nPriority = QThread::NormalPriority;
    if ( ePriority == IRhoRunnable::epHigh )
        nPriority = QThread::HighestPriority;
    else if (ePriority == IRhoRunnable::epLow)
        nPriority = QThread::LowestPriority;
    m_Thread->setPriority(nPriority);
}

void CRhoThreadImpl::stop(unsigned int nTimeoutToKill)
{
    stopWait();
    if ( m_Thread ) {
        m_Thread->quit();
        //m_Thread->wait(nTimeoutToKill);
        if (!m_Thread->isRunning()) {
            m_Thread->terminate();
            m_Thread->wait();
        }
        LOG(INFO) + "Terminate thread.";
        delete m_Thread;
        m_Thread = 0;
    }
}

int CRhoThreadImpl::wait(unsigned int nTimeoutMs)
{
    if (m_waitThread)
        stopWait();
    m_waitThread = new QThread();
    m_waitThread->start();
    bool result = m_waitThread->wait(1000UL*nTimeoutMs) ? 0 : 1;
    delete m_waitThread;
    m_waitThread = 0;
    return result;
}

void CRhoThreadImpl::stopWait()
{
    if (m_waitThread) {
        m_waitThread->terminate(); // quit();
        if (m_waitThread)
            m_waitThread->wait();
    }
}

void CRhoThreadImpl::sleep(unsigned int nTimeout)
{
    QRhoThread::sleep(nTimeout);
}

#endif // OS_WINDOWS_DESKTOP

extern "C" {

void* rho_nativethread_start()
{
    //TODO: rho_nativethread_start
    return 0;
}

void rho_nativethread_end(void* pData)
{
    //TODO: rho_nativethread_end
}

} //extern "C"
<commit_msg>Refactor QT thread code<commit_after>/*------------------------------------------------------------------------
* (The MIT License)
*
* Copyright (c) 2008-2011 Rhomobile, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
* http://rhomobile.com
*------------------------------------------------------------------------*/

#include "common/RhoDefs.h"

#ifdef OS_WINDOWS_DESKTOP

#include "common/RhoPort.h"
#include "RhoThreadImpl.h"

using namespace rho::common;

IMPLEMENT_LOGCLASS(CRhoThreadImpl,"RhoThreadQT");

CRhoThreadImpl::CRhoThreadImpl(): m_Thread(0), m_waitThread(0) {}

CRhoThreadImpl::~CRhoThreadImpl()
{
    if (m_Thread) delete m_Thread;
    if (m_waitThread) delete m_waitThread;
}

void CRhoThreadImpl::start(IRhoRunnable* pRunnable, IRhoRunnable::EPriority ePriority)
{
    LOG(INFO) + "CRhoThreadImpl(QT) start";
    if (m_Thread)
        stop(0);
    m_Thread = new QRhoThread(pRunnable);
    m_Thread->start();
    setThreadPriority(ePriority);
}

void CRhoThreadImpl::setThreadPriority(IRhoRunnable::EPriority ePriority)
{
    QThread::Priority nPriority = QThread::NormalPriority;
    if ( ePriority == IRhoRunnable::epHigh )
        nPriority = QThread::HighestPriority;
    else if (ePriority == IRhoRunnable::epLow)
        nPriority = QThread::LowestPriority;
    m_Thread->setPriority(nPriority);
}

void CRhoThreadImpl::stop(unsigned int nTimeoutToKill)
{
    stopWait();
    if ( m_Thread ) {
        m_Thread->quit();
        //m_Thread->wait(nTimeoutToKill);
        if (!m_Thread->isRunning())
        {
           LOG(INFO) + "Terminate thread and wait after quit";
            m_Thread->terminate();
            m_Thread->wait();
        }
        else
        {
            LOG(INFO) + "Wait after quit";
            m_Thread->wait();
        }
        delete m_Thread;
        m_Thread = 0;
    }
}

int CRhoThreadImpl::wait(unsigned int nTimeoutMs)
{
    bool isVeyBigTimeoutvalue = false;

    if(nTimeoutMs == 4294966296)
	{
		isVeyBigTimeoutvalue = true;
	}
	else if(nTimeoutMs == 4294966295)
	{
		isVeyBigTimeoutvalue = true;
	}

    if (m_waitThread)
        stopWait();

    m_waitThread = new QThread();
    m_waitThread->start();

	bool result;

	if(isVeyBigTimeoutvalue)
	{
	result = m_waitThread->wait(1000UL*nTimeoutMs) ? 0 : 1;
	LOG(INFO) + "CRhoThreadImpl wait for a long time Result:-  "+result;
	}
	else
	{
	result = m_waitThread->wait(1UL*nTimeoutMs) ? 0 : 1;
	LOG(INFO) + "CRhoThreadImpl wait- Result:-  "+result;
	}

    delete m_waitThread;
    m_waitThread = 0;
    LOG(INFO) + "CRhoThreadImpl wait thread deleted";
    return result;
}

void CRhoThreadImpl::stopWait()
{
    QRhoThread::msleep(100);
    LOG(INFO) + "CRhoThreadImpl stopWait after 100 ms sleep";
    if (m_waitThread)
    {
       LOG(INFO) + "CRhoThreadImpl stopWait-Terminate waitthread";
        m_waitThread->terminate(); // quit();
    }
}

void CRhoThreadImpl::sleep(unsigned int nTimeout)
{
    QRhoThread::sleep(nTimeout);
}

#endif // OS_WINDOWS_DESKTOP

extern "C" {

void* rho_nativethread_start()
{
    //TODO: rho_nativethread_start
    return 0;
}

void rho_nativethread_end(void* pData)
{
    //TODO: rho_nativethread_end
}

} //extern "C"
<|endoftext|>


<commit_before>/*!
*	@file	FairingAlgorithm.cpp
*	@brief	Implementation of generic functions for fairing algorithms
*/

#include "FairingAlgorithm.h"
<commit_msg>`FairingAlgorithm`: Added missing constructor<commit_after>/*!
*	@file	FairingAlgorithm.cpp
*	@brief	Implementation of generic functions for fairing algorithms
*/

#include "FairingAlgorithm.h"

namespace psalm
{

/*!
*	Empty constructor
*/

FairingAlgorithm::FairingAlgorithm()
{
}

} // end of namespace "libpsalm"
<|endoftext|>


<commit_before>#include <silicium/observable/bridge.hpp>
#include <silicium/observable/for_each.hpp>
#include <silicium/config.hpp>
#include <silicium/observable/ref.hpp>
#include <silicium/asio/post_forwarder.hpp>
#include <silicium/asio/tcp_acceptor.hpp>
#include <algorithm>
#include <boost/asio/io_service.hpp>
#include <boost/test/unit_test.hpp>

#if !defined(_MSC_VER) && SILICIUM_COMPILER_HAS_AUTO_RETURN_TYPE

BOOST_AUTO_TEST_CASE(asio_post)
{
	boost::asio::io_service io;
	Si::bridge<int> b;
	bool got_element = false;
	auto forwarder = Si::asio::make_post_forwarder(io, Si::ref(b), [&got_element](int element)
	                                               {
		                                               BOOST_REQUIRE(!got_element);
		                                               got_element = true;
		                                               BOOST_CHECK_EQUAL(3, element);
		                                           });
	BOOST_CHECK(!got_element);
	forwarder.start();
	BOOST_CHECK(!got_element);
	b.got_element(3);
	BOOST_CHECK(!got_element);
	io.run();
	BOOST_CHECK(got_element);
}

#endif

BOOST_AUTO_TEST_CASE(asio_make_tcp_acceptor)
{
	// make sure that all overloads still compile
	boost::asio::io_service io;
#if BOOST_VERSION >= 105400
	auto a = Si::asio::make_tcp_acceptor(boost::asio::ip::tcp::acceptor(io));
#endif
	auto b = Si::asio::make_tcp_acceptor(io, boost::asio::ip::tcp::endpoint());
	auto c = Si::asio::make_tcp_acceptor(Si::make_unique<boost::asio::ip::tcp::acceptor>(io));
}

namespace Si
{
	template <class ForegroundDispatcher, class BackgroundDispatcher, class NullaryFunction, class ResultHandler>
	auto async(ForegroundDispatcher &foreground, BackgroundDispatcher &background, NullaryFunction &&work,
	           ResultHandler &&handle_result)
	{
		typedef decltype(work()) result_type;
		typename boost::asio::handler_type<ResultHandler, void(result_type)>::type real_handler(
		    std::forward<ResultHandler>(handle_result));
		typename boost::asio::async_result<decltype(real_handler)> result(real_handler);
		background.post([
			SILICIUM_CAPTURE_EXPRESSION(work, std::forward<NullaryFunction>(work)),
			SILICIUM_CAPTURE_EXPRESSION(real_handler, std::move(real_handler)),
			&foreground
		]() mutable
		                {
			                // unfortunately a post()ed function must be copyable currently, therefore the shared_ptr
			                std::shared_ptr<result_type> result = Si::to_unique(work());
			                foreground.post([
				                SILICIUM_CAPTURE_EXPRESSION(result, std::move(result)),
				                SILICIUM_CAPTURE_EXPRESSION(real_handler, std::move(real_handler))
				            ]() mutable
			                                {
				                                real_handler(std::move(*result));
				                            });
			            });
		return result.get();
	}
}

BOOST_AUTO_TEST_CASE(asio_async)
{
	boost::asio::io_service background;
	boost::asio::io_service foreground;
	bool ok = false;
	Si::async(foreground, background,
	          []
	          {
		          return Si::to_unique(42);
		      },
	          [&ok](std::unique_ptr<int> result)
	          {
		          BOOST_REQUIRE(!ok);
		          BOOST_REQUIRE(result);
		          BOOST_REQUIRE_EQUAL(42, *result);
		          ok = true;
		      });
	BOOST_REQUIRE(!ok);
	foreground.run();
	foreground.reset();
	BOOST_REQUIRE(!ok);
	background.run();
	BOOST_REQUIRE(!ok);
	foreground.run();
	BOOST_CHECK(ok);
}
<commit_msg>add explicit return type to async<commit_after>#include <silicium/observable/bridge.hpp>
#include <silicium/observable/for_each.hpp>
#include <silicium/config.hpp>
#include <silicium/observable/ref.hpp>
#include <silicium/asio/post_forwarder.hpp>
#include <silicium/asio/tcp_acceptor.hpp>
#include <algorithm>
#include <boost/asio/io_service.hpp>
#include <boost/test/unit_test.hpp>

#if !defined(_MSC_VER) && SILICIUM_COMPILER_HAS_AUTO_RETURN_TYPE

BOOST_AUTO_TEST_CASE(asio_post)
{
	boost::asio::io_service io;
	Si::bridge<int> b;
	bool got_element = false;
	auto forwarder = Si::asio::make_post_forwarder(io, Si::ref(b), [&got_element](int element)
	                                               {
		                                               BOOST_REQUIRE(!got_element);
		                                               got_element = true;
		                                               BOOST_CHECK_EQUAL(3, element);
		                                           });
	BOOST_CHECK(!got_element);
	forwarder.start();
	BOOST_CHECK(!got_element);
	b.got_element(3);
	BOOST_CHECK(!got_element);
	io.run();
	BOOST_CHECK(got_element);
}

#endif

BOOST_AUTO_TEST_CASE(asio_make_tcp_acceptor)
{
	// make sure that all overloads still compile
	boost::asio::io_service io;
#if BOOST_VERSION >= 105400
	auto a = Si::asio::make_tcp_acceptor(boost::asio::ip::tcp::acceptor(io));
#endif
	auto b = Si::asio::make_tcp_acceptor(io, boost::asio::ip::tcp::endpoint());
	auto c = Si::asio::make_tcp_acceptor(Si::make_unique<boost::asio::ip::tcp::acceptor>(io));
}

namespace Si
{
	template <class ForegroundDispatcher, class BackgroundDispatcher, class NullaryFunction, class ResultHandler>
	auto async(ForegroundDispatcher &foreground, BackgroundDispatcher &background, NullaryFunction &&work,
	           ResultHandler &&handle_result) ->
	    typename boost::asio::async_result<
	        typename boost::asio::handler_type<ResultHandler, void(decltype(work()))>::type>::type
	{
		typedef decltype(work()) result_type;
		typename boost::asio::handler_type<ResultHandler, void(result_type)>::type real_handler(
		    std::forward<ResultHandler>(handle_result));
		typename boost::asio::async_result<decltype(real_handler)> result(real_handler);
		background.post([
			SILICIUM_CAPTURE_EXPRESSION(work, std::forward<NullaryFunction>(work)),
			SILICIUM_CAPTURE_EXPRESSION(real_handler, std::move(real_handler)),
			&foreground
		]() mutable
		                {
			                // unfortunately a post()ed function must be copyable currently, therefore the shared_ptr
			                std::shared_ptr<result_type> result = Si::to_unique(work());
			                foreground.post([
				                SILICIUM_CAPTURE_EXPRESSION(result, std::move(result)),
				                SILICIUM_CAPTURE_EXPRESSION(real_handler, std::move(real_handler))
				            ]() mutable
			                                {
				                                real_handler(std::move(*result));
				                            });
			            });
		return result.get();
	}
}

BOOST_AUTO_TEST_CASE(asio_async)
{
	boost::asio::io_service background;
	boost::asio::io_service foreground;
	bool ok = false;
	Si::async(foreground, background,
	          []
	          {
		          return Si::to_unique(42);
		      },
	          [&ok](std::unique_ptr<int> result)
	          {
		          BOOST_REQUIRE(!ok);
		          BOOST_REQUIRE(result);
		          BOOST_REQUIRE_EQUAL(42, *result);
		          ok = true;
		      });
	BOOST_REQUIRE(!ok);
	foreground.run();
	foreground.reset();
	BOOST_REQUIRE(!ok);
	background.run();
	BOOST_REQUIRE(!ok);
	foreground.run();
	BOOST_CHECK(ok);
}
<|endoftext|>


<commit_before>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */

#include <db.h>

#include "cursor.hpp"
#include "db.hpp"
#include "db_env.hpp"
#include "db_txn.hpp"
#include "exceptions.hpp"

namespace ftcxx {

    DBC::DBC(const DB &db, const DBTxn &txn, int flags)
        : _txn(),
          _dbc(nullptr)
    {
        if (db.db() != nullptr) {
            DB_TXN *txnp = txn.txn();
            if (txnp == nullptr) {
                _txn = DBTxn(DBEnv(db.db()->dbenv), DB_TXN_READ_ONLY | DB_TXN_SNAPSHOT);
                txnp = _txn.txn();
            }

            ::DBC *c;
            int r = db.db()->cursor(db.db(), txnp, &c, flags);
            handle_ft_retval(r);
            _dbc = c;
        }
    }

    DBC::~DBC() {
        if (_dbc != nullptr) {
            close();
        }
    }

    void DBC::close() {
        int r = _dbc->c_close(_dbc);
        handle_ft_retval(r);
        _dbc = nullptr;
    }

    bool DBC::set_range(const IterationStrategy &strategy, const Bounds &bounds, YDB_CALLBACK_FUNCTION callback, void *extra) const {
        int r = dbc()->c_set_bounds(dbc(), bounds.left_dbt(), bounds.right_dbt(), strategy.prelock, 0);
        handle_ft_retval(r);

        if (strategy.forward) {
            if (bounds.left_infinite()) {
                r = dbc()->c_getf_first(dbc(), strategy.getf_flags(), callback, extra);
            } else {
                r = dbc()->c_getf_set_range(dbc(), strategy.getf_flags(), const_cast<DBT *>(bounds.left_dbt()), callback, extra);
            }
        } else {
            if (bounds.right_infinite()) {
                r = dbc()->c_getf_last(dbc(), strategy.getf_flags(), callback, extra);
            } else {
                r = dbc()->c_getf_set_range_reverse(dbc(), strategy.getf_flags(), const_cast<DBT *>(bounds.right_dbt()), callback, extra);
            }
        }
        if (r == DB_NOTFOUND) {
            return false;
        } else if (r != 0 && r != -1) {
            handle_ft_retval(r);
        }
        return true;
    }

    bool DBC::advance(const IterationStrategy &strategy, YDB_CALLBACK_FUNCTION callback, void *extra) const {
        int r;
        if (strategy.forward) {
            r = dbc()->c_getf_next(dbc(), strategy.getf_flags(), callback, extra);
        } else {
            r = dbc()->c_getf_prev(dbc(), strategy.getf_flags(), callback, extra);
        }
        if (r == DB_NOTFOUND) {
            return false;
        } else if (r != 0 && r != -1) {
            handle_ft_retval(r);
        }
        return true;
    }

} // namespace ftcxx
<commit_msg>Go back to READ_UNCOMMITTED for now<commit_after>/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */

#include <db.h>

#include "cursor.hpp"
#include "db.hpp"
#include "db_env.hpp"
#include "db_txn.hpp"
#include "exceptions.hpp"

namespace ftcxx {

    DBC::DBC(const DB &db, const DBTxn &txn, int flags)
        : _txn(),
          _dbc(nullptr)
    {
        if (db.db() != nullptr) {
            DB_TXN *txnp = txn.txn();
            if (txnp == nullptr) {
                _txn = DBTxn(DBEnv(db.db()->dbenv), DB_TXN_READ_ONLY | DB_READ_UNCOMMITTED);
                txnp = _txn.txn();
            }

            ::DBC *c;
            int r = db.db()->cursor(db.db(), txnp, &c, flags);
            handle_ft_retval(r);
            _dbc = c;
        }
    }

    DBC::~DBC() {
        if (_dbc != nullptr) {
            close();
        }
    }

    void DBC::close() {
        int r = _dbc->c_close(_dbc);
        handle_ft_retval(r);
        _dbc = nullptr;
    }

    bool DBC::set_range(const IterationStrategy &strategy, const Bounds &bounds, YDB_CALLBACK_FUNCTION callback, void *extra) const {
        int r = dbc()->c_set_bounds(dbc(), bounds.left_dbt(), bounds.right_dbt(), strategy.prelock, 0);
        handle_ft_retval(r);

        if (strategy.forward) {
            if (bounds.left_infinite()) {
                r = dbc()->c_getf_first(dbc(), strategy.getf_flags(), callback, extra);
            } else {
                r = dbc()->c_getf_set_range(dbc(), strategy.getf_flags(), const_cast<DBT *>(bounds.left_dbt()), callback, extra);
            }
        } else {
            if (bounds.right_infinite()) {
                r = dbc()->c_getf_last(dbc(), strategy.getf_flags(), callback, extra);
            } else {
                r = dbc()->c_getf_set_range_reverse(dbc(), strategy.getf_flags(), const_cast<DBT *>(bounds.right_dbt()), callback, extra);
            }
        }
        if (r == DB_NOTFOUND) {
            return false;
        } else if (r != 0 && r != -1) {
            handle_ft_retval(r);
        }
        return true;
    }

    bool DBC::advance(const IterationStrategy &strategy, YDB_CALLBACK_FUNCTION callback, void *extra) const {
        int r;
        if (strategy.forward) {
            r = dbc()->c_getf_next(dbc(), strategy.getf_flags(), callback, extra);
        } else {
            r = dbc()->c_getf_prev(dbc(), strategy.getf_flags(), callback, extra);
        }
        if (r == DB_NOTFOUND) {
            return false;
        } else if (r != 0 && r != -1) {
            handle_ft_retval(r);
        }
        return true;
    }

} // namespace ftcxx
<|endoftext|>