<commit_before>//===--- CGBlocks.cpp - Emit LLVM Code for declarations -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code to emit blocks.
//
//===----------------------------------------------------------------------===//

#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "llvm/Module.h"
#include "llvm/Target/TargetData.h"

#include <algorithm>

using namespace clang;
using namespace CodeGen;

enum {
  BLOCK_NEEDS_FREE =        (1 << 24),
  BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
  BLOCK_HAS_CXX_OBJ =       (1 << 26),
  BLOCK_IS_GC =             (1 << 27),
  BLOCK_IS_GLOBAL =         (1 << 28),
  BLOCK_HAS_DESCRIPTOR =    (1 << 29)
};

llvm::Constant *CodeGenFunction::BuildDescriptorBlockDecl() {
  // FIXME: Push up.
  bool BlockHasCopyDispose = false;

  const llvm::PointerType *PtrToInt8Ty
    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
  llvm::Constant *C;
  std::vector<llvm::Constant*> Elts;

  // reserved
  const llvm::IntegerType *LongTy
    = cast<llvm::IntegerType>(
        CGM.getTypes().ConvertType(CGM.getContext().LongTy));
  C = llvm::ConstantInt::get(LongTy, 0);
  Elts.push_back(C);

  // Size
  // FIXME: This should be the size of BlockStructType
  C = llvm::ConstantInt::get(LongTy, 20);
  Elts.push_back(C);

  if (BlockHasCopyDispose) {
    // copy_func_helper_decl
    C = llvm::ConstantInt::get(LongTy, 0);
    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
    Elts.push_back(C);

    // destroy_func_decl
    C = llvm::ConstantInt::get(LongTy, 0);
    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
    Elts.push_back(C);
  }

  C = llvm::ConstantStruct::get(Elts);

  // FIXME: Should be in module?
  static int desc_unique_count;
  char Name[32];
  sprintf(Name, "__block_descriptor_tmp_%d", ++desc_unique_count);
  C = new llvm::GlobalVariable(C->getType(), true,
                               llvm::GlobalValue::InternalLinkage,
                               C, Name, &CGM.getModule());
  return C;
}

llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp() {
  // FIXME: Push up
  bool BlockHasCopyDispose = false;
  bool insideFunction = false;
  bool BlockRefDeclList = false;
  bool BlockByrefDeclList = false;

  std::vector<llvm::Constant*> Elts;
  llvm::Constant *C;

  bool staticBlockTmp = (BlockRefDeclList == 0
                         && BlockByrefDeclList == 0);

  {
    // C = BuildBlockStructInitlist();
    unsigned int flags = BLOCK_HAS_DESCRIPTOR;

    if (BlockHasCopyDispose)
      flags |= BLOCK_HAS_COPY_DISPOSE;

    const llvm::PointerType *PtrToInt8Ty
      = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
    // FIXME: static?  What if we start up a new, unrelated module?
    // logically we want 1 per module.
    static llvm::Constant *NSConcreteGlobalBlock_decl
      = new llvm::GlobalVariable(PtrToInt8Ty, false,
                                 llvm::GlobalValue::ExternalLinkage,
                                 0, "_NSConcreteGlobalBlock",
                                 &CGM.getModule());
    static llvm::Constant *NSConcreteStackBlock_decl
      = new llvm::GlobalVariable(PtrToInt8Ty, false,
                                 llvm::GlobalValue::ExternalLinkage,
                                 0, "_NSConcreteStackBlock",
                                 &CGM.getModule());
    C = NSConcreteStackBlock_decl;
    if (!insideFunction ||
        (!BlockRefDeclList && !BlockByrefDeclList)) {
      C = NSConcreteGlobalBlock_decl;
      flags |= BLOCK_IS_GLOBAL;
    }
    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
    Elts.push_back(C);

    // __flags
    const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
      CGM.getTypes().ConvertType(CGM.getContext().IntTy));
    C = llvm::ConstantInt::get(IntTy, flags);
    Elts.push_back(C);

    // __reserved
    C = llvm::ConstantInt::get(IntTy, 0);
    Elts.push_back(C);

    // __FuncPtr
    // FIXME: Build this up.
    Elts.push_back(C);

    // __descriptor
    Elts.push_back(BuildDescriptorBlockDecl());

    // FIXME: Add block_original_ref_decl_list and block_byref_decl_list.
  }

  C = llvm::ConstantStruct::get(Elts);

  char Name[32];
  // FIXME: Boost in CGM?
  static int global_unique_count;
  sprintf(Name, "__block_holder_tmp_%d", ++global_unique_count);
  C = new llvm::GlobalVariable(C->getType(), true,
                               llvm::GlobalValue::InternalLinkage,
                               C, Name, &CGM.getModule());
  return C;
}

const llvm::Type *CodeGenModule::getBlockDescriptorType() {
  if (BlockDescriptorType)
    return BlockDescriptorType;

  const llvm::Type *UnsignedLongTy =
    getTypes().ConvertType(getContext().UnsignedLongTy);

  // struct __block_descriptor {
  //   unsigned long reserved;
  //   unsigned long block_size;
  // };
  BlockDescriptorType = llvm::StructType::get(UnsignedLongTy,
                                              UnsignedLongTy,
                                              NULL);

  getModule().addTypeName("struct.__block_descriptor",
                          BlockDescriptorType);

  return BlockDescriptorType;
}

const llvm::Type *
CodeGenModule::getGenericBlockLiteralType() {
  if (GenericBlockLiteralType)
    return GenericBlockLiteralType;

  const llvm::Type *Int8PtrTy =
    llvm::PointerType::getUnqual(llvm::Type::Int8Ty);

  const llvm::Type *BlockDescPtrTy =
    llvm::PointerType::getUnqual(getBlockDescriptorType());

  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
    getTypes().ConvertType(getContext().IntTy));

  // struct __block_literal_generic {
  //   void *isa;
  //   int flags;
  //   int reserved;
  //   void (*invoke)(void *);
  //   struct __block_descriptor *descriptor;
  // };
  GenericBlockLiteralType = llvm::StructType::get(Int8PtrTy,
                                                  IntTy,
                                                  IntTy,
                                                  Int8PtrTy,
                                                  BlockDescPtrTy,
                                                  NULL);

  getModule().addTypeName("struct.__block_literal_generic",
                          GenericBlockLiteralType);

  return GenericBlockLiteralType;
}

/// getBlockFunctionType - Given a BlockPointerType, will return the
/// function type for the block, including the first block literal argument.
static QualType getBlockFunctionType(ASTContext &Ctx,
                                     const BlockPointerType *BPT) {
  const FunctionTypeProto *FTy = cast<FunctionTypeProto>(BPT->getPointeeType());

  llvm::SmallVector<QualType, 8> Types;
  Types.push_back(Ctx.getPointerType(Ctx.VoidTy));

  for (FunctionTypeProto::arg_type_iterator i = FTy->arg_type_begin(),
       e = FTy->arg_type_end(); i != e; ++i)
    Types.push_back(*i);

  return Ctx.getFunctionType(FTy->getResultType(),
                             &Types[0], Types.size(),
                             FTy->isVariadic(), 0);
}

RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) {
  const BlockPointerType *BPT =
    E->getCallee()->getType()->getAsBlockPointerType();

  llvm::Value *Callee = EmitScalarExpr(E->getCallee());

  // Get a pointer to the generic block literal.
  const llvm::Type *BlockLiteralTy =
    llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType());

  // Bitcast the callee to a block literal.
  llvm::Value *BlockLiteral =
    Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal");

  // Get the function pointer from the literal.
  llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp");
  llvm::Value *Func = Builder.CreateLoad(FuncPtr, FuncPtr, "tmp");

  // Cast the function pointer to the right type.
  const llvm::Type *BlockFTy =
    ConvertType(getBlockFunctionType(getContext(), BPT));
  const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
  Func = Builder.CreateBitCast(Func, BlockFTyPtr);

  BlockLiteral =
    Builder.CreateBitCast(BlockLiteral,
                          llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
                          "tmp");

  // Add the block literal.
  QualType VoidPtrTy = getContext().getPointerType(getContext().VoidTy);
  CallArgList Args;
  Args.push_back(std::make_pair(RValue::get(BlockLiteral), VoidPtrTy));

  // And the rest of the arguments.
  for (CallExpr::const_arg_iterator i = E->arg_begin(), e = E->arg_end();
       i != e; ++i)
    Args.push_back(std::make_pair(EmitAnyExprToTemp(*i),
                                  i->getType()));

  // And call the block.
  return EmitCall(CGM.getTypes().getFunctionInfo(E->getType(), Args),
                  Func, Args);
}

llvm::Constant *CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE) {
  if (!NSConcreteGlobalBlock) {
    const llvm::Type *Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);

    // FIXME: Wee should have a CodeGenModule::AddRuntimeVariable that does the
    // same thing as CreateRuntimeFunction if there's already a variable with
    // the same name.
    NSConcreteGlobalBlock =
      new llvm::GlobalVariable(Ty, false,
                              llvm::GlobalVariable::ExternalLinkage, 0,
                              "_NSConcreteGlobalBlock", &getModule());
  }

  // Generate the block descriptor.
  const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy);
  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
    getTypes().ConvertType(getContext().IntTy));

  llvm::Constant *DescriptorFields[2];

  // Reserved
  DescriptorFields[0] = llvm::Constant::getNullValue(UnsignedLongTy);

  // Block literal size. For global blocks we just use the size of the generic
  // block literal struct.
  uint64_t BlockLiteralSize =
    TheTargetData.getTypeStoreSizeInBits(getGenericBlockLiteralType()) / 8;
  DescriptorFields[1] = llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize);

  llvm::Constant *DescriptorStruct =
    llvm::ConstantStruct::get(&DescriptorFields[0], 2);

  llvm::GlobalVariable *Descriptor =
    new llvm::GlobalVariable(DescriptorStruct->getType(), true,
                             llvm::GlobalVariable::InternalLinkage,
                             DescriptorStruct, "__block_descriptor_global",
                             &getModule());

  // Generate the constants for the block literal.
  llvm::Constant *LiteralFields[5];

  CodeGenFunction::BlockInfo Info(0, "global");
  llvm::Function *Fn = CodeGenFunction(*this).GenerateBlockFunction(BE, Info);

  // isa
  LiteralFields[0] = NSConcreteGlobalBlock;

  // Flags
  LiteralFields[1] = llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL);

  // Reserved
  LiteralFields[2] = llvm::Constant::getNullValue(IntTy);

  // Function
  LiteralFields[3] = Fn;

  // Descriptor
  LiteralFields[4] = Descriptor;

  llvm::Constant *BlockLiteralStruct =
    llvm::ConstantStruct::get(&LiteralFields[0], 5);

  llvm::GlobalVariable *BlockLiteral =
    new llvm::GlobalVariable(BlockLiteralStruct->getType(), true,
                             llvm::GlobalVariable::InternalLinkage,
                             BlockLiteralStruct, "__block_literal_global",
                             &getModule());

  return BlockLiteral;
}

llvm::Function *CodeGenFunction::GenerateBlockFunction(const BlockExpr *Expr,
                                                       const BlockInfo& Info)
{
  const FunctionTypeProto *FTy =
    cast<FunctionTypeProto>(Expr->getFunctionType());

  FunctionArgList Args;

  const BlockDecl *BD = Expr->getBlockDecl();

  // FIXME: This leaks
  ImplicitParamDecl *SelfDecl =
    ImplicitParamDecl::Create(getContext(), 0,
                              SourceLocation(), 0,
                              getContext().getPointerType(getContext().VoidTy));

  Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType()));

  for (BlockDecl::param_iterator i = BD->param_begin(),
       e = BD->param_end(); i != e; ++i)
    Args.push_back(std::make_pair(*e, (*e)->getType()));

  const CGFunctionInfo &FI =
    CGM.getTypes().getFunctionInfo(FTy->getResultType(), Args);

  std::string Name = std::string("__block_function_") + Info.NameSuffix;

  CodeGenTypes &Types = CGM.getTypes();
  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, FTy->isVariadic());

  llvm::Function *Fn =
    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
                           Name,
                           &CGM.getModule());

  StartFunction(BD, FTy->getResultType(), Fn, Args,
                Expr->getBody()->getLocEnd());
  EmitStmt(Expr->getBody());
  FinishFunction(cast<CompoundStmt>(Expr->getBody())->getRBracLoc());

  return Fn;
}
<commit_msg>Size should be unsigned.<commit_after>//===--- CGBlocks.cpp - Emit LLVM Code for declarations -------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This contains code to emit blocks.
//
//===----------------------------------------------------------------------===//

#include "CodeGenFunction.h"
#include "CodeGenModule.h"
#include "llvm/Module.h"
#include "llvm/Target/TargetData.h"

#include <algorithm>

using namespace clang;
using namespace CodeGen;

enum {
  BLOCK_NEEDS_FREE =        (1 << 24),
  BLOCK_HAS_COPY_DISPOSE =  (1 << 25),
  BLOCK_HAS_CXX_OBJ =       (1 << 26),
  BLOCK_IS_GC =             (1 << 27),
  BLOCK_IS_GLOBAL =         (1 << 28),
  BLOCK_HAS_DESCRIPTOR =    (1 << 29)
};

llvm::Constant *CodeGenFunction::BuildDescriptorBlockDecl() {
  // FIXME: Push up.
  bool BlockHasCopyDispose = false;

  const llvm::PointerType *PtrToInt8Ty
    = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
  const llvm::Type *UnsignedLongTy
    = CGM.getTypes().ConvertType(getContext().UnsignedLongTy);
  llvm::Constant *C;
  std::vector<llvm::Constant*> Elts;

  // reserved
  C = llvm::ConstantInt::get(UnsignedLongTy, 0);
  Elts.push_back(C);

  // Size
  // FIXME: This should be the size of BlockStructType
  C = llvm::ConstantInt::get(UnsignedLongTy, 20);
  Elts.push_back(C);

  if (BlockHasCopyDispose) {
    // copy_func_helper_decl
    C = llvm::ConstantInt::get(UnsignedLongTy, 0);
    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
    Elts.push_back(C);

    // destroy_func_decl
    C = llvm::ConstantInt::get(UnsignedLongTy, 0);
    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
    Elts.push_back(C);
  }

  C = llvm::ConstantStruct::get(Elts);

  // FIXME: Should be in module?
  static int desc_unique_count;
  char Name[32];
  sprintf(Name, "__block_descriptor_tmp_%d", ++desc_unique_count);
  C = new llvm::GlobalVariable(C->getType(), true,
                               llvm::GlobalValue::InternalLinkage,
                               C, Name, &CGM.getModule());
  return C;
}

llvm::Constant *CodeGenFunction::BuildBlockLiteralTmp() {
  // FIXME: Push up
  bool BlockHasCopyDispose = false;
  bool insideFunction = false;
  bool BlockRefDeclList = false;
  bool BlockByrefDeclList = false;

  std::vector<llvm::Constant*> Elts;
  llvm::Constant *C;

  bool staticBlockTmp = (BlockRefDeclList == 0
                         && BlockByrefDeclList == 0);

  {
    // C = BuildBlockStructInitlist();
    unsigned int flags = BLOCK_HAS_DESCRIPTOR;

    if (BlockHasCopyDispose)
      flags |= BLOCK_HAS_COPY_DISPOSE;

    const llvm::PointerType *PtrToInt8Ty
      = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);
    // FIXME: static?  What if we start up a new, unrelated module?
    // logically we want 1 per module.
    static llvm::Constant *NSConcreteGlobalBlock_decl
      = new llvm::GlobalVariable(PtrToInt8Ty, false,
                                 llvm::GlobalValue::ExternalLinkage,
                                 0, "_NSConcreteGlobalBlock",
                                 &CGM.getModule());
    static llvm::Constant *NSConcreteStackBlock_decl
      = new llvm::GlobalVariable(PtrToInt8Ty, false,
                                 llvm::GlobalValue::ExternalLinkage,
                                 0, "_NSConcreteStackBlock",
                                 &CGM.getModule());
    C = NSConcreteStackBlock_decl;
    if (!insideFunction ||
        (!BlockRefDeclList && !BlockByrefDeclList)) {
      C = NSConcreteGlobalBlock_decl;
      flags |= BLOCK_IS_GLOBAL;
    }
    C = llvm::ConstantExpr::getBitCast(C, PtrToInt8Ty);
    Elts.push_back(C);

    // __flags
    const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
      CGM.getTypes().ConvertType(CGM.getContext().IntTy));
    C = llvm::ConstantInt::get(IntTy, flags);
    Elts.push_back(C);

    // __reserved
    C = llvm::ConstantInt::get(IntTy, 0);
    Elts.push_back(C);

    // __FuncPtr
    // FIXME: Build this up.
    Elts.push_back(C);

    // __descriptor
    Elts.push_back(BuildDescriptorBlockDecl());

    // FIXME: Add block_original_ref_decl_list and block_byref_decl_list.
  }

  C = llvm::ConstantStruct::get(Elts);

  char Name[32];
  // FIXME: Boost in CGM?
  static int global_unique_count;
  sprintf(Name, "__block_holder_tmp_%d", ++global_unique_count);
  C = new llvm::GlobalVariable(C->getType(), true,
                               llvm::GlobalValue::InternalLinkage,
                               C, Name, &CGM.getModule());
  return C;
}

const llvm::Type *CodeGenModule::getBlockDescriptorType() {
  if (BlockDescriptorType)
    return BlockDescriptorType;

  const llvm::Type *UnsignedLongTy =
    getTypes().ConvertType(getContext().UnsignedLongTy);

  // struct __block_descriptor {
  //   unsigned long reserved;
  //   unsigned long block_size;
  // };
  BlockDescriptorType = llvm::StructType::get(UnsignedLongTy,
                                              UnsignedLongTy,
                                              NULL);

  getModule().addTypeName("struct.__block_descriptor",
                          BlockDescriptorType);

  return BlockDescriptorType;
}

const llvm::Type *
CodeGenModule::getGenericBlockLiteralType() {
  if (GenericBlockLiteralType)
    return GenericBlockLiteralType;

  const llvm::Type *Int8PtrTy =
    llvm::PointerType::getUnqual(llvm::Type::Int8Ty);

  const llvm::Type *BlockDescPtrTy =
    llvm::PointerType::getUnqual(getBlockDescriptorType());

  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
    getTypes().ConvertType(getContext().IntTy));

  // struct __block_literal_generic {
  //   void *isa;
  //   int flags;
  //   int reserved;
  //   void (*invoke)(void *);
  //   struct __block_descriptor *descriptor;
  // };
  GenericBlockLiteralType = llvm::StructType::get(Int8PtrTy,
                                                  IntTy,
                                                  IntTy,
                                                  Int8PtrTy,
                                                  BlockDescPtrTy,
                                                  NULL);

  getModule().addTypeName("struct.__block_literal_generic",
                          GenericBlockLiteralType);

  return GenericBlockLiteralType;
}

/// getBlockFunctionType - Given a BlockPointerType, will return the
/// function type for the block, including the first block literal argument.
static QualType getBlockFunctionType(ASTContext &Ctx,
                                     const BlockPointerType *BPT) {
  const FunctionTypeProto *FTy = cast<FunctionTypeProto>(BPT->getPointeeType());

  llvm::SmallVector<QualType, 8> Types;
  Types.push_back(Ctx.getPointerType(Ctx.VoidTy));

  for (FunctionTypeProto::arg_type_iterator i = FTy->arg_type_begin(),
       e = FTy->arg_type_end(); i != e; ++i)
    Types.push_back(*i);

  return Ctx.getFunctionType(FTy->getResultType(),
                             &Types[0], Types.size(),
                             FTy->isVariadic(), 0);
}

RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr* E) {
  const BlockPointerType *BPT =
    E->getCallee()->getType()->getAsBlockPointerType();

  llvm::Value *Callee = EmitScalarExpr(E->getCallee());

  // Get a pointer to the generic block literal.
  const llvm::Type *BlockLiteralTy =
    llvm::PointerType::getUnqual(CGM.getGenericBlockLiteralType());

  // Bitcast the callee to a block literal.
  llvm::Value *BlockLiteral =
    Builder.CreateBitCast(Callee, BlockLiteralTy, "block.literal");

  // Get the function pointer from the literal.
  llvm::Value *FuncPtr = Builder.CreateStructGEP(BlockLiteral, 3, "tmp");
  llvm::Value *Func = Builder.CreateLoad(FuncPtr, FuncPtr, "tmp");

  // Cast the function pointer to the right type.
  const llvm::Type *BlockFTy =
    ConvertType(getBlockFunctionType(getContext(), BPT));
  const llvm::Type *BlockFTyPtr = llvm::PointerType::getUnqual(BlockFTy);
  Func = Builder.CreateBitCast(Func, BlockFTyPtr);

  BlockLiteral =
    Builder.CreateBitCast(BlockLiteral,
                          llvm::PointerType::getUnqual(llvm::Type::Int8Ty),
                          "tmp");

  // Add the block literal.
  QualType VoidPtrTy = getContext().getPointerType(getContext().VoidTy);
  CallArgList Args;
  Args.push_back(std::make_pair(RValue::get(BlockLiteral), VoidPtrTy));

  // And the rest of the arguments.
  for (CallExpr::const_arg_iterator i = E->arg_begin(), e = E->arg_end();
       i != e; ++i)
    Args.push_back(std::make_pair(EmitAnyExprToTemp(*i),
                                  i->getType()));

  // And call the block.
  return EmitCall(CGM.getTypes().getFunctionInfo(E->getType(), Args),
                  Func, Args);
}

llvm::Constant *CodeGenModule::GetAddrOfGlobalBlock(const BlockExpr *BE) {
  if (!NSConcreteGlobalBlock) {
    const llvm::Type *Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty);

    // FIXME: Wee should have a CodeGenModule::AddRuntimeVariable that does the
    // same thing as CreateRuntimeFunction if there's already a variable with
    // the same name.
    NSConcreteGlobalBlock =
      new llvm::GlobalVariable(Ty, false,
                              llvm::GlobalVariable::ExternalLinkage, 0,
                              "_NSConcreteGlobalBlock", &getModule());
  }

  // Generate the block descriptor.
  const llvm::Type *UnsignedLongTy = Types.ConvertType(Context.UnsignedLongTy);
  const llvm::IntegerType *IntTy = cast<llvm::IntegerType>(
    getTypes().ConvertType(getContext().IntTy));

  llvm::Constant *DescriptorFields[2];

  // Reserved
  DescriptorFields[0] = llvm::Constant::getNullValue(UnsignedLongTy);

  // Block literal size. For global blocks we just use the size of the generic
  // block literal struct.
  uint64_t BlockLiteralSize =
    TheTargetData.getTypeStoreSizeInBits(getGenericBlockLiteralType()) / 8;
  DescriptorFields[1] = llvm::ConstantInt::get(UnsignedLongTy,BlockLiteralSize);

  llvm::Constant *DescriptorStruct =
    llvm::ConstantStruct::get(&DescriptorFields[0], 2);

  llvm::GlobalVariable *Descriptor =
    new llvm::GlobalVariable(DescriptorStruct->getType(), true,
                             llvm::GlobalVariable::InternalLinkage,
                             DescriptorStruct, "__block_descriptor_global",
                             &getModule());

  // Generate the constants for the block literal.
  llvm::Constant *LiteralFields[5];

  CodeGenFunction::BlockInfo Info(0, "global");
  llvm::Function *Fn = CodeGenFunction(*this).GenerateBlockFunction(BE, Info);

  // isa
  LiteralFields[0] = NSConcreteGlobalBlock;

  // Flags
  LiteralFields[1] = llvm::ConstantInt::get(IntTy, BLOCK_IS_GLOBAL);

  // Reserved
  LiteralFields[2] = llvm::Constant::getNullValue(IntTy);

  // Function
  LiteralFields[3] = Fn;

  // Descriptor
  LiteralFields[4] = Descriptor;

  llvm::Constant *BlockLiteralStruct =
    llvm::ConstantStruct::get(&LiteralFields[0], 5);

  llvm::GlobalVariable *BlockLiteral =
    new llvm::GlobalVariable(BlockLiteralStruct->getType(), true,
                             llvm::GlobalVariable::InternalLinkage,
                             BlockLiteralStruct, "__block_literal_global",
                             &getModule());

  return BlockLiteral;
}

llvm::Function *CodeGenFunction::GenerateBlockFunction(const BlockExpr *Expr,
                                                       const BlockInfo& Info)
{
  const FunctionTypeProto *FTy =
    cast<FunctionTypeProto>(Expr->getFunctionType());

  FunctionArgList Args;

  const BlockDecl *BD = Expr->getBlockDecl();

  // FIXME: This leaks
  ImplicitParamDecl *SelfDecl =
    ImplicitParamDecl::Create(getContext(), 0,
                              SourceLocation(), 0,
                              getContext().getPointerType(getContext().VoidTy));

  Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType()));

  for (BlockDecl::param_iterator i = BD->param_begin(),
       e = BD->param_end(); i != e; ++i)
    Args.push_back(std::make_pair(*e, (*e)->getType()));

  const CGFunctionInfo &FI =
    CGM.getTypes().getFunctionInfo(FTy->getResultType(), Args);

  std::string Name = std::string("__block_function_") + Info.NameSuffix;

  CodeGenTypes &Types = CGM.getTypes();
  const llvm::FunctionType *LTy = Types.GetFunctionType(FI, FTy->isVariadic());

  llvm::Function *Fn =
    llvm::Function::Create(LTy, llvm::GlobalValue::InternalLinkage,
                           Name,
                           &CGM.getModule());

  StartFunction(BD, FTy->getResultType(), Fn, Args,
                Expr->getBody()->getLocEnd());
  EmitStmt(Expr->getBody());
  FinishFunction(cast<CompoundStmt>(Expr->getBody())->getRBracLoc());

  return Fn;
}
<|endoftext|>


<commit_before><commit_msg>Remove a hack that's no longer needed. Review URL: http://codereview.chromium.org/79050<commit_after><|endoftext|>


<commit_before>//===-- InstrinsicInst.cpp - Intrinsic Instruction Wrappers ---------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements methods that make it really easy to deal with intrinsic
// functions.
//
// All intrinsic function calls are instances of the call instruction, so these
// are all subclasses of the CallInst class.  Note that none of these classes
// has state or virtual methods, which is an important part of this gross/neat
// hack working.
//
// In some cases, arguments to intrinsics need to be generic and are defined as
// type pointer to empty struct { }*.  To access the real item of interest the
// cast instruction needs to be stripped away.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Operator.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

//===----------------------------------------------------------------------===//
/// DbgVariableIntrinsic - This is the common base class for debug info
/// intrinsics for variables.
///

Value *DbgVariableIntrinsic::getVariableLocation(bool AllowNullOp) const {
  Value *Op = getArgOperand(0);
  if (AllowNullOp && !Op)
    return nullptr;

  auto *MD = cast<MetadataAsValue>(Op)->getMetadata();
  if (auto *V = dyn_cast<ValueAsMetadata>(MD))
    return V->getValue();

  // When the value goes to null, it gets replaced by an empty MDNode.
  assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
  return nullptr;
}

Optional<uint64_t> DbgVariableIntrinsic::getFragmentSizeInBits() const {
  if (auto Fragment = getExpression()->getFragmentInfo())
    return Fragment->SizeInBits;
  return getVariable()->getSizeInBits();
}

int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
                                               StringRef Name) {
  assert(Name.startswith("llvm."));

  // Do successive binary searches of the dotted name components. For
  // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
  // intrinsics starting with "llvm.gc", then "llvm.gc.experimental", then
  // "llvm.gc.experimental.statepoint", and then we will stop as the range is
  // size 1. During the search, we can skip the prefix that we already know is
  // identical. By using strncmp we consider names with differing suffixes to
  // be part of the equal range.
  size_t CmpStart = 0;
  size_t CmpEnd = 4; // Skip the "llvm" component.
  const char *const *Low = NameTable.begin();
  const char *const *High = NameTable.end();
  const char *const *LastLow = Low;
  while (CmpEnd < Name.size() && High - Low > 0) {
    CmpStart = CmpEnd;
    CmpEnd = Name.find('.', CmpStart + 1);
    CmpEnd = CmpEnd == StringRef::npos ? Name.size() : CmpEnd;
    auto Cmp = [CmpStart, CmpEnd](const char *LHS, const char *RHS) {
      return strncmp(LHS + CmpStart, RHS + CmpStart, CmpEnd - CmpStart) < 0;
    };
    LastLow = Low;
    std::tie(Low, High) = std::equal_range(Low, High, Name.data(), Cmp);
  }
  if (High - Low > 0)
    LastLow = Low;

  if (LastLow == NameTable.end())
    return -1;
  StringRef NameFound = *LastLow;
  if (Name == NameFound ||
      (Name.startswith(NameFound) && Name[NameFound.size()] == '.'))
    return LastLow - NameTable.begin();
  return -1;
}

Value *InstrProfIncrementInst::getStep() const {
  if (InstrProfIncrementInstStep::classof(this)) {
    return const_cast<Value *>(getArgOperand(4));
  }
  const Module *M = getModule();
  LLVMContext &Context = M->getContext();
  return ConstantInt::get(Type::getInt64Ty(Context), 1);
}

Optional<ConstrainedFPIntrinsic::RoundingMode>
ConstrainedFPIntrinsic::getRoundingMode() const {
  unsigned NumOperands = getNumArgOperands();
  Metadata *MD =
      cast<MetadataAsValue>(getArgOperand(NumOperands - 2))->getMetadata();
  if (!MD || !isa<MDString>(MD))
    return None;
  return StrToRoundingMode(cast<MDString>(MD)->getString());
}

Optional<ConstrainedFPIntrinsic::RoundingMode>
ConstrainedFPIntrinsic::StrToRoundingMode(StringRef RoundingArg) {
  // For dynamic rounding mode, we use round to nearest but we will set the
  // 'exact' SDNodeFlag so that the value will not be rounded.
  return StringSwitch<Optional<RoundingMode>>(RoundingArg)
    .Case("round.dynamic",    rmDynamic)
    .Case("round.tonearest",  rmToNearest)
    .Case("round.downward",   rmDownward)
    .Case("round.upward",     rmUpward)
    .Case("round.towardzero", rmTowardZero)
    .Default(None);
}

Optional<StringRef>
ConstrainedFPIntrinsic::RoundingModeToStr(RoundingMode UseRounding) {
  Optional<StringRef> RoundingStr = None;
  switch (UseRounding) {
  case ConstrainedFPIntrinsic::rmDynamic:
    RoundingStr = "round.dynamic";
    break;
  case ConstrainedFPIntrinsic::rmToNearest:
    RoundingStr = "round.tonearest";
    break;
  case ConstrainedFPIntrinsic::rmDownward:
    RoundingStr = "round.downward";
    break;
  case ConstrainedFPIntrinsic::rmUpward:
    RoundingStr = "round.upward";
    break;
  case ConstrainedFPIntrinsic::rmTowardZero:
    RoundingStr = "round.towardzero";
    break;
  }
  return RoundingStr;
}

Optional<ConstrainedFPIntrinsic::ExceptionBehavior>
ConstrainedFPIntrinsic::getExceptionBehavior() const {
  unsigned NumOperands = getNumArgOperands();
  Metadata *MD =
      cast<MetadataAsValue>(getArgOperand(NumOperands - 1))->getMetadata();
  if (!MD || !isa<MDString>(MD))
    return None;
  return StrToExceptionBehavior(cast<MDString>(MD)->getString());
}

Optional<ConstrainedFPIntrinsic::ExceptionBehavior>
ConstrainedFPIntrinsic::StrToExceptionBehavior(StringRef ExceptionArg) {
  return StringSwitch<Optional<ExceptionBehavior>>(ExceptionArg)
    .Case("fpexcept.ignore",  ebIgnore)
    .Case("fpexcept.maytrap", ebMayTrap)
    .Case("fpexcept.strict",  ebStrict)
    .Default(None);
}

Optional<StringRef>
ConstrainedFPIntrinsic::ExceptionBehaviorToStr(ExceptionBehavior UseExcept) {
  Optional<StringRef> ExceptStr = None;
  switch (UseExcept) {
  case ConstrainedFPIntrinsic::ebStrict:
    ExceptStr = "fpexcept.strict";
    break;
  case ConstrainedFPIntrinsic::ebIgnore:
    ExceptStr = "fpexcept.ignore";
    break;
  case ConstrainedFPIntrinsic::ebMayTrap:
    ExceptStr = "fpexcept.maytrap";
    break;
  }
  return ExceptStr;
}

bool ConstrainedFPIntrinsic::isUnaryOp() const {
  switch (getIntrinsicID()) {
    default:
      return false;
    case Intrinsic::experimental_constrained_fptosi:
    case Intrinsic::experimental_constrained_fptoui:
    case Intrinsic::experimental_constrained_fptrunc:
    case Intrinsic::experimental_constrained_fpext:
    case Intrinsic::experimental_constrained_sqrt:
    case Intrinsic::experimental_constrained_sin:
    case Intrinsic::experimental_constrained_cos:
    case Intrinsic::experimental_constrained_exp:
    case Intrinsic::experimental_constrained_exp2:
    case Intrinsic::experimental_constrained_log:
    case Intrinsic::experimental_constrained_log10:
    case Intrinsic::experimental_constrained_log2:
    case Intrinsic::experimental_constrained_rint:
    case Intrinsic::experimental_constrained_nearbyint:
    case Intrinsic::experimental_constrained_ceil:
    case Intrinsic::experimental_constrained_floor:
    case Intrinsic::experimental_constrained_round:
    case Intrinsic::experimental_constrained_trunc:
      return true;
  }
}

bool ConstrainedFPIntrinsic::isTernaryOp() const {
  switch (getIntrinsicID()) {
    default:
      return false;
    case Intrinsic::experimental_constrained_fma:
      return true;
  }
}

Instruction::BinaryOps BinaryOpIntrinsic::getBinaryOp() const {
  switch (getIntrinsicID()) {
    case Intrinsic::uadd_with_overflow:
    case Intrinsic::sadd_with_overflow:
    case Intrinsic::uadd_sat:
    case Intrinsic::sadd_sat:
      return Instruction::Add;
    case Intrinsic::usub_with_overflow:
    case Intrinsic::ssub_with_overflow:
    case Intrinsic::usub_sat:
    case Intrinsic::ssub_sat:
      return Instruction::Sub;
    case Intrinsic::umul_with_overflow:
    case Intrinsic::smul_with_overflow:
      return Instruction::Mul;
    default:
      llvm_unreachable("Invalid intrinsic");
  }
}

bool BinaryOpIntrinsic::isSigned() const {
  switch (getIntrinsicID()) {
    case Intrinsic::sadd_with_overflow:
    case Intrinsic::ssub_with_overflow:
    case Intrinsic::smul_with_overflow:
    case Intrinsic::sadd_sat:
    case Intrinsic::ssub_sat:
      return true;
    default:
      return false;
  }
}

unsigned BinaryOpIntrinsic::getNoWrapKind() const {
  if (isSigned())
    return OverflowingBinaryOperator::NoSignedWrap;
  else
    return OverflowingBinaryOperator::NoUnsignedWrap;
}
<commit_msg>Fix cppcheck "reduce variable scope" warning. NFCI.<commit_after>//===-- InstrinsicInst.cpp - Intrinsic Instruction Wrappers ---------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements methods that make it really easy to deal with intrinsic
// functions.
//
// All intrinsic function calls are instances of the call instruction, so these
// are all subclasses of the CallInst class.  Note that none of these classes
// has state or virtual methods, which is an important part of this gross/neat
// hack working.
//
// In some cases, arguments to intrinsics need to be generic and are defined as
// type pointer to empty struct { }*.  To access the real item of interest the
// cast instruction needs to be stripped away.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Operator.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

//===----------------------------------------------------------------------===//
/// DbgVariableIntrinsic - This is the common base class for debug info
/// intrinsics for variables.
///

Value *DbgVariableIntrinsic::getVariableLocation(bool AllowNullOp) const {
  Value *Op = getArgOperand(0);
  if (AllowNullOp && !Op)
    return nullptr;

  auto *MD = cast<MetadataAsValue>(Op)->getMetadata();
  if (auto *V = dyn_cast<ValueAsMetadata>(MD))
    return V->getValue();

  // When the value goes to null, it gets replaced by an empty MDNode.
  assert(!cast<MDNode>(MD)->getNumOperands() && "Expected an empty MDNode");
  return nullptr;
}

Optional<uint64_t> DbgVariableIntrinsic::getFragmentSizeInBits() const {
  if (auto Fragment = getExpression()->getFragmentInfo())
    return Fragment->SizeInBits;
  return getVariable()->getSizeInBits();
}

int llvm::Intrinsic::lookupLLVMIntrinsicByName(ArrayRef<const char *> NameTable,
                                               StringRef Name) {
  assert(Name.startswith("llvm."));

  // Do successive binary searches of the dotted name components. For
  // "llvm.gc.experimental.statepoint.p1i8.p1i32", we will find the range of
  // intrinsics starting with "llvm.gc", then "llvm.gc.experimental", then
  // "llvm.gc.experimental.statepoint", and then we will stop as the range is
  // size 1. During the search, we can skip the prefix that we already know is
  // identical. By using strncmp we consider names with differing suffixes to
  // be part of the equal range.
  size_t CmpEnd = 4; // Skip the "llvm" component.
  const char *const *Low = NameTable.begin();
  const char *const *High = NameTable.end();
  const char *const *LastLow = Low;
  while (CmpEnd < Name.size() && High - Low > 0) {
    size_t CmpStart = CmpEnd;
    CmpEnd = Name.find('.', CmpStart + 1);
    CmpEnd = CmpEnd == StringRef::npos ? Name.size() : CmpEnd;
    auto Cmp = [CmpStart, CmpEnd](const char *LHS, const char *RHS) {
      return strncmp(LHS + CmpStart, RHS + CmpStart, CmpEnd - CmpStart) < 0;
    };
    LastLow = Low;
    std::tie(Low, High) = std::equal_range(Low, High, Name.data(), Cmp);
  }
  if (High - Low > 0)
    LastLow = Low;

  if (LastLow == NameTable.end())
    return -1;
  StringRef NameFound = *LastLow;
  if (Name == NameFound ||
      (Name.startswith(NameFound) && Name[NameFound.size()] == '.'))
    return LastLow - NameTable.begin();
  return -1;
}

Value *InstrProfIncrementInst::getStep() const {
  if (InstrProfIncrementInstStep::classof(this)) {
    return const_cast<Value *>(getArgOperand(4));
  }
  const Module *M = getModule();
  LLVMContext &Context = M->getContext();
  return ConstantInt::get(Type::getInt64Ty(Context), 1);
}

Optional<ConstrainedFPIntrinsic::RoundingMode>
ConstrainedFPIntrinsic::getRoundingMode() const {
  unsigned NumOperands = getNumArgOperands();
  Metadata *MD =
      cast<MetadataAsValue>(getArgOperand(NumOperands - 2))->getMetadata();
  if (!MD || !isa<MDString>(MD))
    return None;
  return StrToRoundingMode(cast<MDString>(MD)->getString());
}

Optional<ConstrainedFPIntrinsic::RoundingMode>
ConstrainedFPIntrinsic::StrToRoundingMode(StringRef RoundingArg) {
  // For dynamic rounding mode, we use round to nearest but we will set the
  // 'exact' SDNodeFlag so that the value will not be rounded.
  return StringSwitch<Optional<RoundingMode>>(RoundingArg)
    .Case("round.dynamic",    rmDynamic)
    .Case("round.tonearest",  rmToNearest)
    .Case("round.downward",   rmDownward)
    .Case("round.upward",     rmUpward)
    .Case("round.towardzero", rmTowardZero)
    .Default(None);
}

Optional<StringRef>
ConstrainedFPIntrinsic::RoundingModeToStr(RoundingMode UseRounding) {
  Optional<StringRef> RoundingStr = None;
  switch (UseRounding) {
  case ConstrainedFPIntrinsic::rmDynamic:
    RoundingStr = "round.dynamic";
    break;
  case ConstrainedFPIntrinsic::rmToNearest:
    RoundingStr = "round.tonearest";
    break;
  case ConstrainedFPIntrinsic::rmDownward:
    RoundingStr = "round.downward";
    break;
  case ConstrainedFPIntrinsic::rmUpward:
    RoundingStr = "round.upward";
    break;
  case ConstrainedFPIntrinsic::rmTowardZero:
    RoundingStr = "round.towardzero";
    break;
  }
  return RoundingStr;
}

Optional<ConstrainedFPIntrinsic::ExceptionBehavior>
ConstrainedFPIntrinsic::getExceptionBehavior() const {
  unsigned NumOperands = getNumArgOperands();
  Metadata *MD =
      cast<MetadataAsValue>(getArgOperand(NumOperands - 1))->getMetadata();
  if (!MD || !isa<MDString>(MD))
    return None;
  return StrToExceptionBehavior(cast<MDString>(MD)->getString());
}

Optional<ConstrainedFPIntrinsic::ExceptionBehavior>
ConstrainedFPIntrinsic::StrToExceptionBehavior(StringRef ExceptionArg) {
  return StringSwitch<Optional<ExceptionBehavior>>(ExceptionArg)
    .Case("fpexcept.ignore",  ebIgnore)
    .Case("fpexcept.maytrap", ebMayTrap)
    .Case("fpexcept.strict",  ebStrict)
    .Default(None);
}

Optional<StringRef>
ConstrainedFPIntrinsic::ExceptionBehaviorToStr(ExceptionBehavior UseExcept) {
  Optional<StringRef> ExceptStr = None;
  switch (UseExcept) {
  case ConstrainedFPIntrinsic::ebStrict:
    ExceptStr = "fpexcept.strict";
    break;
  case ConstrainedFPIntrinsic::ebIgnore:
    ExceptStr = "fpexcept.ignore";
    break;
  case ConstrainedFPIntrinsic::ebMayTrap:
    ExceptStr = "fpexcept.maytrap";
    break;
  }
  return ExceptStr;
}

bool ConstrainedFPIntrinsic::isUnaryOp() const {
  switch (getIntrinsicID()) {
    default:
      return false;
    case Intrinsic::experimental_constrained_fptosi:
    case Intrinsic::experimental_constrained_fptoui:
    case Intrinsic::experimental_constrained_fptrunc:
    case Intrinsic::experimental_constrained_fpext:
    case Intrinsic::experimental_constrained_sqrt:
    case Intrinsic::experimental_constrained_sin:
    case Intrinsic::experimental_constrained_cos:
    case Intrinsic::experimental_constrained_exp:
    case Intrinsic::experimental_constrained_exp2:
    case Intrinsic::experimental_constrained_log:
    case Intrinsic::experimental_constrained_log10:
    case Intrinsic::experimental_constrained_log2:
    case Intrinsic::experimental_constrained_rint:
    case Intrinsic::experimental_constrained_nearbyint:
    case Intrinsic::experimental_constrained_ceil:
    case Intrinsic::experimental_constrained_floor:
    case Intrinsic::experimental_constrained_round:
    case Intrinsic::experimental_constrained_trunc:
      return true;
  }
}

bool ConstrainedFPIntrinsic::isTernaryOp() const {
  switch (getIntrinsicID()) {
    default:
      return false;
    case Intrinsic::experimental_constrained_fma:
      return true;
  }
}

Instruction::BinaryOps BinaryOpIntrinsic::getBinaryOp() const {
  switch (getIntrinsicID()) {
    case Intrinsic::uadd_with_overflow:
    case Intrinsic::sadd_with_overflow:
    case Intrinsic::uadd_sat:
    case Intrinsic::sadd_sat:
      return Instruction::Add;
    case Intrinsic::usub_with_overflow:
    case Intrinsic::ssub_with_overflow:
    case Intrinsic::usub_sat:
    case Intrinsic::ssub_sat:
      return Instruction::Sub;
    case Intrinsic::umul_with_overflow:
    case Intrinsic::smul_with_overflow:
      return Instruction::Mul;
    default:
      llvm_unreachable("Invalid intrinsic");
  }
}

bool BinaryOpIntrinsic::isSigned() const {
  switch (getIntrinsicID()) {
    case Intrinsic::sadd_with_overflow:
    case Intrinsic::ssub_with_overflow:
    case Intrinsic::smul_with_overflow:
    case Intrinsic::sadd_sat:
    case Intrinsic::ssub_sat:
      return true;
    default:
      return false;
  }
}

unsigned BinaryOpIntrinsic::getNoWrapKind() const {
  if (isSigned())
    return OverflowingBinaryOperator::NoSignedWrap;
  else
    return OverflowingBinaryOperator::NoUnsignedWrap;
}
<|endoftext|>


<commit_before>/**
 * Created by TekuConcept on June 19, 2018
 */

#include "SocketPollTable.h"

using namespace Impact;

SocketPollTable::SocketPollTable() {}

SocketPollTable::SocketPollTable(PollInitializer handles) {
	for(auto& handle : handles) {
		push_back(handle);
	}
}

SocketPollTable::~SocketPollTable() {}

void SocketPollTable::resetEvents() {
	std::lock_guard<std::mutex> lock(_mtx_);
	for(auto& descriptor : _descriptors_) {
		descriptor.revents = 0;
	}
}

bool SocketPollTable::empty() const {
	return _descriptors_.empty();
}

unsigned int SocketPollTable::size() const {
	return _descriptors_.size();
}

void SocketPollTable::reserve(unsigned int capacity) {
	std::lock_guard<std::mutex> lock(_mtx_);
	_descriptors_.reserve(capacity);
}

void SocketPollTable::shrink_to_fit() {
	std::lock_guard<std::mutex> lock(_mtx_);
	_descriptors_.shrink_to_fit();
}

void SocketPollTable::clear() {
	std::lock_guard<std::mutex> lock(_mtx_);
	_descriptors_.clear();
}

void SocketPollTable::push_back(HandleEventPair pair) {
	std::lock_guard<std::mutex> lock(_mtx_);
	struct pollfd sfd;
	sfd.fd = pair.first.descriptor;
	sfd.events = (short)pair.second;
	sfd.revents = 0;
	_descriptors_.push_back(sfd);
}

void SocketPollTable::erase(unsigned int position) {
	std::lock_guard<std::mutex> lock(_mtx_);
	_descriptors_.erase(_descriptors_.begin() + position);
}

void SocketPollTable::pop_back() {
	std::lock_guard<std::mutex> lock(_mtx_);
	_descriptors_.pop_back();
}

PollFlags SocketPollTable::at(unsigned int idx) {
	std::lock_guard<std::mutex> lock(_mtx_);
	return static_cast<PollFlags>(_descriptors_[idx].revents);
}

PollFlags SocketPollTable::operator[] (unsigned int idx) {
	std::lock_guard<std::mutex> lock(_mtx_);
	return static_cast<PollFlags>(_descriptors_[idx].revents);
}

unsigned int SocketPollTable::find(const SocketHandle& target) {
	std::lock_guard<std::mutex> lock(_mtx_);
	if(_descriptors_.size() == 0) return static_cast<unsigned int>(-1);
	unsigned int index = 0;
	for(const auto& descriptor : _descriptors_) {
		if(descriptor.fd == target.descriptor)
			return index;
		index++;
	}
	return static_cast<unsigned int>(-1); // EOF
}<commit_msg>Dev Checkpoint 070720181528<commit_after>/**
 * Created by TekuConcept on June 19, 2018
 */

#include "SocketPollTable.h"

using namespace Impact;

SocketPollTable::SocketPollTable() {}

SocketPollTable::SocketPollTable(PollInitializer handles) {
	for(auto& handle : handles) {
		push_back(handle);
	}
}

SocketPollTable::~SocketPollTable() {}

void SocketPollTable::resetEvents() {
	std::lock_guard<std::mutex> lock(_mtx_);
	for(auto& descriptor : _descriptors_) {
		descriptor.revents = 0;
	}
}

bool SocketPollTable::empty() const {
	return _descriptors_.empty();
}

unsigned int SocketPollTable::size() const {
	return _descriptors_.size();
}

void SocketPollTable::reserve(unsigned int capacity) {
	std::lock_guard<std::mutex> lock(_mtx_);
	_descriptors_.reserve(capacity);
}

void SocketPollTable::shrink_to_fit() {
	std::lock_guard<std::mutex> lock(_mtx_);
	_descriptors_.shrink_to_fit();
}

void SocketPollTable::clear() {
	std::lock_guard<std::mutex> lock(_mtx_);
	_descriptors_.clear();
}

void SocketPollTable::push_back(HandleEventPair pair) {
	std::lock_guard<std::mutex> lock(_mtx_);
	struct pollfd sfd;
	sfd.fd = pair.first.descriptor;
	sfd.events = (short)pair.second;
	sfd.revents = 0;
	_descriptors_.push_back(sfd);
}

void SocketPollTable::erase(unsigned int position) {
	std::lock_guard<std::mutex> lock(_mtx_);
	_descriptors_.erase(_descriptors_.begin() + position);
}

void SocketPollTable::pop_back() {
	std::lock_guard<std::mutex> lock(_mtx_);
	_descriptors_.pop_back();
}

PollFlags SocketPollTable::at(unsigned int idx) {
	std::lock_guard<std::mutex> lock(_mtx_);
	return static_cast<PollFlags>(_descriptors_.at(idx).revents);
}

PollFlags SocketPollTable::operator[] (unsigned int idx) {
	std::lock_guard<std::mutex> lock(_mtx_);
	return static_cast<PollFlags>(_descriptors_[idx].revents);
}

unsigned int SocketPollTable::find(const SocketHandle& target) {
	std::lock_guard<std::mutex> lock(_mtx_);
	if(_descriptors_.size() == 0) return static_cast<unsigned int>(-1);
	unsigned int index = 0;
	for(const auto& descriptor : _descriptors_) {
		if(descriptor.fd == target.descriptor)
			return index;
		index++;
	}
	return static_cast<unsigned int>(-1); // EOF
}<|endoftext|>


<commit_before>#include "dreal/util/if_then_else_eliminator.h"

#include <algorithm>  // To suppress cpplint on max.
#include <atomic>
#include <set>
#include <stdexcept>
#include <string>

#include "dreal/util/logging.h"
#include "dreal/util/nnfizer.h"
#include "dreal/util/stat.h"
#include "dreal/util/timer.h"

using std::cout;
using std::set;
using std::to_string;
using std::unordered_set;

namespace dreal {

// A class to show statistics information at destruction.
class IfThenElseElimStat : public Stat {
 public:
  explicit IfThenElseElimStat(const bool enabled) : Stat{enabled} {}
  IfThenElseElimStat(const IfThenElseElimStat&) = delete;
  IfThenElseElimStat(IfThenElseElimStat&&) = delete;
  IfThenElseElimStat& operator=(const IfThenElseElimStat&) = delete;
  IfThenElseElimStat& operator=(IfThenElseElimStat&&) = delete;
  ~IfThenElseElimStat() override {
    if (enabled()) {
      using fmt::print;
      print(cout, "{:<45} @ {:<20} = {:>15}\n", "Total # of Process",
            "ITE Elim", num_process_);
      if (num_process_ > 0) {
        print(cout, "{:<45} @ {:<20} = {:>15f} sec\n",
              "Total time spent in Processing", "ITE Elim",
              timer_process_.seconds());
      }
    }
  }

  void increase_num_process() { increase(&num_process_); }

  Timer timer_process_;

 private:
  std::atomic<int> num_process_{0};
};

Formula IfThenElseEliminator::Process(const Formula& f) {
  static IfThenElseElimStat stat{DREAL_LOG_INFO_ENABLED};
  TimerGuard timer_guard(&stat.timer_process_, stat.enabled());
  stat.increase_num_process();

  Formula new_f{Visit(f, Formula::True())};
  if (f.EqualTo(new_f) && added_formulas_.empty()) {
    return f;
  } else {
    return new_f && make_conjunction(added_formulas_);
  }
}

const unordered_set<Variable, hash_value<Variable>>&
IfThenElseEliminator::variables() const {
  return ite_variables_;
}

Expression IfThenElseEliminator::Visit(const Expression& e,
                                       const Formula& guard) {
  return VisitExpression<Expression>(this, e, guard);
}

Expression IfThenElseEliminator::VisitVariable(const Expression& e,
                                               const Formula&) {
  return e;
}

Expression IfThenElseEliminator::VisitConstant(const Expression& e,
                                               const Formula&) {
  return e;
}

Expression IfThenElseEliminator::VisitRealConstant(const Expression& e,
                                                   const Formula&) {
  return e;
}

Expression IfThenElseEliminator::VisitAddition(const Expression& e,
                                               const Formula& guard) {
  // e = c₀ + ∑ᵢ cᵢ * eᵢ
  Expression ret{get_constant_in_addition(e)};
  for (const auto& p : get_expr_to_coeff_map_in_addition(e)) {
    const Expression& e_i{p.first};
    const double c_i{p.second};
    ret += c_i * Visit(e_i, guard);
  }
  return ret;
}

Expression IfThenElseEliminator::VisitMultiplication(const Expression& e,
                                                     const Formula& guard) {
  // e = c₀ * ∏ᵢ pow(eᵢ₁, eᵢ₂)
  Expression ret{get_constant_in_multiplication(e)};
  for (const auto& p : get_base_to_exponent_map_in_multiplication(e)) {
    const Expression& e_i1{p.first};
    const Expression& e_i2{p.second};
    ret *= pow(Visit(e_i1, guard), Visit(e_i2, guard));
  }
  return ret;
}

Expression IfThenElseEliminator::VisitDivision(const Expression& e,
                                               const Formula& guard) {
  return Visit(get_first_argument(e), guard) /
         Visit(get_second_argument(e), guard);
}

Expression IfThenElseEliminator::VisitLog(const Expression& e,
                                          const Formula& guard) {
  return log(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitAbs(const Expression& e,
                                          const Formula& guard) {
  return abs(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitExp(const Expression& e,
                                          const Formula& guard) {
  return exp(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitSqrt(const Expression& e,
                                           const Formula& guard) {
  return sqrt(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitPow(const Expression& e,
                                          const Formula& guard) {
  return pow(Visit(get_first_argument(e), guard),
             Visit(get_second_argument(e), guard));
}

Expression IfThenElseEliminator::VisitSin(const Expression& e,
                                          const Formula& guard) {
  return sin(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitCos(const Expression& e,
                                          const Formula& guard) {
  return cos(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitTan(const Expression& e,
                                          const Formula& guard) {
  return tan(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitAsin(const Expression& e,
                                           const Formula& guard) {
  return asin(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitAcos(const Expression& e,
                                           const Formula& guard) {
  return acos(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitAtan(const Expression& e,
                                           const Formula& guard) {
  return atan(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitAtan2(const Expression& e,
                                            const Formula& guard) {
  return atan2(Visit(get_first_argument(e), guard),
               Visit(get_second_argument(e), guard));
}

Expression IfThenElseEliminator::VisitSinh(const Expression& e,
                                           const Formula& guard) {
  return sinh(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitCosh(const Expression& e,
                                           const Formula& guard) {
  return cosh(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitTanh(const Expression& e,
                                           const Formula& guard) {
  return tanh(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitMin(const Expression& e,
                                          const Formula& guard) {
  return min(Visit(get_first_argument(e), guard),
             Visit(get_second_argument(e), guard));
}

Expression IfThenElseEliminator::VisitMax(const Expression& e,
                                          const Formula& guard) {
  return max(Visit(get_first_argument(e), guard),
             Visit(get_second_argument(e), guard));
}

Expression IfThenElseEliminator::VisitIfThenElse(const Expression& e,
                                                 const Formula& guard) {
  static int counter{0};
  const Variable new_var{"ITE" + to_string(counter++),
                         Variable::Type::CONTINUOUS};
  ite_variables_.insert(new_var);
  const Formula c{Visit(get_conditional_formula(e), guard)};
  const Formula then_guard{guard && c};
  const Formula else_guard{guard && !c};
  const Expression e1{Visit(get_then_expression(e), then_guard)};
  const Expression e2{Visit(get_else_expression(e), else_guard)};
  // (then_guard ∧ (new_var = e1)) ∨ (else_guard ∧ (new_var = e2))
  added_formulas_.push_back((then_guard && (new_var == e1)) ||
                            (else_guard && (new_var == e2)));
  return new_var;
}

Expression IfThenElseEliminator::VisitUninterpretedFunction(const Expression& e,
                                                            const Formula&) {
  return e;
}

Formula IfThenElseEliminator::Visit(const Formula& f, const Formula& guard) {
  return VisitFormula<Formula>(this, f, guard);
}

Formula IfThenElseEliminator::VisitFalse(const Formula& f, const Formula&) {
  return f;
}

Formula IfThenElseEliminator::VisitTrue(const Formula& f, const Formula&) {
  return f;
}

Formula IfThenElseEliminator::VisitVariable(const Formula& f, const Formula&) {
  return f;
}

Formula IfThenElseEliminator::VisitEqualTo(const Formula& f,
                                           const Formula& guard) {
  return Visit(get_lhs_expression(f), guard) ==
         Visit(get_rhs_expression(f), guard);
}

Formula IfThenElseEliminator::VisitNotEqualTo(const Formula& f,
                                              const Formula& guard) {
  return Visit(get_lhs_expression(f), guard) !=
         Visit(get_rhs_expression(f), guard);
}

Formula IfThenElseEliminator::VisitGreaterThan(const Formula& f,
                                               const Formula& guard) {
  return Visit(get_lhs_expression(f), guard) >
         Visit(get_rhs_expression(f), guard);
}

Formula IfThenElseEliminator::VisitGreaterThanOrEqualTo(const Formula& f,
                                                        const Formula& guard) {
  return Visit(get_lhs_expression(f), guard) >=
         Visit(get_rhs_expression(f), guard);
}

Formula IfThenElseEliminator::VisitLessThan(const Formula& f,
                                            const Formula& guard) {
  return Visit(get_lhs_expression(f), guard) <
         Visit(get_rhs_expression(f), guard);
}

Formula IfThenElseEliminator::VisitLessThanOrEqualTo(const Formula& f,
                                                     const Formula& guard) {
  return Visit(get_lhs_expression(f), guard) <=
         Visit(get_rhs_expression(f), guard);
}

Formula IfThenElseEliminator::VisitConjunction(const Formula& f,
                                               const Formula& guard) {
  // f := f₁ ∧ ... ∧ fₙ
  set<Formula> new_conjuncts;
  for (const Formula& f_i : get_operands(f)) {
    new_conjuncts.emplace(Visit(f_i, guard));
  }
  return make_conjunction(new_conjuncts);
}

Formula IfThenElseEliminator::VisitDisjunction(const Formula& f,
                                               const Formula& guard) {
  // f := f₁ ∨ ... ∨ fₙ
  set<Formula> new_disjuncts;
  for (const Formula& f_i : get_operands(f)) {
    new_disjuncts.emplace(Visit(f_i, guard));
  }
  return make_disjunction(new_disjuncts);
}

Formula IfThenElseEliminator::VisitNegation(const Formula& f,
                                            const Formula& guard) {
  return !Visit(get_operand(f), guard);
}

Formula IfThenElseEliminator::VisitForall(const Formula& f,
                                          const Formula& guard) {
  //    ∃x. ∀y. ITE(f, e₁, e₂) > 0
  // => ∃x. ¬∃y. ¬(ITE(f, e₁, e₂) > 0)
  // => ∃x. ¬∃y. ∃v. ¬(v > 0) ∧ (f → (v = e₁)) ∧ (¬f → (v = e₂))
  // => ∃x. ∀y. ∀v. ¬(¬(v > 0) ∧ (f → (v = e₁)) ∧ (¬f → (v = e₂)))
  // => ∃x. ∀y. ∀v. (v > 0) ∨ ¬((f → (v = e₁)) ∧ (¬f → (v = e₂)))
  // => ∃x. ∀y. ∀v. ¬((f → (v = e₁)) ∧ (¬f → (v = e₂))) ∨ (v > 0)
  // => ∃x. ∀y. ∀v. ((f → (v = e₁)) ∧ (¬f → (v = e₂))) → (v > 0)
  // => ∃x. ∀y. ∀v. (v > 0) ∨ (f ∧ (v ≠ e₁)) ∨ (¬f ∧ (v ≠ e₂)).

  // Note that we have the following:
  // => ∃x. ∀y. ∀v. ¬(¬(v > 0) ∧ ¬(f ∧ (v ≠ e₁)) ∧ ¬(¬f ∧ (v ≠ e₂)).
  // => ∃x. ∀y. ∀v. ¬(¬(v > 0) ∧ (¬f ∨ (v = e₁)) ∧ (f ∨ (v = e₂)).
  // => ∃x. ∀y. ∀v. ¬(¬(v > 0) ∧ (f → (v = e₁)) ∧ (¬f → (v = e₂)).
  //
  // That is, we can first process the negation of the original
  // formula `ITE(f, e₁, e₂) > 0`, then negate the result again while
  // collecting the newly introduced variables (`v`s) to treat them as
  // universally quantified variables (instead of existential
  // variables). In this way, we can use the existing ITE-elim routine.
  Variables quantified_variables{get_quantified_variables(f)};
  const Formula& quantified_formula{get_quantified_formula(f)};
  IfThenElseEliminator ite_eliminator_forall;
  const Formula eliminated{ite_eliminator_forall.Process(!quantified_formula)};
  quantified_variables.insert(ite_eliminator_forall.variables().begin(),
                              ite_eliminator_forall.variables().end());
  return forall(quantified_variables, Nnfizer{}.Convert(!eliminated));
}

}  // namespace dreal
<commit_msg>fix(util): Remove unused params<commit_after>#include "dreal/util/if_then_else_eliminator.h"

#include <algorithm>  // To suppress cpplint on max.
#include <atomic>
#include <set>
#include <stdexcept>
#include <string>

#include "dreal/util/logging.h"
#include "dreal/util/nnfizer.h"
#include "dreal/util/stat.h"
#include "dreal/util/timer.h"

using std::cout;
using std::set;
using std::to_string;
using std::unordered_set;

namespace dreal {

// A class to show statistics information at destruction.
class IfThenElseElimStat : public Stat {
 public:
  explicit IfThenElseElimStat(const bool enabled) : Stat{enabled} {}
  IfThenElseElimStat(const IfThenElseElimStat&) = delete;
  IfThenElseElimStat(IfThenElseElimStat&&) = delete;
  IfThenElseElimStat& operator=(const IfThenElseElimStat&) = delete;
  IfThenElseElimStat& operator=(IfThenElseElimStat&&) = delete;
  ~IfThenElseElimStat() override {
    if (enabled()) {
      using fmt::print;
      print(cout, "{:<45} @ {:<20} = {:>15}\n", "Total # of Process",
            "ITE Elim", num_process_);
      if (num_process_ > 0) {
        print(cout, "{:<45} @ {:<20} = {:>15f} sec\n",
              "Total time spent in Processing", "ITE Elim",
              timer_process_.seconds());
      }
    }
  }

  void increase_num_process() { increase(&num_process_); }

  Timer timer_process_;

 private:
  std::atomic<int> num_process_{0};
};

Formula IfThenElseEliminator::Process(const Formula& f) {
  static IfThenElseElimStat stat{DREAL_LOG_INFO_ENABLED};
  TimerGuard timer_guard(&stat.timer_process_, stat.enabled());
  stat.increase_num_process();

  Formula new_f{Visit(f, Formula::True())};
  if (f.EqualTo(new_f) && added_formulas_.empty()) {
    return f;
  } else {
    return new_f && make_conjunction(added_formulas_);
  }
}

const unordered_set<Variable, hash_value<Variable>>&
IfThenElseEliminator::variables() const {
  return ite_variables_;
}

Expression IfThenElseEliminator::Visit(const Expression& e,
                                       const Formula& guard) {
  return VisitExpression<Expression>(this, e, guard);
}

Expression IfThenElseEliminator::VisitVariable(const Expression& e,
                                               const Formula&) {
  return e;
}

Expression IfThenElseEliminator::VisitConstant(const Expression& e,
                                               const Formula&) {
  return e;
}

Expression IfThenElseEliminator::VisitRealConstant(const Expression& e,
                                                   const Formula&) {
  return e;
}

Expression IfThenElseEliminator::VisitAddition(const Expression& e,
                                               const Formula& guard) {
  // e = c₀ + ∑ᵢ cᵢ * eᵢ
  Expression ret{get_constant_in_addition(e)};
  for (const auto& p : get_expr_to_coeff_map_in_addition(e)) {
    const Expression& e_i{p.first};
    const double c_i{p.second};
    ret += c_i * Visit(e_i, guard);
  }
  return ret;
}

Expression IfThenElseEliminator::VisitMultiplication(const Expression& e,
                                                     const Formula& guard) {
  // e = c₀ * ∏ᵢ pow(eᵢ₁, eᵢ₂)
  Expression ret{get_constant_in_multiplication(e)};
  for (const auto& p : get_base_to_exponent_map_in_multiplication(e)) {
    const Expression& e_i1{p.first};
    const Expression& e_i2{p.second};
    ret *= pow(Visit(e_i1, guard), Visit(e_i2, guard));
  }
  return ret;
}

Expression IfThenElseEliminator::VisitDivision(const Expression& e,
                                               const Formula& guard) {
  return Visit(get_first_argument(e), guard) /
         Visit(get_second_argument(e), guard);
}

Expression IfThenElseEliminator::VisitLog(const Expression& e,
                                          const Formula& guard) {
  return log(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitAbs(const Expression& e,
                                          const Formula& guard) {
  return abs(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitExp(const Expression& e,
                                          const Formula& guard) {
  return exp(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitSqrt(const Expression& e,
                                           const Formula& guard) {
  return sqrt(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitPow(const Expression& e,
                                          const Formula& guard) {
  return pow(Visit(get_first_argument(e), guard),
             Visit(get_second_argument(e), guard));
}

Expression IfThenElseEliminator::VisitSin(const Expression& e,
                                          const Formula& guard) {
  return sin(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitCos(const Expression& e,
                                          const Formula& guard) {
  return cos(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitTan(const Expression& e,
                                          const Formula& guard) {
  return tan(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitAsin(const Expression& e,
                                           const Formula& guard) {
  return asin(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitAcos(const Expression& e,
                                           const Formula& guard) {
  return acos(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitAtan(const Expression& e,
                                           const Formula& guard) {
  return atan(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitAtan2(const Expression& e,
                                            const Formula& guard) {
  return atan2(Visit(get_first_argument(e), guard),
               Visit(get_second_argument(e), guard));
}

Expression IfThenElseEliminator::VisitSinh(const Expression& e,
                                           const Formula& guard) {
  return sinh(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitCosh(const Expression& e,
                                           const Formula& guard) {
  return cosh(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitTanh(const Expression& e,
                                           const Formula& guard) {
  return tanh(Visit(get_argument(e), guard));
}

Expression IfThenElseEliminator::VisitMin(const Expression& e,
                                          const Formula& guard) {
  return min(Visit(get_first_argument(e), guard),
             Visit(get_second_argument(e), guard));
}

Expression IfThenElseEliminator::VisitMax(const Expression& e,
                                          const Formula& guard) {
  return max(Visit(get_first_argument(e), guard),
             Visit(get_second_argument(e), guard));
}

Expression IfThenElseEliminator::VisitIfThenElse(const Expression& e,
                                                 const Formula& guard) {
  static int counter{0};
  const Variable new_var{"ITE" + to_string(counter++),
                         Variable::Type::CONTINUOUS};
  ite_variables_.insert(new_var);
  const Formula c{Visit(get_conditional_formula(e), guard)};
  const Formula then_guard{guard && c};
  const Formula else_guard{guard && !c};
  const Expression e1{Visit(get_then_expression(e), then_guard)};
  const Expression e2{Visit(get_else_expression(e), else_guard)};
  // (then_guard ∧ (new_var = e1)) ∨ (else_guard ∧ (new_var = e2))
  added_formulas_.push_back((then_guard && (new_var == e1)) ||
                            (else_guard && (new_var == e2)));
  return new_var;
}

Expression IfThenElseEliminator::VisitUninterpretedFunction(const Expression& e,
                                                            const Formula&) {
  return e;
}

Formula IfThenElseEliminator::Visit(const Formula& f, const Formula& guard) {
  return VisitFormula<Formula>(this, f, guard);
}

Formula IfThenElseEliminator::VisitFalse(const Formula& f, const Formula&) {
  return f;
}

Formula IfThenElseEliminator::VisitTrue(const Formula& f, const Formula&) {
  return f;
}

Formula IfThenElseEliminator::VisitVariable(const Formula& f, const Formula&) {
  return f;
}

Formula IfThenElseEliminator::VisitEqualTo(const Formula& f,
                                           const Formula& guard) {
  return Visit(get_lhs_expression(f), guard) ==
         Visit(get_rhs_expression(f), guard);
}

Formula IfThenElseEliminator::VisitNotEqualTo(const Formula& f,
                                              const Formula& guard) {
  return Visit(get_lhs_expression(f), guard) !=
         Visit(get_rhs_expression(f), guard);
}

Formula IfThenElseEliminator::VisitGreaterThan(const Formula& f,
                                               const Formula& guard) {
  return Visit(get_lhs_expression(f), guard) >
         Visit(get_rhs_expression(f), guard);
}

Formula IfThenElseEliminator::VisitGreaterThanOrEqualTo(const Formula& f,
                                                        const Formula& guard) {
  return Visit(get_lhs_expression(f), guard) >=
         Visit(get_rhs_expression(f), guard);
}

Formula IfThenElseEliminator::VisitLessThan(const Formula& f,
                                            const Formula& guard) {
  return Visit(get_lhs_expression(f), guard) <
         Visit(get_rhs_expression(f), guard);
}

Formula IfThenElseEliminator::VisitLessThanOrEqualTo(const Formula& f,
                                                     const Formula& guard) {
  return Visit(get_lhs_expression(f), guard) <=
         Visit(get_rhs_expression(f), guard);
}

Formula IfThenElseEliminator::VisitConjunction(const Formula& f,
                                               const Formula& guard) {
  // f := f₁ ∧ ... ∧ fₙ
  set<Formula> new_conjuncts;
  for (const Formula& f_i : get_operands(f)) {
    new_conjuncts.emplace(Visit(f_i, guard));
  }
  return make_conjunction(new_conjuncts);
}

Formula IfThenElseEliminator::VisitDisjunction(const Formula& f,
                                               const Formula& guard) {
  // f := f₁ ∨ ... ∨ fₙ
  set<Formula> new_disjuncts;
  for (const Formula& f_i : get_operands(f)) {
    new_disjuncts.emplace(Visit(f_i, guard));
  }
  return make_disjunction(new_disjuncts);
}

Formula IfThenElseEliminator::VisitNegation(const Formula& f,
                                            const Formula& guard) {
  return !Visit(get_operand(f), guard);
}

Formula IfThenElseEliminator::VisitForall(const Formula& f, const Formula&) {
  //    ∃x. ∀y. ITE(f, e₁, e₂) > 0
  // => ∃x. ¬∃y. ¬(ITE(f, e₁, e₂) > 0)
  // => ∃x. ¬∃y. ∃v. ¬(v > 0) ∧ (f → (v = e₁)) ∧ (¬f → (v = e₂))
  // => ∃x. ∀y. ∀v. ¬(¬(v > 0) ∧ (f → (v = e₁)) ∧ (¬f → (v = e₂)))
  // => ∃x. ∀y. ∀v. (v > 0) ∨ ¬((f → (v = e₁)) ∧ (¬f → (v = e₂)))
  // => ∃x. ∀y. ∀v. ¬((f → (v = e₁)) ∧ (¬f → (v = e₂))) ∨ (v > 0)
  // => ∃x. ∀y. ∀v. ((f → (v = e₁)) ∧ (¬f → (v = e₂))) → (v > 0)
  // => ∃x. ∀y. ∀v. (v > 0) ∨ (f ∧ (v ≠ e₁)) ∨ (¬f ∧ (v ≠ e₂)).

  // Note that we have the following:
  // => ∃x. ∀y. ∀v. ¬(¬(v > 0) ∧ ¬(f ∧ (v ≠ e₁)) ∧ ¬(¬f ∧ (v ≠ e₂)).
  // => ∃x. ∀y. ∀v. ¬(¬(v > 0) ∧ (¬f ∨ (v = e₁)) ∧ (f ∨ (v = e₂)).
  // => ∃x. ∀y. ∀v. ¬(¬(v > 0) ∧ (f → (v = e₁)) ∧ (¬f → (v = e₂)).
  //
  // That is, we can first process the negation of the original
  // formula `ITE(f, e₁, e₂) > 0`, then negate the result again while
  // collecting the newly introduced variables (`v`s) to treat them as
  // universally quantified variables (instead of existential
  // variables). In this way, we can use the existing ITE-elim routine.
  Variables quantified_variables{get_quantified_variables(f)};
  const Formula& quantified_formula{get_quantified_formula(f)};
  IfThenElseEliminator ite_eliminator_forall;
  const Formula eliminated{ite_eliminator_forall.Process(!quantified_formula)};
  quantified_variables.insert(ite_eliminator_forall.variables().begin(),
                              ite_eliminator_forall.variables().end());
  return forall(quantified_variables, Nnfizer{}.Convert(!eliminated));
}

}  // namespace dreal
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * 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/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "vcl/svapp.hxx"
#include "vcl/sysdata.hxx"

#include "quartz/salvd.h"
#ifdef MACOSX
#include "osx/salinst.h"
#include "osx/saldata.hxx"
#include "osx/salframe.h"
#else
#include "headless/svpframe.hxx"
#include "headless/svpgdi.hxx"
#include "headless/svpinst.hxx"
#include "headless/svpvd.hxx"
#endif
#include "quartz/salgdi.h"

// -----------------------------------------------------------------------

SalVirtualDevice* AquaSalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
    long nDX, long nDY, sal_uInt16 nBitCount, const SystemGraphicsData *pData )
{
    // #i92075# can be called first in a thread
    SalData::ensureThreadAutoreleasePool();

#ifdef IOS
    if( pData )
        return new AquaSalVirtualDevice( static_cast< AquaSalGraphics* >( pGraphics ), nDX, nDY, nBitCount, pData );
    else
        return new SvpSalVirtualDevice( nBitCount );
#else
        return new AquaSalVirtualDevice( static_cast< AquaSalGraphics* >( pGraphics ), nDX, nDY, nBitCount, pData );
#endif
}

// -----------------------------------------------------------------------

void AquaSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
{
    delete pDevice;
}

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

AquaSalVirtualDevice::AquaSalVirtualDevice( AquaSalGraphics* pGraphic, long nDX, long nDY, sal_uInt16 nBitCount, const SystemGraphicsData *pData )
:   mbGraphicsUsed( false )
,   mxBitmapContext( NULL )
,   mnBitmapDepth( 0 )
,   mxLayer( NULL )
{
    if( pGraphic && pData && pData->rCGContext )
    {
        // Create virtual device based on existing SystemGraphicsData
        // We ignore nDx and nDY, as the desired size comes from the SystemGraphicsData.
        // WTF does the above mean, SystemGraphicsData has no size field(s).
        mbForeignContext = true;        // the mxContext is from pData
        mpGraphics = new AquaSalGraphics( /*pGraphic*/ );
#ifdef IOS
        // Note: we should *not* create a CGLayer and assign it to
        // mxLayer here. Don't confuse CGLayer and CALayer. A CGLayer
        // is basically a fancy off-screen bitmap not related to
        // anything being displayed at all. The CGContext passed in
        // here refers to something actively part of the compositor
        // stack and being dislayed on the device, and *there*
        // CALayers are involved, sure. The use of mxLayer in this
        // code is for "traditional" LO virtual devices, off-screen
        // bitmaps. I think. On the other hand, the use of
        // VirtualDevice with a "foreign" CGContext for OS X is
        // actually dead code...
#endif
        mpGraphics->SetVirDevGraphics( mxLayer, pData->rCGContext );
    }
    else
    {
        // create empty new virtual device
        mbForeignContext = false;           // the mxContext is created within VCL
        mpGraphics = new AquaSalGraphics(); // never fails
        mnBitmapDepth = nBitCount;
#ifdef MACOSX
        // inherit resolution from reference device
        if( pGraphic )
        {
            AquaSalFrame* pFrame = pGraphic->getGraphicsFrame();
            if( pFrame && AquaSalFrame::isAlive( pFrame ) )
            {
                mpGraphics->setGraphicsFrame( pFrame );
                mpGraphics->copyResolution( *pGraphic );
            }
        }
#endif
        if( nDX && nDY )
            SetSize( nDX, nDY );

        // NOTE: if SetSize does not succeed, we just ignore the nDX and nDY
    }
}

// -----------------------------------------------------------------------

AquaSalVirtualDevice::~AquaSalVirtualDevice()
{
    if( mpGraphics )
    {
        mpGraphics->SetVirDevGraphics( NULL, NULL );
        delete mpGraphics;
        mpGraphics = 0;
    }
    Destroy();
}

// -----------------------------------------------------------------------

void AquaSalVirtualDevice::Destroy()
{
    if( mbForeignContext ) {
        // Do not delete mxContext that we have received from outside VCL
        mxLayer = NULL;
        return;
    }

    if( mxLayer )
    {
        if( mpGraphics )
            mpGraphics->SetVirDevGraphics( NULL, NULL );
        CGLayerRelease( mxLayer );
        mxLayer = NULL;
    }

    if( mxBitmapContext )
    {
        void* pRawData = CGBitmapContextGetData( mxBitmapContext );
        rtl_freeMemory( pRawData );
        CGContextRelease( mxBitmapContext );
        mxBitmapContext = NULL;
    }
}

// -----------------------------------------------------------------------

SalGraphics* AquaSalVirtualDevice::GetGraphics()
{
    if( mbGraphicsUsed || !mpGraphics )
        return 0;

    mbGraphicsUsed = true;
    return mpGraphics;
}

// -----------------------------------------------------------------------

void AquaSalVirtualDevice::ReleaseGraphics( SalGraphics* )
{
    mbGraphicsUsed = false;
}

// -----------------------------------------------------------------------

sal_Bool AquaSalVirtualDevice::SetSize( long nDX, long nDY )
{
#ifdef IOS
    (void) nDX;
    (void) nDY;
    assert(mbForeignContext);
#endif

    if( mbForeignContext )
    {
        // Do not delete/resize mxContext that we have received from outside VCL
        return true;
    }

#ifdef IOS
    return false;
#else
    if( mxLayer )
    {
        const CGSize aSize = CGLayerGetSize( mxLayer );
        if( (nDX == aSize.width) && (nDY == aSize.height) )
        {
            // Yay, we do not have to do anything :)
            return true;
        }
    }

    Destroy();

    // create a Quartz layer matching to the intended virdev usage
    CGContextRef xCGContext = NULL;
    if( mnBitmapDepth && (mnBitmapDepth < 16) )
    {
        mnBitmapDepth = 8;  // TODO: are 1bit vdevs worth it?
        const CGColorSpaceRef aCGColorSpace = GetSalData()->mxGraySpace;
        const CGBitmapInfo aCGBmpInfo = kCGImageAlphaNone;
        const int nBytesPerRow = (mnBitmapDepth * nDX + 7) / 8;

        void* pRawData = rtl_allocateMemory( nBytesPerRow * nDY );
        mxBitmapContext = CGBitmapContextCreate( pRawData, nDX, nDY,
                                                 mnBitmapDepth, nBytesPerRow, aCGColorSpace, aCGBmpInfo );
        xCGContext = mxBitmapContext;
    }
    else
    {
        // default to a NSView target context
        AquaSalFrame* pSalFrame = mpGraphics->getGraphicsFrame();
        if( !pSalFrame || !AquaSalFrame::isAlive( pSalFrame ))
        {
            if( !GetSalData()->maFrames.empty() )
            {
                // get the first matching frame
                pSalFrame = *GetSalData()->maFrames.begin();
            }
            else
            {
                // ensure we don't reuse a dead AquaSalFrame on the very
                // unlikely case of no other frame to use
                pSalFrame = NULL;
            }
            // update the frame reference
            mpGraphics->setGraphicsFrame( pSalFrame );
        }
        if( pSalFrame )
        {
            // #i91990#
            NSWindow* pNSWindow = pSalFrame->getNSWindow();
            if ( pNSWindow )
            {
                NSGraphicsContext* pNSContext = [NSGraphicsContext graphicsContextWithWindow: pNSWindow];
                if( pNSContext )
                    xCGContext = reinterpret_cast<CGContextRef>([pNSContext graphicsPort]);
            }
            else
            {
                // fall back to a bitmap context
                mnBitmapDepth = 32;
                const CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
                const CGBitmapInfo aCGBmpInfo = kCGImageAlphaNoneSkipFirst;
                const int nBytesPerRow = (mnBitmapDepth * nDX) / 8;

                void* pRawData = rtl_allocateMemory( nBytesPerRow * nDY );
                mxBitmapContext = CGBitmapContextCreate( pRawData, nDX, nDY,
                                                         8, nBytesPerRow, aCGColorSpace, aCGBmpInfo );
                xCGContext = mxBitmapContext;
            }
        }
    }

    DBG_ASSERT( xCGContext, "no context" );

    const CGSize aNewSize = { static_cast<CGFloat>(nDX), static_cast<CGFloat>(nDY) };
    mxLayer = CGLayerCreateWithContext( xCGContext, aNewSize, NULL );

    if( mxLayer && mpGraphics )
    {
        // get the matching Quartz context
        CGContextRef xDrawContext = CGLayerGetContext( mxLayer );
        mpGraphics->SetVirDevGraphics( mxLayer, xDrawContext, mnBitmapDepth );
    }

    return (mxLayer != NULL);
#endif
}

// -----------------------------------------------------------------------

void AquaSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
{
    if( mxLayer )
    {
        const CGSize aSize = CGLayerGetSize( mxLayer );
        rWidth = static_cast<long>(aSize.width);
        rHeight = static_cast<long>(aSize.height);
    }
    else
    {
        rWidth = 0;
        rHeight = 0;
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>Indentation fix<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * 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/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#include "vcl/svapp.hxx"
#include "vcl/sysdata.hxx"

#include "quartz/salvd.h"
#ifdef MACOSX
#include "osx/salinst.h"
#include "osx/saldata.hxx"
#include "osx/salframe.h"
#else
#include "headless/svpframe.hxx"
#include "headless/svpgdi.hxx"
#include "headless/svpinst.hxx"
#include "headless/svpvd.hxx"
#endif
#include "quartz/salgdi.h"

// -----------------------------------------------------------------------

SalVirtualDevice* AquaSalInstance::CreateVirtualDevice( SalGraphics* pGraphics,
    long nDX, long nDY, sal_uInt16 nBitCount, const SystemGraphicsData *pData )
{
    // #i92075# can be called first in a thread
    SalData::ensureThreadAutoreleasePool();

#ifdef IOS
    if( pData )
        return new AquaSalVirtualDevice( static_cast< AquaSalGraphics* >( pGraphics ), nDX, nDY, nBitCount, pData );
    else
        return new SvpSalVirtualDevice( nBitCount );
#else
    return new AquaSalVirtualDevice( static_cast< AquaSalGraphics* >( pGraphics ), nDX, nDY, nBitCount, pData );
#endif
}

// -----------------------------------------------------------------------

void AquaSalInstance::DestroyVirtualDevice( SalVirtualDevice* pDevice )
{
    delete pDevice;
}

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

AquaSalVirtualDevice::AquaSalVirtualDevice( AquaSalGraphics* pGraphic, long nDX, long nDY, sal_uInt16 nBitCount, const SystemGraphicsData *pData )
:   mbGraphicsUsed( false )
,   mxBitmapContext( NULL )
,   mnBitmapDepth( 0 )
,   mxLayer( NULL )
{
    if( pGraphic && pData && pData->rCGContext )
    {
        // Create virtual device based on existing SystemGraphicsData
        // We ignore nDx and nDY, as the desired size comes from the SystemGraphicsData.
        // WTF does the above mean, SystemGraphicsData has no size field(s).
        mbForeignContext = true;        // the mxContext is from pData
        mpGraphics = new AquaSalGraphics( /*pGraphic*/ );
#ifdef IOS
        // Note: we should *not* create a CGLayer and assign it to
        // mxLayer here. Don't confuse CGLayer and CALayer. A CGLayer
        // is basically a fancy off-screen bitmap not related to
        // anything being displayed at all. The CGContext passed in
        // here refers to something actively part of the compositor
        // stack and being dislayed on the device, and *there*
        // CALayers are involved, sure. The use of mxLayer in this
        // code is for "traditional" LO virtual devices, off-screen
        // bitmaps. I think. On the other hand, the use of
        // VirtualDevice with a "foreign" CGContext for OS X is
        // actually dead code...
#endif
        mpGraphics->SetVirDevGraphics( mxLayer, pData->rCGContext );
    }
    else
    {
        // create empty new virtual device
        mbForeignContext = false;           // the mxContext is created within VCL
        mpGraphics = new AquaSalGraphics(); // never fails
        mnBitmapDepth = nBitCount;
#ifdef MACOSX
        // inherit resolution from reference device
        if( pGraphic )
        {
            AquaSalFrame* pFrame = pGraphic->getGraphicsFrame();
            if( pFrame && AquaSalFrame::isAlive( pFrame ) )
            {
                mpGraphics->setGraphicsFrame( pFrame );
                mpGraphics->copyResolution( *pGraphic );
            }
        }
#endif
        if( nDX && nDY )
            SetSize( nDX, nDY );

        // NOTE: if SetSize does not succeed, we just ignore the nDX and nDY
    }
}

// -----------------------------------------------------------------------

AquaSalVirtualDevice::~AquaSalVirtualDevice()
{
    if( mpGraphics )
    {
        mpGraphics->SetVirDevGraphics( NULL, NULL );
        delete mpGraphics;
        mpGraphics = 0;
    }
    Destroy();
}

// -----------------------------------------------------------------------

void AquaSalVirtualDevice::Destroy()
{
    if( mbForeignContext ) {
        // Do not delete mxContext that we have received from outside VCL
        mxLayer = NULL;
        return;
    }

    if( mxLayer )
    {
        if( mpGraphics )
            mpGraphics->SetVirDevGraphics( NULL, NULL );
        CGLayerRelease( mxLayer );
        mxLayer = NULL;
    }

    if( mxBitmapContext )
    {
        void* pRawData = CGBitmapContextGetData( mxBitmapContext );
        rtl_freeMemory( pRawData );
        CGContextRelease( mxBitmapContext );
        mxBitmapContext = NULL;
    }
}

// -----------------------------------------------------------------------

SalGraphics* AquaSalVirtualDevice::GetGraphics()
{
    if( mbGraphicsUsed || !mpGraphics )
        return 0;

    mbGraphicsUsed = true;
    return mpGraphics;
}

// -----------------------------------------------------------------------

void AquaSalVirtualDevice::ReleaseGraphics( SalGraphics* )
{
    mbGraphicsUsed = false;
}

// -----------------------------------------------------------------------

sal_Bool AquaSalVirtualDevice::SetSize( long nDX, long nDY )
{
#ifdef IOS
    (void) nDX;
    (void) nDY;
    assert(mbForeignContext);
#endif

    if( mbForeignContext )
    {
        // Do not delete/resize mxContext that we have received from outside VCL
        return true;
    }

#ifdef IOS
    return false;
#else
    if( mxLayer )
    {
        const CGSize aSize = CGLayerGetSize( mxLayer );
        if( (nDX == aSize.width) && (nDY == aSize.height) )
        {
            // Yay, we do not have to do anything :)
            return true;
        }
    }

    Destroy();

    // create a Quartz layer matching to the intended virdev usage
    CGContextRef xCGContext = NULL;
    if( mnBitmapDepth && (mnBitmapDepth < 16) )
    {
        mnBitmapDepth = 8;  // TODO: are 1bit vdevs worth it?
        const CGColorSpaceRef aCGColorSpace = GetSalData()->mxGraySpace;
        const CGBitmapInfo aCGBmpInfo = kCGImageAlphaNone;
        const int nBytesPerRow = (mnBitmapDepth * nDX + 7) / 8;

        void* pRawData = rtl_allocateMemory( nBytesPerRow * nDY );
        mxBitmapContext = CGBitmapContextCreate( pRawData, nDX, nDY,
                                                 mnBitmapDepth, nBytesPerRow, aCGColorSpace, aCGBmpInfo );
        xCGContext = mxBitmapContext;
    }
    else
    {
        // default to a NSView target context
        AquaSalFrame* pSalFrame = mpGraphics->getGraphicsFrame();
        if( !pSalFrame || !AquaSalFrame::isAlive( pSalFrame ))
        {
            if( !GetSalData()->maFrames.empty() )
            {
                // get the first matching frame
                pSalFrame = *GetSalData()->maFrames.begin();
            }
            else
            {
                // ensure we don't reuse a dead AquaSalFrame on the very
                // unlikely case of no other frame to use
                pSalFrame = NULL;
            }
            // update the frame reference
            mpGraphics->setGraphicsFrame( pSalFrame );
        }
        if( pSalFrame )
        {
            // #i91990#
            NSWindow* pNSWindow = pSalFrame->getNSWindow();
            if ( pNSWindow )
            {
                NSGraphicsContext* pNSContext = [NSGraphicsContext graphicsContextWithWindow: pNSWindow];
                if( pNSContext )
                    xCGContext = reinterpret_cast<CGContextRef>([pNSContext graphicsPort]);
            }
            else
            {
                // fall back to a bitmap context
                mnBitmapDepth = 32;
                const CGColorSpaceRef aCGColorSpace = GetSalData()->mxRGBSpace;
                const CGBitmapInfo aCGBmpInfo = kCGImageAlphaNoneSkipFirst;
                const int nBytesPerRow = (mnBitmapDepth * nDX) / 8;

                void* pRawData = rtl_allocateMemory( nBytesPerRow * nDY );
                mxBitmapContext = CGBitmapContextCreate( pRawData, nDX, nDY,
                                                         8, nBytesPerRow, aCGColorSpace, aCGBmpInfo );
                xCGContext = mxBitmapContext;
            }
        }
    }

    DBG_ASSERT( xCGContext, "no context" );

    const CGSize aNewSize = { static_cast<CGFloat>(nDX), static_cast<CGFloat>(nDY) };
    mxLayer = CGLayerCreateWithContext( xCGContext, aNewSize, NULL );

    if( mxLayer && mpGraphics )
    {
        // get the matching Quartz context
        CGContextRef xDrawContext = CGLayerGetContext( mxLayer );
        mpGraphics->SetVirDevGraphics( mxLayer, xDrawContext, mnBitmapDepth );
    }

    return (mxLayer != NULL);
#endif
}

// -----------------------------------------------------------------------

void AquaSalVirtualDevice::GetSize( long& rWidth, long& rHeight )
{
    if( mxLayer )
    {
        const CGSize aSize = CGLayerGetSize( mxLayer );
        rWidth = static_cast<long>(aSize.width);
        rHeight = static_cast<long>(aSize.height);
    }
    else
    {
        rWidth = 0;
        rHeight = 0;
    }
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium 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 3
of the License, or (at your option) any later version.

Bohrium 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 General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#include <cassert>
#include <cstring>
#include <iostream>
#include <bh.h>
#include "timing.h"
#include <set>

static int sleep = -1;

//Sleep a period based on BH_VEM_PROXY_SLEEP (in ms)
void timing_sleep(void)
{
    if(sleep == -1)
    {
        const char *str = getenv("BH_VEM_PROXY_SLEEP");
        if(str == NULL)
            sleep = 0;
        else
            sleep = atoi(str);
        printf("sleep enabled: %dms\n", sleep);
    }
    if(sleep == 0)
        return;

    struct timespec tim, tim2;
    tim.tv_sec = sleep/1000000;
    tim.tv_nsec = sleep%1000000 * 1000;

    if(nanosleep(&tim , &tim2) < 0 )
        printf("Nano sleep system call failed \n");
}

<commit_msg>fixed name conflict<commit_after>/*
This file is part of Bohrium and copyright (c) 2012 the Bohrium
team <http://www.bh107.org>.

Bohrium 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 3
of the License, or (at your option) any later version.

Bohrium 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 General Public License for more details.

You should have received a copy of the
GNU Lesser General Public License along with Bohrium.

If not, see <http://www.gnu.org/licenses/>.
*/

#include <cassert>
#include <cstring>
#include <iostream>
#include <bh.h>
#include "timing.h"
#include <set>

static int bh_sleep = -1;

//Sleep a period based on BH_VEM_PROXY_SLEEP (in ms)
void timing_sleep(void)
{
    if(bh_sleep == -1)
    {
        const char *str = getenv("BH_VEM_PROXY_SLEEP");
        if(str == NULL)
            bh_sleep = 0;
        else
            bh_sleep = atoi(str);
        fprintf(stderr,"sleep enabled: %dms\n", bh_sleep);
    }
    if(bh_sleep == 0)
        return;

    struct timespec tim, tim2;
    tim.tv_sec = bh_sleep/1000000;
    tim.tv_nsec = bh_sleep%1000000 * 1000;

    if(nanosleep(&tim , &tim2) < 0 )
        printf("Nano sleep system call failed \n");
}

<|endoftext|>