<commit_before>//= RValues.cpp - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines SVal, Loc, and NonLoc, classes that represent
//  abstract r-values for use with path-sensitive value tracking.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/Support/Streams.h"

using namespace clang;
using llvm::dyn_cast;
using llvm::cast;
using llvm::APSInt;

//===----------------------------------------------------------------------===//
// Symbol iteration within an SVal.
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Utility methods.
//===----------------------------------------------------------------------===//

const FunctionDecl* SVal::getAsFunctionDecl() const {
  if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) {
    const MemRegion* R = X->getRegion();
    if (const CodeTextRegion* CTR = dyn_cast<CodeTextRegion>(R)) {
      if (CTR->isDeclared())
        return CTR->getDecl();
    }
  }

  return 0;
}

/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
///  wraps a symbol, return that SymbolRef.  Otherwise return 0.
// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
SymbolRef SVal::getAsLocSymbol() const {
  if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
    const MemRegion *R = X->getRegion();

    while (R) {
      // Blast through region views.
      if (const TypedViewRegion *View = dyn_cast<TypedViewRegion>(R)) {
        R = View->getSuperRegion();
        continue;
      }

      if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
        return SymR->getSymbol();

      break;
    }
  }

  return 0;
}

/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
///  Otherwise return 0.
// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
SymbolRef SVal::getAsSymbol() const {
  if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
    return X->getSymbol();

  if (const nonloc::SymExprVal *X = dyn_cast<nonloc::SymExprVal>(this))
    if (SymbolRef Y = dyn_cast<SymbolData>(X->getSymbolicExpression()))
      return Y;

  return getAsLocSymbol();
}

/// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
///  return that expression.  Otherwise return NULL.
const SymExpr *SVal::getAsSymbolicExpression() const {
  if (const nonloc::SymExprVal *X = dyn_cast<nonloc::SymExprVal>(this))
    return X->getSymbolicExpression();

  return getAsSymbol();
}

bool SVal::symbol_iterator::operator==(const symbol_iterator &X) const {
  return itr == X.itr;
}

bool SVal::symbol_iterator::operator!=(const symbol_iterator &X) const {
  return itr != X.itr;
}

SVal::symbol_iterator::symbol_iterator(const SymExpr *SE) {
  itr.push_back(SE);
  while (!isa<SymbolData>(itr.back())) expand();
}

SVal::symbol_iterator& SVal::symbol_iterator::operator++() {
  assert(!itr.empty() && "attempting to iterate on an 'end' iterator");
  assert(isa<SymbolData>(itr.back()));
  itr.pop_back();
  if (!itr.empty())
    while (!isa<SymbolData>(itr.back())) expand();
  return *this;
}

SymbolRef SVal::symbol_iterator::operator*() {
  assert(!itr.empty() && "attempting to dereference an 'end' iterator");
  return cast<SymbolData>(itr.back());
}

void SVal::symbol_iterator::expand() {
  const SymExpr *SE = itr.back();
  itr.pop_back();

  if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
    itr.push_back(SIE->getLHS());
    return;
  }
  else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
    itr.push_back(SSE->getLHS());
    itr.push_back(SSE->getRHS());
    return;
  }

  assert(false && "unhandled expansion case");
}

//===----------------------------------------------------------------------===//
// Other Iterators.
//===----------------------------------------------------------------------===//

nonloc::CompoundVal::iterator nonloc::CompoundVal::begin() const {
  return getValue()->begin();
}

nonloc::CompoundVal::iterator nonloc::CompoundVal::end() const {
  return getValue()->end();
}

//===----------------------------------------------------------------------===//
// Useful predicates.
//===----------------------------------------------------------------------===//

bool SVal::isZeroConstant() const {
  if (isa<loc::ConcreteInt>(*this))
    return cast<loc::ConcreteInt>(*this).getValue() == 0;
  else if (isa<nonloc::ConcreteInt>(*this))
    return cast<nonloc::ConcreteInt>(*this).getValue() == 0;
  else
    return false;
}

//===----------------------------------------------------------------------===//
// Transfer function dispatch for Non-Locs.
//===----------------------------------------------------------------------===//

SVal nonloc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
                                     BinaryOperator::Opcode Op,
                                     const nonloc::ConcreteInt& R) const {

  const llvm::APSInt* X =
    BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());

  if (X)
    return nonloc::ConcreteInt(*X);
  else
    return UndefinedVal();
}

  // Bitwise-Complement.

nonloc::ConcreteInt
nonloc::ConcreteInt::EvalComplement(BasicValueFactory& BasicVals) const {
  return BasicVals.getValue(~getValue());
}

  // Unary Minus.

nonloc::ConcreteInt
nonloc::ConcreteInt::EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const {
  assert (U->getType() == U->getSubExpr()->getType());
  assert (U->getType()->isIntegerType());
  return BasicVals.getValue(-getValue());
}

//===----------------------------------------------------------------------===//
// Transfer function dispatch for Locs.
//===----------------------------------------------------------------------===//

SVal loc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
                                 BinaryOperator::Opcode Op,
                                 const loc::ConcreteInt& R) const {

  assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
          (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));

  const llvm::APSInt* X = BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());

  if (X)
    return loc::ConcreteInt(*X);
  else
    return UndefinedVal();
}

//===----------------------------------------------------------------------===//
// Utility methods for constructing SVals.
//===----------------------------------------------------------------------===//

SVal ValueManager::makeZeroVal(QualType T) {
  if (Loc::IsLocType(T))
    return Loc::MakeNull(BasicVals);

  if (T->isIntegerType())
    return NonLoc::MakeVal(BasicVals, 0, T);

  // FIXME: Handle floats.
  // FIXME: Handle structs.
  return UnknownVal();
}

//===----------------------------------------------------------------------===//
// Utility methods for constructing Non-Locs.
//===----------------------------------------------------------------------===//

NonLoc ValueManager::makeNonLoc(SymbolRef sym) {
  return nonloc::SymbolVal(sym);
}

NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
                                const APSInt& v, QualType T) {
  // The Environment ensures we always get a persistent APSInt in
  // BasicValueFactory, so we don't need to get the APSInt from
  // BasicValueFactory again.
  assert(!Loc::IsLocType(T));
  return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, v, T));
}

NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
                                const SymExpr *rhs, QualType T) {
  assert(SymMgr.getType(lhs) == SymMgr.getType(rhs));
  assert(!Loc::IsLocType(T));
  return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T));
}

NonLoc NonLoc::MakeIntVal(BasicValueFactory& BasicVals, uint64_t X,
                          bool isUnsigned) {
  return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned));
}

NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X,
                       unsigned BitWidth, bool isUnsigned) {
  return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned));
}

NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T) {
  return nonloc::ConcreteInt(BasicVals.getValue(X, T));
}

NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I) {

  return nonloc::ConcreteInt(BasicVals.getValue(APSInt(I->getValue(),
                              I->getType()->isUnsignedIntegerType())));
}

NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I,
                       bool isUnsigned) {
  return nonloc::ConcreteInt(BasicVals.getValue(I, isUnsigned));
}

NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APSInt& I) {
  return nonloc::ConcreteInt(BasicVals.getValue(I));
}

NonLoc NonLoc::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) {
  return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
}

NonLoc ValueManager::makeTruthVal(bool b, QualType T) {
  return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T));
}

NonLoc NonLoc::MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
                               BasicValueFactory& BasicVals) {
  return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
}

SVal ValueManager::getRValueSymbolVal(const MemRegion* R) {
  SymbolRef sym = SymMgr.getRegionRValueSymbol(R);

  if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
    QualType T = TR->getRValueType(SymMgr.getContext());

    // If T is of function pointer type, create a CodeTextRegion wrapping a
    // symbol.
    if (T->isFunctionPointerType()) {
      return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T));
    }

    if (Loc::IsLocType(T))
      return Loc::MakeVal(MemMgr.getSymbolicRegion(sym));

    // Only handle integers for now.
    if (T->isIntegerType() && T->isScalarType())
      return makeNonLoc(sym);
  }

  return UnknownVal();
}

SVal ValueManager::getConjuredSymbolVal(const Expr* E, unsigned Count) {
  QualType T = E->getType();
  SymbolRef sym = SymMgr.getConjuredSymbol(E, Count);

  // If T is of function pointer type, create a CodeTextRegion wrapping a
  // symbol.
  if (T->isFunctionPointerType()) {
    return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T));
  }

  if (Loc::IsLocType(T))
    return Loc::MakeVal(MemMgr.getSymbolicRegion(sym));

  if (T->isIntegerType() && T->isScalarType())
    return makeNonLoc(sym);

  return UnknownVal();
}

SVal ValueManager::getConjuredSymbolVal(const Expr* E, QualType T,
                                        unsigned Count) {

  SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count);

  // If T is of function pointer type, create a CodeTextRegion wrapping a
  // symbol.
  if (T->isFunctionPointerType()) {
    return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T));
  }

  if (Loc::IsLocType(T))
    return Loc::MakeVal(MemMgr.getSymbolicRegion(sym));

  if (T->isIntegerType() && T->isScalarType())
    return makeNonLoc(sym);

  return UnknownVal();
}

SVal ValueManager::getFunctionPointer(const FunctionDecl* FD) {
  CodeTextRegion* R
    = MemMgr.getCodeTextRegion(FD, Context.getPointerType(FD->getType()));
  return loc::MemRegionVal(R);
}

nonloc::LocAsInteger nonloc::LocAsInteger::Make(BasicValueFactory& Vals, Loc V,
                                                unsigned Bits) {
  return LocAsInteger(Vals.getPersistentSValWithData(V, Bits));
}

//===----------------------------------------------------------------------===//
// Utility methods for constructing Locs.
//===----------------------------------------------------------------------===//

Loc Loc::MakeVal(const MemRegion* R) { return loc::MemRegionVal(R); }

Loc Loc::MakeVal(AddrLabelExpr* E) { return loc::GotoLabel(E->getLabel()); }

Loc Loc::MakeNull(BasicValueFactory &BasicVals) {
  return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth());
}

//===----------------------------------------------------------------------===//
// Pretty-Printing.
//===----------------------------------------------------------------------===//

void SVal::printStdErr() const { print(llvm::errs()); }

void SVal::print(std::ostream& Out) const {
  llvm::raw_os_ostream out(Out);
  print(out);
}

void SVal::print(llvm::raw_ostream& Out) const {

  switch (getBaseKind()) {

    case UnknownKind:
      Out << "Invalid"; break;

    case NonLocKind:
      cast<NonLoc>(this)->print(Out); break;

    case LocKind:
      cast<Loc>(this)->print(Out); break;

    case UndefinedKind:
      Out << "Undefined"; break;

    default:
      assert (false && "Invalid SVal.");
  }
}

void NonLoc::print(llvm::raw_ostream& Out) const {

  switch (getSubKind()) {

    case nonloc::ConcreteIntKind:
      Out << cast<nonloc::ConcreteInt>(this)->getValue().getZExtValue();

      if (cast<nonloc::ConcreteInt>(this)->getValue().isUnsigned())
        Out << 'U';

      break;

    case nonloc::SymbolValKind:
      Out << '$' << cast<nonloc::SymbolVal>(this)->getSymbol();
      break;

    case nonloc::SymExprValKind: {
      const nonloc::SymExprVal& C = *cast<nonloc::SymExprVal>(this);
      const SymExpr *SE = C.getSymbolicExpression();
      Out << SE;
      break;
    }

    case nonloc::LocAsIntegerKind: {
      const nonloc::LocAsInteger& C = *cast<nonloc::LocAsInteger>(this);
      C.getLoc().print(Out);
      Out << " [as " << C.getNumBits() << " bit integer]";
      break;
    }

    case nonloc::CompoundValKind: {
      const nonloc::CompoundVal& C = *cast<nonloc::CompoundVal>(this);
      Out << " {";
      bool first = true;
      for (nonloc::CompoundVal::iterator I=C.begin(), E=C.end(); I!=E; ++I) {
        if (first) { Out << ' '; first = false; }
        else Out << ", ";
        (*I).print(Out);
      }
      Out << " }";
      break;
    }

    default:
      assert (false && "Pretty-printed not implemented for this NonLoc.");
      break;
  }
}

void Loc::print(llvm::raw_ostream& Out) const {

  switch (getSubKind()) {

    case loc::ConcreteIntKind:
      Out << cast<loc::ConcreteInt>(this)->getValue().getZExtValue()
          << " (Loc)";
      break;

    case loc::GotoLabelKind:
      Out << "&&"
          << cast<loc::GotoLabel>(this)->getLabel()->getID()->getName();
      break;

    case loc::MemRegionKind:
      Out << '&' << cast<loc::MemRegionVal>(this)->getRegion()->getString();
      break;

    default:
      assert (false && "Pretty-printing not implemented for this Loc.");
      break;
  }
}
<commit_msg>Use 'getAs<CodeTextRegion>' instead of 'dyn_cast<CodeTextRegion>' to handle any layered regions.<commit_after>//= RValues.cpp - Abstract RValues for Path-Sens. Value Tracking -*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines SVal, Loc, and NonLoc, classes that represent
//  abstract r-values for use with path-sensitive value tracking.
//
//===----------------------------------------------------------------------===//

#include "clang/Analysis/PathSensitive/GRState.h"
#include "clang/Basic/IdentifierTable.h"
#include "llvm/Support/Streams.h"

using namespace clang;
using llvm::dyn_cast;
using llvm::cast;
using llvm::APSInt;

//===----------------------------------------------------------------------===//
// Symbol iteration within an SVal.
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// Utility methods.
//===----------------------------------------------------------------------===//

const FunctionDecl* SVal::getAsFunctionDecl() const {
  if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) {
    const MemRegion* R = X->getRegion();
    if (const CodeTextRegion* CTR = R->getAs<CodeTextRegion>()) {
      if (CTR->isDeclared())
        return CTR->getDecl();
    }
  }

  return 0;
}

/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and
///  wraps a symbol, return that SymbolRef.  Otherwise return 0.
// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
SymbolRef SVal::getAsLocSymbol() const {
  if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
    const MemRegion *R = X->getRegion();

    while (R) {
      // Blast through region views.
      if (const TypedViewRegion *View = dyn_cast<TypedViewRegion>(R)) {
        R = View->getSuperRegion();
        continue;
      }

      if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
        return SymR->getSymbol();

      break;
    }
  }

  return 0;
}

/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
///  Otherwise return 0.
// FIXME: should we consider SymbolRef wrapped in CodeTextRegion?
SymbolRef SVal::getAsSymbol() const {
  if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
    return X->getSymbol();

  if (const nonloc::SymExprVal *X = dyn_cast<nonloc::SymExprVal>(this))
    if (SymbolRef Y = dyn_cast<SymbolData>(X->getSymbolicExpression()))
      return Y;

  return getAsLocSymbol();
}

/// getAsSymbolicExpression - If this Sval wraps a symbolic expression then
///  return that expression.  Otherwise return NULL.
const SymExpr *SVal::getAsSymbolicExpression() const {
  if (const nonloc::SymExprVal *X = dyn_cast<nonloc::SymExprVal>(this))
    return X->getSymbolicExpression();

  return getAsSymbol();
}

bool SVal::symbol_iterator::operator==(const symbol_iterator &X) const {
  return itr == X.itr;
}

bool SVal::symbol_iterator::operator!=(const symbol_iterator &X) const {
  return itr != X.itr;
}

SVal::symbol_iterator::symbol_iterator(const SymExpr *SE) {
  itr.push_back(SE);
  while (!isa<SymbolData>(itr.back())) expand();
}

SVal::symbol_iterator& SVal::symbol_iterator::operator++() {
  assert(!itr.empty() && "attempting to iterate on an 'end' iterator");
  assert(isa<SymbolData>(itr.back()));
  itr.pop_back();
  if (!itr.empty())
    while (!isa<SymbolData>(itr.back())) expand();
  return *this;
}

SymbolRef SVal::symbol_iterator::operator*() {
  assert(!itr.empty() && "attempting to dereference an 'end' iterator");
  return cast<SymbolData>(itr.back());
}

void SVal::symbol_iterator::expand() {
  const SymExpr *SE = itr.back();
  itr.pop_back();

  if (const SymIntExpr *SIE = dyn_cast<SymIntExpr>(SE)) {
    itr.push_back(SIE->getLHS());
    return;
  }
  else if (const SymSymExpr *SSE = dyn_cast<SymSymExpr>(SE)) {
    itr.push_back(SSE->getLHS());
    itr.push_back(SSE->getRHS());
    return;
  }

  assert(false && "unhandled expansion case");
}

//===----------------------------------------------------------------------===//
// Other Iterators.
//===----------------------------------------------------------------------===//

nonloc::CompoundVal::iterator nonloc::CompoundVal::begin() const {
  return getValue()->begin();
}

nonloc::CompoundVal::iterator nonloc::CompoundVal::end() const {
  return getValue()->end();
}

//===----------------------------------------------------------------------===//
// Useful predicates.
//===----------------------------------------------------------------------===//

bool SVal::isZeroConstant() const {
  if (isa<loc::ConcreteInt>(*this))
    return cast<loc::ConcreteInt>(*this).getValue() == 0;
  else if (isa<nonloc::ConcreteInt>(*this))
    return cast<nonloc::ConcreteInt>(*this).getValue() == 0;
  else
    return false;
}

//===----------------------------------------------------------------------===//
// Transfer function dispatch for Non-Locs.
//===----------------------------------------------------------------------===//

SVal nonloc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
                                     BinaryOperator::Opcode Op,
                                     const nonloc::ConcreteInt& R) const {

  const llvm::APSInt* X =
    BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());

  if (X)
    return nonloc::ConcreteInt(*X);
  else
    return UndefinedVal();
}

  // Bitwise-Complement.

nonloc::ConcreteInt
nonloc::ConcreteInt::EvalComplement(BasicValueFactory& BasicVals) const {
  return BasicVals.getValue(~getValue());
}

  // Unary Minus.

nonloc::ConcreteInt
nonloc::ConcreteInt::EvalMinus(BasicValueFactory& BasicVals, UnaryOperator* U) const {
  assert (U->getType() == U->getSubExpr()->getType());
  assert (U->getType()->isIntegerType());
  return BasicVals.getValue(-getValue());
}

//===----------------------------------------------------------------------===//
// Transfer function dispatch for Locs.
//===----------------------------------------------------------------------===//

SVal loc::ConcreteInt::EvalBinOp(BasicValueFactory& BasicVals,
                                 BinaryOperator::Opcode Op,
                                 const loc::ConcreteInt& R) const {

  assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub ||
          (Op >= BinaryOperator::LT && Op <= BinaryOperator::NE));

  const llvm::APSInt* X = BasicVals.EvaluateAPSInt(Op, getValue(), R.getValue());

  if (X)
    return loc::ConcreteInt(*X);
  else
    return UndefinedVal();
}

//===----------------------------------------------------------------------===//
// Utility methods for constructing SVals.
//===----------------------------------------------------------------------===//

SVal ValueManager::makeZeroVal(QualType T) {
  if (Loc::IsLocType(T))
    return Loc::MakeNull(BasicVals);

  if (T->isIntegerType())
    return NonLoc::MakeVal(BasicVals, 0, T);

  // FIXME: Handle floats.
  // FIXME: Handle structs.
  return UnknownVal();
}

//===----------------------------------------------------------------------===//
// Utility methods for constructing Non-Locs.
//===----------------------------------------------------------------------===//

NonLoc ValueManager::makeNonLoc(SymbolRef sym) {
  return nonloc::SymbolVal(sym);
}

NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
                                const APSInt& v, QualType T) {
  // The Environment ensures we always get a persistent APSInt in
  // BasicValueFactory, so we don't need to get the APSInt from
  // BasicValueFactory again.
  assert(!Loc::IsLocType(T));
  return nonloc::SymExprVal(SymMgr.getSymIntExpr(lhs, op, v, T));
}

NonLoc ValueManager::makeNonLoc(const SymExpr *lhs, BinaryOperator::Opcode op,
                                const SymExpr *rhs, QualType T) {
  assert(SymMgr.getType(lhs) == SymMgr.getType(rhs));
  assert(!Loc::IsLocType(T));
  return nonloc::SymExprVal(SymMgr.getSymSymExpr(lhs, op, rhs, T));
}

NonLoc NonLoc::MakeIntVal(BasicValueFactory& BasicVals, uint64_t X,
                          bool isUnsigned) {
  return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned));
}

NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X,
                       unsigned BitWidth, bool isUnsigned) {
  return nonloc::ConcreteInt(BasicVals.getValue(X, BitWidth, isUnsigned));
}

NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T) {
  return nonloc::ConcreteInt(BasicVals.getValue(X, T));
}

NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, IntegerLiteral* I) {

  return nonloc::ConcreteInt(BasicVals.getValue(APSInt(I->getValue(),
                              I->getType()->isUnsignedIntegerType())));
}

NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APInt& I,
                       bool isUnsigned) {
  return nonloc::ConcreteInt(BasicVals.getValue(I, isUnsigned));
}

NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, const llvm::APSInt& I) {
  return nonloc::ConcreteInt(BasicVals.getValue(I));
}

NonLoc NonLoc::MakeIntTruthVal(BasicValueFactory& BasicVals, bool b) {
  return nonloc::ConcreteInt(BasicVals.getTruthValue(b));
}

NonLoc ValueManager::makeTruthVal(bool b, QualType T) {
  return nonloc::ConcreteInt(BasicVals.getTruthValue(b, T));
}

NonLoc NonLoc::MakeCompoundVal(QualType T, llvm::ImmutableList<SVal> Vals,
                               BasicValueFactory& BasicVals) {
  return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals));
}

SVal ValueManager::getRValueSymbolVal(const MemRegion* R) {
  SymbolRef sym = SymMgr.getRegionRValueSymbol(R);

  if (const TypedRegion* TR = dyn_cast<TypedRegion>(R)) {
    QualType T = TR->getRValueType(SymMgr.getContext());

    // If T is of function pointer type, create a CodeTextRegion wrapping a
    // symbol.
    if (T->isFunctionPointerType()) {
      return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T));
    }

    if (Loc::IsLocType(T))
      return Loc::MakeVal(MemMgr.getSymbolicRegion(sym));

    // Only handle integers for now.
    if (T->isIntegerType() && T->isScalarType())
      return makeNonLoc(sym);
  }

  return UnknownVal();
}

SVal ValueManager::getConjuredSymbolVal(const Expr* E, unsigned Count) {
  QualType T = E->getType();
  SymbolRef sym = SymMgr.getConjuredSymbol(E, Count);

  // If T is of function pointer type, create a CodeTextRegion wrapping a
  // symbol.
  if (T->isFunctionPointerType()) {
    return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T));
  }

  if (Loc::IsLocType(T))
    return Loc::MakeVal(MemMgr.getSymbolicRegion(sym));

  if (T->isIntegerType() && T->isScalarType())
    return makeNonLoc(sym);

  return UnknownVal();
}

SVal ValueManager::getConjuredSymbolVal(const Expr* E, QualType T,
                                        unsigned Count) {

  SymbolRef sym = SymMgr.getConjuredSymbol(E, T, Count);

  // If T is of function pointer type, create a CodeTextRegion wrapping a
  // symbol.
  if (T->isFunctionPointerType()) {
    return Loc::MakeVal(MemMgr.getCodeTextRegion(sym, T));
  }

  if (Loc::IsLocType(T))
    return Loc::MakeVal(MemMgr.getSymbolicRegion(sym));

  if (T->isIntegerType() && T->isScalarType())
    return makeNonLoc(sym);

  return UnknownVal();
}

SVal ValueManager::getFunctionPointer(const FunctionDecl* FD) {
  CodeTextRegion* R
    = MemMgr.getCodeTextRegion(FD, Context.getPointerType(FD->getType()));
  return loc::MemRegionVal(R);
}

nonloc::LocAsInteger nonloc::LocAsInteger::Make(BasicValueFactory& Vals, Loc V,
                                                unsigned Bits) {
  return LocAsInteger(Vals.getPersistentSValWithData(V, Bits));
}

//===----------------------------------------------------------------------===//
// Utility methods for constructing Locs.
//===----------------------------------------------------------------------===//

Loc Loc::MakeVal(const MemRegion* R) { return loc::MemRegionVal(R); }

Loc Loc::MakeVal(AddrLabelExpr* E) { return loc::GotoLabel(E->getLabel()); }

Loc Loc::MakeNull(BasicValueFactory &BasicVals) {
  return loc::ConcreteInt(BasicVals.getZeroWithPtrWidth());
}

//===----------------------------------------------------------------------===//
// Pretty-Printing.
//===----------------------------------------------------------------------===//

void SVal::printStdErr() const { print(llvm::errs()); }

void SVal::print(std::ostream& Out) const {
  llvm::raw_os_ostream out(Out);
  print(out);
}

void SVal::print(llvm::raw_ostream& Out) const {

  switch (getBaseKind()) {

    case UnknownKind:
      Out << "Invalid"; break;

    case NonLocKind:
      cast<NonLoc>(this)->print(Out); break;

    case LocKind:
      cast<Loc>(this)->print(Out); break;

    case UndefinedKind:
      Out << "Undefined"; break;

    default:
      assert (false && "Invalid SVal.");
  }
}

void NonLoc::print(llvm::raw_ostream& Out) const {

  switch (getSubKind()) {

    case nonloc::ConcreteIntKind:
      Out << cast<nonloc::ConcreteInt>(this)->getValue().getZExtValue();

      if (cast<nonloc::ConcreteInt>(this)->getValue().isUnsigned())
        Out << 'U';

      break;

    case nonloc::SymbolValKind:
      Out << '$' << cast<nonloc::SymbolVal>(this)->getSymbol();
      break;

    case nonloc::SymExprValKind: {
      const nonloc::SymExprVal& C = *cast<nonloc::SymExprVal>(this);
      const SymExpr *SE = C.getSymbolicExpression();
      Out << SE;
      break;
    }

    case nonloc::LocAsIntegerKind: {
      const nonloc::LocAsInteger& C = *cast<nonloc::LocAsInteger>(this);
      C.getLoc().print(Out);
      Out << " [as " << C.getNumBits() << " bit integer]";
      break;
    }

    case nonloc::CompoundValKind: {
      const nonloc::CompoundVal& C = *cast<nonloc::CompoundVal>(this);
      Out << " {";
      bool first = true;
      for (nonloc::CompoundVal::iterator I=C.begin(), E=C.end(); I!=E; ++I) {
        if (first) { Out << ' '; first = false; }
        else Out << ", ";
        (*I).print(Out);
      }
      Out << " }";
      break;
    }

    default:
      assert (false && "Pretty-printed not implemented for this NonLoc.");
      break;
  }
}

void Loc::print(llvm::raw_ostream& Out) const {

  switch (getSubKind()) {

    case loc::ConcreteIntKind:
      Out << cast<loc::ConcreteInt>(this)->getValue().getZExtValue()
          << " (Loc)";
      break;

    case loc::GotoLabelKind:
      Out << "&&"
          << cast<loc::GotoLabel>(this)->getLabel()->getID()->getName();
      break;

    case loc::MemRegionKind:
      Out << '&' << cast<loc::MemRegionVal>(this)->getRegion()->getString();
      break;

    default:
      assert (false && "Pretty-printing not implemented for this Loc.");
      break;
  }
}
<|endoftext|>


<commit_before>//===--- Link.cpp - Link in transparent SILFunctions from module ----------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SILPasses/Passes.h"
#include "swift/SILPasses/Transforms.h"
#include "swift/SIL/SILModule.h"

using namespace swift;

//===----------------------------------------------------------------------===//
//                          Top Level Driver
//===----------------------------------------------------------------------===//

void swift::performSILLinking(SILModule *M, bool LinkAll) {
  auto LinkMode = LinkAll? SILModule::LinkingMode::LinkAll :
    SILModule::LinkingMode::LinkNormal;
  for (auto &Fn : *M)
    M->linkFunction(&Fn, LinkMode);

  if (!LinkAll)
    return;

  M->linkAllWitnessTables();
  M->linkAllVTables();
}

namespace {

class SILLinker : public SILModuleTransform {

  /// The entry point to the transformation.
  void run() {
    // Remove dead stores, merge duplicate loads, and forward stores to loads.
    bool Changed = false;
    SILModule &M = *getModule();
    for (auto &Fn : M)
      Changed |= M.linkFunction(&Fn, SILModule::LinkingMode::LinkAll);

    if (Changed)
      invalidateAnalysis(SILAnalysis::InvalidationKind::CallGraph);
  }

  StringRef getName() override { return "SIL Linker"; }
};
} // end anonymous namespace

SILTransform *swift::createSILLinker() {
  return new SILLinker();
}
<commit_msg>The linker pass can import new vtables. Flush all analysis.<commit_after>//===--- Link.cpp - Link in transparent SILFunctions from module ----------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/SILPasses/Passes.h"
#include "swift/SILPasses/Transforms.h"
#include "swift/SIL/SILModule.h"

using namespace swift;

//===----------------------------------------------------------------------===//
//                          Top Level Driver
//===----------------------------------------------------------------------===//

void swift::performSILLinking(SILModule *M, bool LinkAll) {
  auto LinkMode = LinkAll? SILModule::LinkingMode::LinkAll :
    SILModule::LinkingMode::LinkNormal;
  for (auto &Fn : *M)
    M->linkFunction(&Fn, LinkMode);

  if (!LinkAll)
    return;

  M->linkAllWitnessTables();
  M->linkAllVTables();
}

namespace {

class SILLinker : public SILModuleTransform {

  /// The entry point to the transformation.
  void run() {
    // Remove dead stores, merge duplicate loads, and forward stores to loads.
    bool Changed = false;
    SILModule &M = *getModule();
    for (auto &Fn : M)
      Changed |= M.linkFunction(&Fn, SILModule::LinkingMode::LinkAll);

    if (Changed)
      invalidateAnalysis(SILAnalysis::InvalidationKind::All);
  }

  StringRef getName() override { return "SIL Linker"; }
};
} // end anonymous namespace

SILTransform *swift::createSILLinker() {
  return new SILLinker();
}
<|endoftext|>


<commit_before>//===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This header file implements atomic operations.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/Atomic.h"
#include "llvm/Config/llvm-config.h"

using namespace llvm;

#if defined(_MSC_VER)
#include <windows.h>
#undef MemoryFence
#endif

void sys::MemoryFence() {
#if LLVM_HAS_ATOMICS == 0
  return;
#else
#  if defined(__GNUC__)
  __sync_synchronize();
#  elif defined(_MSC_VER)
  MemoryBarrier();
#  else
# error No memory fence implementation for your platform!
#  endif
#endif
}

sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
                                  sys::cas_flag new_value,
                                  sys::cas_flag old_value) {
#if LLVM_HAS_ATOMICS == 0
  sys::cas_flag result = *ptr;
  if (result == old_value)
    *ptr = new_value;
  return result;
#elif defined(__GNUC__)
  return __sync_val_compare_and_swap(ptr, old_value, new_value);
#elif defined(_MSC_VER)
  return InterlockedCompareExchange(ptr, new_value, old_value);
#else
#  error No compare-and-swap implementation for your platform!
#endif
}

sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) {
#if LLVM_HAS_ATOMICS == 0
  ++(*ptr);
  return *ptr;
#elif defined(__GNUC__)
  return __sync_add_and_fetch(ptr, 1);
#elif defined(_MSC_VER)
  return InterlockedIncrement(ptr);
#else
#  error No atomic increment implementation for your platform!
#endif
}

sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) {
#if LLVM_HAS_ATOMICS == 0
  --(*ptr);
  return *ptr;
#elif defined(__GNUC__)
  return __sync_sub_and_fetch(ptr, 1);
#elif defined(_MSC_VER)
  return InterlockedDecrement(ptr);
#else
#  error No atomic decrement implementation for your platform!
#endif
}

sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) {
#if LLVM_HAS_ATOMICS == 0
  *ptr += val;
  return *ptr;
#elif defined(__GNUC__)
  return __sync_add_and_fetch(ptr, val);
#elif defined(_MSC_VER)
  return InterlockedExchangeAdd(ptr, val) + val;
#else
#  error No atomic add implementation for your platform!
#endif
}

sys::cas_flag sys::AtomicMul(volatile sys::cas_flag* ptr, sys::cas_flag val) {
  sys::cas_flag original, result;
  do {
    original = *ptr;
    result = original * val;
  } while (sys::CompareAndSwap(ptr, result, original) != original);

  return result;
}

sys::cas_flag sys::AtomicDiv(volatile sys::cas_flag* ptr, sys::cas_flag val) {
  sys::cas_flag original, result;
  do {
    original = *ptr;
    result = original / val;
  } while (sys::CompareAndSwap(ptr, result, original) != original);

  return result;
}
<commit_msg>XLC supports the same atomic functions as GCC, use them. Patch by Kai.<commit_after>//===-- Atomic.cpp - Atomic Operations --------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This header file implements atomic operations.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/Atomic.h"
#include "llvm/Config/llvm-config.h"

using namespace llvm;

#if defined(_MSC_VER)
#include <windows.h>
#undef MemoryFence
#endif

#if defined(__GNUC__) || (defined(__IBMCPP__) && __IBMCPP__ >= 1210)
#define GNU_ATOMICS
#endif

void sys::MemoryFence() {
#if LLVM_HAS_ATOMICS == 0
  return;
#else
#  if defined(GNU_ATOMICS)
  __sync_synchronize();
#  elif defined(_MSC_VER)
  MemoryBarrier();
#  else
# error No memory fence implementation for your platform!
#  endif
#endif
}

sys::cas_flag sys::CompareAndSwap(volatile sys::cas_flag* ptr,
                                  sys::cas_flag new_value,
                                  sys::cas_flag old_value) {
#if LLVM_HAS_ATOMICS == 0
  sys::cas_flag result = *ptr;
  if (result == old_value)
    *ptr = new_value;
  return result;
#elif defined(GNU_ATOMICS)
  return __sync_val_compare_and_swap(ptr, old_value, new_value);
#elif defined(_MSC_VER)
  return InterlockedCompareExchange(ptr, new_value, old_value);
#else
#  error No compare-and-swap implementation for your platform!
#endif
}

sys::cas_flag sys::AtomicIncrement(volatile sys::cas_flag* ptr) {
#if LLVM_HAS_ATOMICS == 0
  ++(*ptr);
  return *ptr;
#elif defined(GNU_ATOMICS)
  return __sync_add_and_fetch(ptr, 1);
#elif defined(_MSC_VER)
  return InterlockedIncrement(ptr);
#else
#  error No atomic increment implementation for your platform!
#endif
}

sys::cas_flag sys::AtomicDecrement(volatile sys::cas_flag* ptr) {
#if LLVM_HAS_ATOMICS == 0
  --(*ptr);
  return *ptr;
#elif defined(GNU_ATOMICS)
  return __sync_sub_and_fetch(ptr, 1);
#elif defined(_MSC_VER)
  return InterlockedDecrement(ptr);
#else
#  error No atomic decrement implementation for your platform!
#endif
}

sys::cas_flag sys::AtomicAdd(volatile sys::cas_flag* ptr, sys::cas_flag val) {
#if LLVM_HAS_ATOMICS == 0
  *ptr += val;
  return *ptr;
#elif defined(GNU_ATOMICS)
  return __sync_add_and_fetch(ptr, val);
#elif defined(_MSC_VER)
  return InterlockedExchangeAdd(ptr, val) + val;
#else
#  error No atomic add implementation for your platform!
#endif
}

sys::cas_flag sys::AtomicMul(volatile sys::cas_flag* ptr, sys::cas_flag val) {
  sys::cas_flag original, result;
  do {
    original = *ptr;
    result = original * val;
  } while (sys::CompareAndSwap(ptr, result, original) != original);

  return result;
}

sys::cas_flag sys::AtomicDiv(volatile sys::cas_flag* ptr, sys::cas_flag val) {
  sys::cas_flag original, result;
  do {
    original = *ptr;
    result = original / val;
  } while (sys::CompareAndSwap(ptr, result, original) != original);

  return result;
}
<|endoftext|>


<commit_before>//===--- Triple.cpp - Target triple helper class --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/Triple.h"

#include "llvm/ADT/Twine.h"
#include <cassert>
#include <cstring>
using namespace llvm;

//

const char *Triple::getArchTypeName(ArchType Kind) {
  switch (Kind) {
  case InvalidArch: return "<invalid>";
  case UnknownArch: return "unknown";

  case alpha:   return "alpha";
  case arm:     return "arm";
  case bfin:    return "bfin";
  case cellspu: return "cellspu";
  case mips:    return "mips";
  case mipsel:  return "mipsel";
  case msp430:  return "msp430";
  case pic16:   return "pic16";
  case ppc64:   return "powerpc64";
  case ppc:     return "powerpc";
  case sparc:   return "sparc";
  case systemz: return "s390x";
  case tce:     return "tce";
  case thumb:   return "thumb";
  case x86:     return "i386";
  case x86_64:  return "x86_64";
  case xcore:   return "xcore";
  }

  return "<invalid>";
}

const char *Triple::getArchTypePrefix(ArchType Kind) {
  switch (Kind) {
  default:
    return 0;

  case alpha:   return "alpha";

  case arm:
  case thumb:   return "arm";

  case bfin:    return "bfin";

  case cellspu: return "spu";

  case ppc64:
  case ppc:     return "ppc";

  case sparc:   return "sparc";

  case x86:
  case x86_64:  return "x86";
  case xcore:   return "xcore";
  }
}

const char *Triple::getVendorTypeName(VendorType Kind) {
  switch (Kind) {
  case UnknownVendor: return "unknown";

  case Apple: return "apple";
  case PC: return "pc";
  }

  return "<invalid>";
}

const char *Triple::getOSTypeName(OSType Kind) {
  switch (Kind) {
  case UnknownOS: return "unknown";

  case AuroraUX: return "auroraux";
  case Cygwin: return "cygwin";
  case Darwin: return "darwin";
  case DragonFly: return "dragonfly";
  case FreeBSD: return "freebsd";
  case Linux: return "linux";
  case MinGW32: return "mingw32";
  case MinGW64: return "mingw64";
  case NetBSD: return "netbsd";
  case OpenBSD: return "openbsd";
  case Solaris: return "solaris";
  case Win32: return "win32";
  }

  return "<invalid>";
}

Triple::ArchType Triple::getArchTypeForLLVMName(const StringRef &Name) {
  if (Name == "alpha")
    return alpha;
  if (Name == "arm")
    return arm;
  if (Name == "bfin")
    return bfin;
  if (Name == "cellspu")
    return cellspu;
  if (Name == "mips")
    return mips;
  if (Name == "mipsel")
    return mipsel;
  if (Name == "msp430")
    return msp430;
  if (Name == "pic16")
    return pic16;
  if (Name == "ppc64")
    return ppc64;
  if (Name == "ppc")
    return ppc;
  if (Name == "sparc")
    return sparc;
  if (Name == "systemz")
    return systemz;
  if (Name == "tce")
    return tce;
  if (Name == "thumb")
    return thumb;
  if (Name == "x86")
    return x86;
  if (Name == "x86-64")
    return x86_64;
  if (Name == "xcore")
    return xcore;

  return UnknownArch;
}

Triple::ArchType Triple::getArchTypeForDarwinArchName(const StringRef &Str) {
  // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
  // archs which Darwin doesn't use.

  // The matching this routine does is fairly pointless, since it is neither the
  // complete architecture list, nor a reasonable subset. The problem is that
  // historically the driver driver accepts this and also ties its -march=
  // handling to the architecture name, so we need to be careful before removing
  // support for it.

  if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
      Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
      Str == "ppc7450" || Str == "ppc970")
    return Triple::ppc;

  if (Str == "ppc64")
    return Triple::ppc64;

  if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
      Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
      Str == "pentIIm5" || Str == "pentium4")
    return Triple::x86;

  if (Str == "x86_64")
    return Triple::x86_64;

  // This is derived from the driver driver.
  if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
      Str == "armv6" || Str == "armv7")
    return Triple::arm;

  return Triple::UnknownArch;
}

//

void Triple::Parse() const {
  assert(!isInitialized() && "Invalid parse call.");

  StringRef ArchName = getArchName();
  StringRef VendorName = getVendorName();
  StringRef OSName = getOSName();

  if (ArchName.size() == 4 && ArchName[0] == 'i' &&
      ArchName[2] == '8' && ArchName[3] == '6' &&
      ArchName[1] - '3' < 6) // i[3-9]86
    Arch = x86;
  else if (ArchName == "amd64" || ArchName == "x86_64")
    Arch = x86_64;
  else if (ArchName == "bfin")
    Arch = bfin;
  else if (ArchName == "pic16")
    Arch = pic16;
  else if (ArchName == "powerpc")
    Arch = ppc;
  else if (ArchName == "powerpc64")
    Arch = ppc64;
  else if (ArchName == "arm" ||
           ArchName.startswith("armv") ||
           ArchName == "xscale")
    Arch = arm;
  else if (ArchName == "thumb" ||
           ArchName.startswith("thumbv"))
    Arch = thumb;
  else if (ArchName.startswith("alpha"))
    Arch = alpha;
  else if (ArchName == "spu" || ArchName == "cellspu")
    Arch = cellspu;
  else if (ArchName == "msp430")
    Arch = msp430;
  else if (ArchName == "mips" || ArchName == "mipsallegrex")
    Arch = mips;
  else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
           ArchName == "psp")
    Arch = mipsel;
  else if (ArchName == "sparc")
    Arch = sparc;
  else if (ArchName == "s390x")
    Arch = systemz;
  else if (ArchName == "tce")
    Arch = tce;
  else if (ArchName == "xcore")
    Arch = xcore;
  else
    Arch = UnknownArch;

  // Handle some exceptional cases where the OS / environment components are
  // stuck into the vendor field.
  if (StringRef(getTriple()).count('-') == 1) {
    StringRef VendorName = getVendorName();

    if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
      Vendor = PC;
      OS = MinGW32;
      return;
    }

    // arm-elf is another example, but we don't currently parse anything about
    // the environment.
  }

  if (VendorName == "apple")
    Vendor = Apple;
  else if (VendorName == "pc")
    Vendor = PC;
  else
    Vendor = UnknownVendor;

  if (OSName.startswith("auroraux"))
    OS = AuroraUX;
  else if (OSName.startswith("cygwin"))
    OS = Cygwin;
  else if (OSName.startswith("darwin"))
    OS = Darwin;
  else if (OSName.startswith("dragonfly"))
    OS = DragonFly;
  else if (OSName.startswith("freebsd"))
    OS = FreeBSD;
  else if (OSName.startswith("linux"))
    OS = Linux;
  else if (OSName.startswith("mingw32"))
    OS = MinGW32;
  else if (OSName.startswith("mingw64"))
    OS = MinGW64;
  else if (OSName.startswith("netbsd"))
    OS = NetBSD;
  else if (OSName.startswith("openbsd"))
    OS = OpenBSD;
  else if (OSName.startswith("solaris"))
    OS = Solaris;
  else if (OSName.startswith("win32"))
    OS = Win32;
  else
    OS = UnknownOS;

  assert(isInitialized() && "Failed to initialize!");
}

StringRef Triple::getArchName() const {
  return StringRef(Data).split('-').first;           // Isolate first component
}

StringRef Triple::getVendorName() const {
  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
  return Tmp.split('-').first;                       // Isolate second component
}

StringRef Triple::getOSName() const {
  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
  Tmp = Tmp.split('-').second;                       // Strip second component
  return Tmp.split('-').first;                       // Isolate third component
}

StringRef Triple::getEnvironmentName() const {
  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
  Tmp = Tmp.split('-').second;                       // Strip second component
  return Tmp.split('-').second;                      // Strip third component
}

StringRef Triple::getOSAndEnvironmentName() const {
  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
  return Tmp.split('-').second;                      // Strip second component
}

static unsigned EatNumber(StringRef &Str) {
  assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
  unsigned Result = Str[0]-'0';

  // Eat the digit.
  Str = Str.substr(1);

  // Handle "darwin11".
  if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
    Result = Result*10 + (Str[0] - '0');
    // Eat the digit.
    Str = Str.substr(1);
  }

  return Result;
}

/// getDarwinNumber - Parse the 'darwin number' out of the specific target
/// triple.  For example, if we have darwin8.5 return 8,5,0.  If any entry is
/// not defined, return 0's.  This requires that the triple have an OSType of
/// darwin before it is called.
void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
                             unsigned &Revision) const {
  assert(getOS() == Darwin && "Not a darwin target triple!");
  StringRef OSName = getOSName();
  assert(OSName.startswith("darwin") && "Unknown darwin target triple!");

  // Strip off "darwin".
  OSName = OSName.substr(6);

  Maj = Min = Revision = 0;

  if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
    return;

  // The major version is the first digit.
  Maj = EatNumber(OSName);
  if (OSName.empty()) return;

  // Handle minor version: 10.4.9 -> darwin8.9.
  if (OSName[0] != '.')
    return;

  // Eat the '.'.
  OSName = OSName.substr(1);

  if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
    return;

  Min = EatNumber(OSName);
  if (OSName.empty()) return;

  // Handle revision darwin8.9.1
  if (OSName[0] != '.')
    return;

  // Eat the '.'.
  OSName = OSName.substr(1);

  if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
    return;

  Revision = EatNumber(OSName);
}

void Triple::setTriple(const Twine &Str) {
  Data = Str.str();
  Arch = InvalidArch;
}

void Triple::setArch(ArchType Kind) {
  setArchName(getArchTypeName(Kind));
}

void Triple::setVendor(VendorType Kind) {
  setVendorName(getVendorTypeName(Kind));
}

void Triple::setOS(OSType Kind) {
  setOSName(getOSTypeName(Kind));
}

void Triple::setArchName(const StringRef &Str) {
  setTriple(Str + "-" + getVendorName() + "-" + getOSAndEnvironmentName());
}

void Triple::setVendorName(const StringRef &Str) {
  setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
}

void Triple::setOSName(const StringRef &Str) {
  if (hasEnvironment())
    setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
              "-" + getEnvironmentName());
  else
    setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
}

void Triple::setEnvironmentName(const StringRef &Str) {
  setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
            "-" + Str);
}

void Triple::setOSAndEnvironmentName(const StringRef &Str) {
  setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
}
<commit_msg>Add comment re: clang dependency.<commit_after>//===--- Triple.cpp - Target triple helper class --------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/ADT/Triple.h"

#include "llvm/ADT/Twine.h"
#include <cassert>
#include <cstring>
using namespace llvm;

//

const char *Triple::getArchTypeName(ArchType Kind) {
  switch (Kind) {
  case InvalidArch: return "<invalid>";
  case UnknownArch: return "unknown";

  case alpha:   return "alpha";
  case arm:     return "arm";
  case bfin:    return "bfin";
  case cellspu: return "cellspu";
  case mips:    return "mips";
  case mipsel:  return "mipsel";
  case msp430:  return "msp430";
  case pic16:   return "pic16";
  case ppc64:   return "powerpc64";
  case ppc:     return "powerpc";
  case sparc:   return "sparc";
  case systemz: return "s390x";
  case tce:     return "tce";
  case thumb:   return "thumb";
  case x86:     return "i386";
  case x86_64:  return "x86_64";
  case xcore:   return "xcore";
  }

  return "<invalid>";
}

const char *Triple::getArchTypePrefix(ArchType Kind) {
  switch (Kind) {
  default:
    return 0;

  case alpha:   return "alpha";

  case arm:
  case thumb:   return "arm";

  case bfin:    return "bfin";

  case cellspu: return "spu";

  case ppc64:
  case ppc:     return "ppc";

  case sparc:   return "sparc";

  case x86:
  case x86_64:  return "x86";
  case xcore:   return "xcore";
  }
}

const char *Triple::getVendorTypeName(VendorType Kind) {
  switch (Kind) {
  case UnknownVendor: return "unknown";

  case Apple: return "apple";
  case PC: return "pc";
  }

  return "<invalid>";
}

const char *Triple::getOSTypeName(OSType Kind) {
  switch (Kind) {
  case UnknownOS: return "unknown";

  case AuroraUX: return "auroraux";
  case Cygwin: return "cygwin";
  case Darwin: return "darwin";
  case DragonFly: return "dragonfly";
  case FreeBSD: return "freebsd";
  case Linux: return "linux";
  case MinGW32: return "mingw32";
  case MinGW64: return "mingw64";
  case NetBSD: return "netbsd";
  case OpenBSD: return "openbsd";
  case Solaris: return "solaris";
  case Win32: return "win32";
  }

  return "<invalid>";
}

Triple::ArchType Triple::getArchTypeForLLVMName(const StringRef &Name) {
  if (Name == "alpha")
    return alpha;
  if (Name == "arm")
    return arm;
  if (Name == "bfin")
    return bfin;
  if (Name == "cellspu")
    return cellspu;
  if (Name == "mips")
    return mips;
  if (Name == "mipsel")
    return mipsel;
  if (Name == "msp430")
    return msp430;
  if (Name == "pic16")
    return pic16;
  if (Name == "ppc64")
    return ppc64;
  if (Name == "ppc")
    return ppc;
  if (Name == "sparc")
    return sparc;
  if (Name == "systemz")
    return systemz;
  if (Name == "tce")
    return tce;
  if (Name == "thumb")
    return thumb;
  if (Name == "x86")
    return x86;
  if (Name == "x86-64")
    return x86_64;
  if (Name == "xcore")
    return xcore;

  return UnknownArch;
}

Triple::ArchType Triple::getArchTypeForDarwinArchName(const StringRef &Str) {
  // See arch(3) and llvm-gcc's driver-driver.c. We don't implement support for
  // archs which Darwin doesn't use.

  // The matching this routine does is fairly pointless, since it is neither the
  // complete architecture list, nor a reasonable subset. The problem is that
  // historically the driver driver accepts this and also ties its -march=
  // handling to the architecture name, so we need to be careful before removing
  // support for it.

  // This code must be kept in sync with Clang's Darwin specific argument
  // translation.

  if (Str == "ppc" || Str == "ppc601" || Str == "ppc603" || Str == "ppc604" ||
      Str == "ppc604e" || Str == "ppc750" || Str == "ppc7400" ||
      Str == "ppc7450" || Str == "ppc970")
    return Triple::ppc;

  if (Str == "ppc64")
    return Triple::ppc64;

  if (Str == "i386" || Str == "i486" || Str == "i486SX" || Str == "pentium" ||
      Str == "i586" || Str == "pentpro" || Str == "i686" || Str == "pentIIm3" ||
      Str == "pentIIm5" || Str == "pentium4")
    return Triple::x86;

  if (Str == "x86_64")
    return Triple::x86_64;

  // This is derived from the driver driver.
  if (Str == "arm" || Str == "armv4t" || Str == "armv5" || Str == "xscale" ||
      Str == "armv6" || Str == "armv7")
    return Triple::arm;

  return Triple::UnknownArch;
}

//

void Triple::Parse() const {
  assert(!isInitialized() && "Invalid parse call.");

  StringRef ArchName = getArchName();
  StringRef VendorName = getVendorName();
  StringRef OSName = getOSName();

  if (ArchName.size() == 4 && ArchName[0] == 'i' &&
      ArchName[2] == '8' && ArchName[3] == '6' &&
      ArchName[1] - '3' < 6) // i[3-9]86
    Arch = x86;
  else if (ArchName == "amd64" || ArchName == "x86_64")
    Arch = x86_64;
  else if (ArchName == "bfin")
    Arch = bfin;
  else if (ArchName == "pic16")
    Arch = pic16;
  else if (ArchName == "powerpc")
    Arch = ppc;
  else if (ArchName == "powerpc64")
    Arch = ppc64;
  else if (ArchName == "arm" ||
           ArchName.startswith("armv") ||
           ArchName == "xscale")
    Arch = arm;
  else if (ArchName == "thumb" ||
           ArchName.startswith("thumbv"))
    Arch = thumb;
  else if (ArchName.startswith("alpha"))
    Arch = alpha;
  else if (ArchName == "spu" || ArchName == "cellspu")
    Arch = cellspu;
  else if (ArchName == "msp430")
    Arch = msp430;
  else if (ArchName == "mips" || ArchName == "mipsallegrex")
    Arch = mips;
  else if (ArchName == "mipsel" || ArchName == "mipsallegrexel" ||
           ArchName == "psp")
    Arch = mipsel;
  else if (ArchName == "sparc")
    Arch = sparc;
  else if (ArchName == "s390x")
    Arch = systemz;
  else if (ArchName == "tce")
    Arch = tce;
  else if (ArchName == "xcore")
    Arch = xcore;
  else
    Arch = UnknownArch;

  // Handle some exceptional cases where the OS / environment components are
  // stuck into the vendor field.
  if (StringRef(getTriple()).count('-') == 1) {
    StringRef VendorName = getVendorName();

    if (VendorName.startswith("mingw32")) { // 'i386-mingw32', etc.
      Vendor = PC;
      OS = MinGW32;
      return;
    }

    // arm-elf is another example, but we don't currently parse anything about
    // the environment.
  }

  if (VendorName == "apple")
    Vendor = Apple;
  else if (VendorName == "pc")
    Vendor = PC;
  else
    Vendor = UnknownVendor;

  if (OSName.startswith("auroraux"))
    OS = AuroraUX;
  else if (OSName.startswith("cygwin"))
    OS = Cygwin;
  else if (OSName.startswith("darwin"))
    OS = Darwin;
  else if (OSName.startswith("dragonfly"))
    OS = DragonFly;
  else if (OSName.startswith("freebsd"))
    OS = FreeBSD;
  else if (OSName.startswith("linux"))
    OS = Linux;
  else if (OSName.startswith("mingw32"))
    OS = MinGW32;
  else if (OSName.startswith("mingw64"))
    OS = MinGW64;
  else if (OSName.startswith("netbsd"))
    OS = NetBSD;
  else if (OSName.startswith("openbsd"))
    OS = OpenBSD;
  else if (OSName.startswith("solaris"))
    OS = Solaris;
  else if (OSName.startswith("win32"))
    OS = Win32;
  else
    OS = UnknownOS;

  assert(isInitialized() && "Failed to initialize!");
}

StringRef Triple::getArchName() const {
  return StringRef(Data).split('-').first;           // Isolate first component
}

StringRef Triple::getVendorName() const {
  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
  return Tmp.split('-').first;                       // Isolate second component
}

StringRef Triple::getOSName() const {
  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
  Tmp = Tmp.split('-').second;                       // Strip second component
  return Tmp.split('-').first;                       // Isolate third component
}

StringRef Triple::getEnvironmentName() const {
  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
  Tmp = Tmp.split('-').second;                       // Strip second component
  return Tmp.split('-').second;                      // Strip third component
}

StringRef Triple::getOSAndEnvironmentName() const {
  StringRef Tmp = StringRef(Data).split('-').second; // Strip first component
  return Tmp.split('-').second;                      // Strip second component
}

static unsigned EatNumber(StringRef &Str) {
  assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
  unsigned Result = Str[0]-'0';

  // Eat the digit.
  Str = Str.substr(1);

  // Handle "darwin11".
  if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
    Result = Result*10 + (Str[0] - '0');
    // Eat the digit.
    Str = Str.substr(1);
  }

  return Result;
}

/// getDarwinNumber - Parse the 'darwin number' out of the specific target
/// triple.  For example, if we have darwin8.5 return 8,5,0.  If any entry is
/// not defined, return 0's.  This requires that the triple have an OSType of
/// darwin before it is called.
void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
                             unsigned &Revision) const {
  assert(getOS() == Darwin && "Not a darwin target triple!");
  StringRef OSName = getOSName();
  assert(OSName.startswith("darwin") && "Unknown darwin target triple!");

  // Strip off "darwin".
  OSName = OSName.substr(6);

  Maj = Min = Revision = 0;

  if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
    return;

  // The major version is the first digit.
  Maj = EatNumber(OSName);
  if (OSName.empty()) return;

  // Handle minor version: 10.4.9 -> darwin8.9.
  if (OSName[0] != '.')
    return;

  // Eat the '.'.
  OSName = OSName.substr(1);

  if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
    return;

  Min = EatNumber(OSName);
  if (OSName.empty()) return;

  // Handle revision darwin8.9.1
  if (OSName[0] != '.')
    return;

  // Eat the '.'.
  OSName = OSName.substr(1);

  if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
    return;

  Revision = EatNumber(OSName);
}

void Triple::setTriple(const Twine &Str) {
  Data = Str.str();
  Arch = InvalidArch;
}

void Triple::setArch(ArchType Kind) {
  setArchName(getArchTypeName(Kind));
}

void Triple::setVendor(VendorType Kind) {
  setVendorName(getVendorTypeName(Kind));
}

void Triple::setOS(OSType Kind) {
  setOSName(getOSTypeName(Kind));
}

void Triple::setArchName(const StringRef &Str) {
  setTriple(Str + "-" + getVendorName() + "-" + getOSAndEnvironmentName());
}

void Triple::setVendorName(const StringRef &Str) {
  setTriple(getArchName() + "-" + Str + "-" + getOSAndEnvironmentName());
}

void Triple::setOSName(const StringRef &Str) {
  if (hasEnvironment())
    setTriple(getArchName() + "-" + getVendorName() + "-" + Str +
              "-" + getEnvironmentName());
  else
    setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
}

void Triple::setEnvironmentName(const StringRef &Str) {
  setTriple(getArchName() + "-" + getVendorName() + "-" + getOSName() +
            "-" + Str);
}

void Triple::setOSAndEnvironmentName(const StringRef &Str) {
  setTriple(getArchName() + "-" + getVendorName() + "-" + Str);
}
<|endoftext|>


<commit_before>#include "pch.h"
#include "rdo_rule.h"
#include "rdo_runtime.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

namespace rdoRuntime {

// ----------------------------------------------------------------------------
// ---------- RDORule
// ----------------------------------------------------------------------------
RDORule::RDORule( RDORuntime* runtime, RDOPatternRule* pattern, bool trace, const std::string& name ):
	RDOActivityPattern<RDOPatternRule>( runtime, pattern, trace, name ),
	RDORuntimeContainer( runtime ),
	additionalCondition( NULL )
{
	setTraceID( getRuntime()->getFreeActivityId() );
	haveAdditionalCondition = false;
}

RDORule::RDORule( RDORuntime* runtime, RDOPatternRule* pattern, bool trace, RDOCalc* condition, const std::string& name ):
	RDOActivityPattern<RDOPatternRule>( runtime, pattern, trace, name ),
	RDORuntimeContainer( runtime ),
	additionalCondition( condition )
{
	setTraceID( getRuntime()->getFreeActivityId() );
	haveAdditionalCondition = true;
}

bool RDORule::choiceFrom( RDORuntime* runtime )
{
	runtime->setCurrentActivity( this );
	if ( haveAdditionalCondition ) {
		if ( !additionalCondition->calcValue( runtime ).getAsBool() ) {
			return false;
		}
	}
	return m_pattern->choiceFrom( runtime );
}

void RDORule::convertRule( RDORuntime* runtime )
{
	runtime->setCurrentActivity( this );
	m_pattern->convertRule( runtime );
}

void RDORule::onAfterRule( RDOSimulator* sim, bool inSearch )
{
	updateConvertStatus( sim, m_pattern->m_convertorStatus );
	if ( !inSearch ) {
		getRuntime()->getTracer()->writeRule( this, getRuntime() );
	}
	m_pattern->convertErase( static_cast<RDORuntime*>(sim) );
	updateRelRes( sim );
}

bool RDORule::onCheckCondition( RDOSimulator* sim )
{
	onBeforeChoiceFrom( sim );
	sim->inc_cnt_choice_from();
	return choiceFrom( static_cast<RDORuntime*>(sim) );
}

RDOBaseOperation::BOResult RDORule::onDoOperation( RDOSimulator* sim )
{
	onBeforeRule( sim );
	convertRule( static_cast<RDORuntime*>(sim) );
	onAfterRule( sim );
	return RDOBaseOperation::BOR_done;
}

} // namespace rdoRuntime
<commit_msg>Дата внесения изменений: 02.11.08 Автор: Лущан Дмитрий Смысл изменений: не запускать патерн (рул), если после его выполнения состояние системы не изменилось<commit_after>#include "pch.h"
#include "rdo_rule.h"
#include "rdo_runtime.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

namespace rdoRuntime {

// ----------------------------------------------------------------------------
// ---------- RDORule
// ----------------------------------------------------------------------------
RDORule::RDORule( RDORuntime* runtime, RDOPatternRule* pattern, bool trace, const std::string& name ):
	RDOActivityPattern<RDOPatternRule>( runtime, pattern, trace, name ),
	RDORuntimeContainer( runtime ),
	additionalCondition( NULL )
{
	setTraceID( getRuntime()->getFreeActivityId() );
	haveAdditionalCondition = false;
}

RDORule::RDORule( RDORuntime* runtime, RDOPatternRule* pattern, bool trace, RDOCalc* condition, const std::string& name ):
	RDOActivityPattern<RDOPatternRule>( runtime, pattern, trace, name ),
	RDORuntimeContainer( runtime ),
	additionalCondition( condition )
{
	setTraceID( getRuntime()->getFreeActivityId() );
	haveAdditionalCondition = true;
}

bool RDORule::choiceFrom( RDORuntime* runtime )
{
	runtime->setCurrentActivity( this );
	if ( haveAdditionalCondition ) {
		if ( !additionalCondition->calcValue( runtime ).getAsBool() ) {
			return false;
		}
	}
	return m_pattern->choiceFrom( runtime );
}

void RDORule::convertRule( RDORuntime* runtime )
{
	runtime->setCurrentActivity( this );
	m_pattern->convertRule( runtime );
}

void RDORule::onAfterRule( RDOSimulator* sim, bool inSearch )
{
	updateConvertStatus( sim, m_pattern->m_convertorStatus );
	if ( !inSearch ) {
		getRuntime()->getTracer()->writeRule( this, getRuntime() );
	}
	m_pattern->convertErase( static_cast<RDORuntime*>(sim) );
	updateRelRes( sim );
}

bool RDORule::onCheckCondition( RDOSimulator* sim )
/*
  : 02.11.08
:
 :    (),
*/
{
	onBeforeChoiceFrom( sim );
	sim->inc_cnt_choice_from();
	bool result = choiceFrom( static_cast<RDORuntime*>(sim) );
	if ( result )
	{
//      clone
		RDOSimulator* clone = sim->clone();
		onBeforeRule( clone );
		convertRule( static_cast<RDORuntime*>(clone) );
		onAfterRule( clone );
//
		if ( *clone == *sim )
		{
			result = false;
		}
		delete clone;
	}
	return result;
}

RDOBaseOperation::BOResult RDORule::onDoOperation( RDOSimulator* sim )
{
	onBeforeRule( sim );
	convertRule( static_cast<RDORuntime*>(sim) );
	onAfterRule( sim );
	return RDOBaseOperation::BOR_done;
}

} // namespace rdoRuntime
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: share.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 22:26:59 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <typeinfo>
#include <exception>
#include <cstddef>

namespace CPPU_CURRENT_NAMESPACE
{

// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h

struct _Unwind_Exception
{
    unsigned exception_class __attribute__((__mode__(__DI__)));
    void * exception_cleanup;
    unsigned private_1 __attribute__((__mode__(__word__)));
    unsigned private_2 __attribute__((__mode__(__word__)));
} __attribute__((__aligned__));

struct __cxa_exception
{
    ::std::type_info *exceptionType;
    void (*exceptionDestructor)(void *);

    ::std::unexpected_handler unexpectedHandler;
    ::std::terminate_handler terminateHandler;

    __cxa_exception *nextException;

    int handlerCount;

    int handlerSwitchValue;
    const unsigned char *actionRecord;
    const unsigned char *languageSpecificData;
    void *catchTemp;
    void *adjustedPtr;

    _Unwind_Exception unwindHeader;
};

extern "C" void *__cxa_allocate_exception(
    std::size_t thrown_size ) throw();
extern "C" void __cxa_throw (
    void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));

struct __cxa_eh_globals
{
    __cxa_exception *caughtExceptions;
    unsigned int uncaughtExceptions;
};
extern "C" __cxa_eh_globals *__cxa_get_globals () throw();

// -----

//==================================================================================================
void raiseException(
    uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
//==================================================================================================
void fillUnoException(
    __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
}
<commit_msg>INTEGRATION: CWS sixtyfour03 (1.3.32); FILE MERGED 2006/03/06 11:08:58 kendy 1.3.32.1: #i62810# x86-64 bridge improvements: slightly better debug<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: share.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2006-03-08 08:51:06 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "uno/mapping.h"

#include <typeinfo>
#include <exception>
#include <cstddef>

namespace CPPU_CURRENT_NAMESPACE
{

void dummy_can_throw_anything( char const * );

// ----- following decl from libstdc++-v3/libsupc++/unwind-cxx.h and unwind.h

struct _Unwind_Exception
{
    unsigned exception_class __attribute__((__mode__(__DI__)));
    void * exception_cleanup;
    unsigned private_1 __attribute__((__mode__(__word__)));
    unsigned private_2 __attribute__((__mode__(__word__)));
} __attribute__((__aligned__));

struct __cxa_exception
{
    ::std::type_info *exceptionType;
    void (*exceptionDestructor)(void *);

    ::std::unexpected_handler unexpectedHandler;
    ::std::terminate_handler terminateHandler;

    __cxa_exception *nextException;

    int handlerCount;

    int handlerSwitchValue;
    const unsigned char *actionRecord;
    const unsigned char *languageSpecificData;
    void *catchTemp;
    void *adjustedPtr;

    _Unwind_Exception unwindHeader;
};

extern "C" void *__cxa_allocate_exception(
    std::size_t thrown_size ) throw();
extern "C" void __cxa_throw (
    void *thrown_exception, std::type_info *tinfo, void (*dest) (void *) ) __attribute__((noreturn));

struct __cxa_eh_globals
{
    __cxa_exception *caughtExceptions;
    unsigned int uncaughtExceptions;
};
extern "C" __cxa_eh_globals *__cxa_get_globals () throw();

// -----

//==================================================================================================
void raiseException(
    uno_Any * pUnoExc, uno_Mapping * pUno2Cpp );
//==================================================================================================
void fillUnoException(
    __cxa_exception * header, uno_Any *, uno_Mapping * pCpp2Uno );
}
<|endoftext|>


<commit_before>#include "btree.h"

#include <map>
#include <vector>
using namespace std;

// TODO: For ease to debug, start with a simple 2-3 tree
const int max_size = 3;
const int min_size = 2;

class btree_node;

struct insert_result
{
    bool succeed;
    bool overflow;
};

struct split_result
{
    btree_node* sibling;
    int key;
};

struct remove_result
{
    bool succeed;
    bool underflow;
};

class btree_node
{
public:
    virtual ~btree_node();
    virtual insert_result insert(int key, int value) = 0;
    virtual split_result split() = 0;
    virtual bool select(int key, int* result) = 0;
    virtual remove_result remove(int key) = 0;
    virtual bool can_borrow() = 0;
    virtual bool can_accept() = 0;
};

class btree_internal_node : public btree_node
{
public:
    btree_internal_node(int key, btree_node* left, btree_node* right);
    ~btree_internal_node();
    virtual insert_result insert(int key, int value);
    virtual split_result split();
    virtual bool select(int key, int* result);
    virtual remove_result remove(int key);
    virtual bool can_borrow();
    virtual bool can_accept();
private:
    btree_internal_node();
    vector<int> keys;
    vector<btree_node*> children;
};

class btree_leaf_node : public btree_node
{
public:
    virtual ~btree_leaf_node();
    virtual insert_result insert(int key, int value);
    virtual split_result split();
    virtual bool select(int key, int* result);
    virtual remove_result remove(int key);
    virtual bool can_borrow();
    virtual bool can_accept();
private:
    vector<int> keys;
    vector<int> values;
};

class btree_impl
{
public:
    bool insert(int key, int value);
    bool select(int key, int* result);
    bool remove(int key);
private:
    btree_node* m_root;
};

btree::btree()
{
    this->m_impl = new btree_impl();
}

btree::~btree()
{
    delete this->m_impl;
}

bool btree::insert(int key, int value)
{
    return this->m_impl->insert(key, value);
}

bool btree::select(int key, int* result)
{
    return this->m_impl->select(key, result);
}

bool btree::remove(int key)
{
    return this->m_impl->remove(key);
}

btree_node::~btree_node()
{
}

btree_leaf_node::~btree_leaf_node()
{
}

insert_result btree_leaf_node::insert(int key, int value)
{
    insert_result result;
    for (size_t upper_index = 0; upper_index <= this->keys.size(); upper_index++)
    {
        int lower_index = upper_index - 1;
        bool lower_is_good = (lower_index == -1) || (this->keys[lower_index] <= key);
        bool upper_is_good = (upper_index == this->keys.size()) || (key < this->keys[upper_index]);
        if (lower_is_good && upper_is_good)
        {
            if (lower_index != -1 && key == this->keys[lower_index])
            {
                result.succeed = false;
            }
            else
            {
                this->keys.insert(this->keys.begin() + upper_index, key);
                this->values.insert(this->values.begin() + upper_index, value);
                result.succeed = true;
                result.overflow = (this->keys.size() == (max_size + 1));
            }

            break;
        }
    }

    return result;
}

split_result btree_leaf_node::split()
{
    split_result result;
    btree_leaf_node* sibling = new btree_leaf_node();
    for (size_t i = min_size; i < this->keys.size(); i++)
    {
        sibling->keys.push_back(this->keys[i]);
        sibling->values.push_back(this->values[i]);
    }
    this->keys.resize(min_size);
    this->values.resize(min_size);

    result.sibling = sibling;
    result.key = sibling->keys[0];
    return result;
}

bool btree_leaf_node::select(int key, int* result)
{
    for (size_t i = 0; i < this->keys.size(); i++)
    {
        if (this->keys[i] == key)
        {
            *result = this->values[i];
            return true;
        }
    }

    return false;
}

remove_result btree_leaf_node::remove(int key)
{
    remove_result result;
    result.succeed = false;
    for (size_t i = 0; i < this->keys.size(); i++)
    {
        if (this->keys[i] == key)
        {
            result.succeed = true;
            this->keys.erase(this->keys.begin() + i);
            this->values.erase(this->values.begin() + i);
            break;
        }
    }

    result.underflow = this->keys.size() < min_size;
    return result;
}

bool btree_leaf_node::can_borrow()
{
    return this->keys.size() > min_size;
}

bool btree_leaf_node::can_accept()
{
    return this->keys.size() < max_size;
}

btree_internal_node::btree_internal_node(int key, btree_node* left, btree_node* right)
{
    this->keys.push_back(key);
    this->children.push_back(left);
    this->children.push_back(right);
}

btree_internal_node::btree_internal_node()
{

}

btree_internal_node::~btree_internal_node()
{

}

insert_result btree_internal_node::insert(int key, int value)
{
    insert_result result;
    for (size_t upper_index = 0; upper_index <= this->keys.size(); upper_index++)
    {
        int lower_index = upper_index - 1;
        bool lower_is_good = (lower_index == -1) || (this->keys[lower_index] <= key);
        bool upper_is_good = (upper_index == this->keys.size()) || (key < this->keys[upper_index]);
        if (lower_is_good && upper_is_good)
        {
            insert_result children_insert_result = this->children[upper_index]->insert(key, value);
            if (children_insert_result.succeed)
            {
                result.succeed = true;
                if (children_insert_result.overflow)
                {
                    split_result children_split_result = this->children[upper_index]->split();
                    if (upper_index == this->keys.size())
                    {
                        this->children.push_back(children_split_result.sibling);
                        this->keys.push_back(children_split_result.key);
                    }
                    else
                    {
                        this->children.insert(this->children.begin() + upper_index + 1, children_split_result.sibling);
                        this->keys.insert(this->keys.begin() + upper_index, children_split_result.key);
                    }

                    result.overflow = this->children.size() == max_size + 1;
                }
                else
                {
                    result.overflow = false;
                }
            }
            else
            {
                result.succeed = false;
            }

            break;
        }
    }

    return result;
}

split_result btree_internal_node::split()
{
    split_result result;
    btree_internal_node* sibling = new btree_internal_node();
    for (size_t i = min_size; i < this->children.size(); i++)
    {
        sibling->children.push_back(this->children[i]);
    }
    for (size_t i = min_size; i < this->keys.size(); i++)
    {
        sibling->keys.push_back(this->keys[i]);
    }
    result.sibling = sibling;
    result.key = this->keys[min_size - 1];
    this->keys.resize(min_size - 1);
    this->children.resize(min_size);
    return result;
}

bool btree_internal_node::select(int key, int* result)
{
    for (size_t upper_index = 0; upper_index <= this->keys.size(); upper_index++)
    {
        int lower_index = upper_index - 1;
        bool lower_is_good = (lower_index == -1) || (this->keys[lower_index] <= key);
        bool upper_is_good = (upper_index == this->keys.size()) || (key < this->keys[upper_index]);
        if (lower_is_good && upper_is_good)
        {
            return this->children[upper_index]->select(key, result);
        }
    }

    return false;
}

remove_result btree_internal_node::remove(int key)
{
    remove_result result;
    result.succeed = false;
    for (size_t upper_index = 0; upper_index <= this->keys.size(); upper_index++)
    {
        int lower_index = upper_index - 1;
        bool lower_is_good = (lower_index == -1) || (this->keys[lower_index] <= key);
        bool upper_is_good = (upper_index == this->keys.size()) || (key < this->keys[upper_index]);
        if (lower_is_good && upper_is_good)
        {
            remove_result child_remove_result = this->children[upper_index]->remove(key);
            if (child_remove_result.succeed)
            {
                result.succeed = true;
                if (child_remove_result.underflow)
                {
                    bool underflow_solved = false;
                    if (upper_index > 0)
                    {
                        if (this->children[upper_index - 1]->can_borrow())
                        {
                            // The actual borrowing act is a little more complicated
                            // We need to update the internal node that represent the key
                            // How? I am still thinking ...
                        }
                    }
                }
            }

            break;
        }
    }

    return result;
}

bool btree_internal_node::can_borrow()
{
    return this->children.size() > min_size;
}

bool btree_internal_node::can_accept()
{
    return this->children.size() < max_size;
}

bool btree_impl::insert(int key, int value)
{
    if (this->m_root == nullptr)
    {
        this->m_root = new btree_leaf_node();
    }

    insert_result result = this->m_root->insert(key, value);

    if (result.succeed)
    {
        if (result.overflow)
        {
            split_result split_result = this->m_root->split();
            this->m_root = new btree_internal_node(split_result.key, this->m_root, split_result.sibling);
            return true;
        }
        else
        {
            return true;
        }
    }
    else
    {
        return false;
    }
}

bool btree_impl::select(int key, int* result)
{
    if (this->m_root == nullptr)
    {
        return false;
    }
    else
    {
        return this->m_root->select(key, result);
    }
}

bool btree_impl::remove(int key)
{
    if (this->m_root == nullptr)
    {
        return false;
    }
    else
    {
        remove_result result = this->m_root->remove(key);
        if (result.succeed)
        {
            // It is okay for the root to underflow
            return true;
        }
        else
        {
            return false;
        }
    }
}
<commit_msg>comments<commit_after>#include "btree.h"

#include <map>
#include <vector>
using namespace std;

// TODO: For ease to debug, start with a simple 2-3 tree
const int max_size = 3;
const int min_size = 2;

class btree_node;

struct insert_result
{
    bool succeed;
    bool overflow;
};

struct split_result
{
    btree_node* sibling;
    int key;
};

struct remove_result
{
    bool succeed;
    bool underflow;
};

class btree_node
{
public:
    virtual ~btree_node();
    virtual insert_result insert(int key, int value) = 0;
    virtual split_result split() = 0;
    virtual bool select(int key, int* result) = 0;
    virtual remove_result remove(int key) = 0;
    virtual bool can_borrow() = 0;
    virtual bool can_accept() = 0;
};

class btree_internal_node : public btree_node
{
public:
    btree_internal_node(int key, btree_node* left, btree_node* right);
    ~btree_internal_node();
    virtual insert_result insert(int key, int value);
    virtual split_result split();
    virtual bool select(int key, int* result);
    virtual remove_result remove(int key);
    virtual bool can_borrow();
    virtual bool can_accept();
private:
    btree_internal_node();
    vector<int> keys;
    vector<btree_node*> children;
};

class btree_leaf_node : public btree_node
{
public:
    virtual ~btree_leaf_node();
    virtual insert_result insert(int key, int value);
    virtual split_result split();
    virtual bool select(int key, int* result);
    virtual remove_result remove(int key);
    virtual bool can_borrow();
    virtual bool can_accept();
private:
    vector<int> keys;
    vector<int> values;
};

class btree_impl
{
public:
    bool insert(int key, int value);
    bool select(int key, int* result);
    bool remove(int key);
private:
    btree_node* m_root;
};

btree::btree()
{
    this->m_impl = new btree_impl();
}

btree::~btree()
{
    delete this->m_impl;
}

bool btree::insert(int key, int value)
{
    return this->m_impl->insert(key, value);
}

bool btree::select(int key, int* result)
{
    return this->m_impl->select(key, result);
}

bool btree::remove(int key)
{
    return this->m_impl->remove(key);
}

btree_node::~btree_node()
{
}

btree_leaf_node::~btree_leaf_node()
{
}

insert_result btree_leaf_node::insert(int key, int value)
{
    insert_result result;
    for (size_t upper_index = 0; upper_index <= this->keys.size(); upper_index++)
    {
        int lower_index = upper_index - 1;
        bool lower_is_good = (lower_index == -1) || (this->keys[lower_index] <= key);
        bool upper_is_good = (upper_index == this->keys.size()) || (key < this->keys[upper_index]);
        if (lower_is_good && upper_is_good)
        {
            if (lower_index != -1 && key == this->keys[lower_index])
            {
                result.succeed = false;
            }
            else
            {
                this->keys.insert(this->keys.begin() + upper_index, key);
                this->values.insert(this->values.begin() + upper_index, value);
                result.succeed = true;
                result.overflow = (this->keys.size() == (max_size + 1));
            }

            break;
        }
    }

    return result;
}

split_result btree_leaf_node::split()
{
    split_result result;
    btree_leaf_node* sibling = new btree_leaf_node();
    for (size_t i = min_size; i < this->keys.size(); i++)
    {
        sibling->keys.push_back(this->keys[i]);
        sibling->values.push_back(this->values[i]);
    }
    this->keys.resize(min_size);
    this->values.resize(min_size);

    result.sibling = sibling;
    result.key = sibling->keys[0];
    return result;
}

bool btree_leaf_node::select(int key, int* result)
{
    for (size_t i = 0; i < this->keys.size(); i++)
    {
        if (this->keys[i] == key)
        {
            *result = this->values[i];
            return true;
        }
    }

    return false;
}

remove_result btree_leaf_node::remove(int key)
{
    remove_result result;
    result.succeed = false;
    for (size_t i = 0; i < this->keys.size(); i++)
    {
        if (this->keys[i] == key)
        {
            result.succeed = true;
            this->keys.erase(this->keys.begin() + i);
            this->values.erase(this->values.begin() + i);
            break;
        }
    }

    result.underflow = this->keys.size() < min_size;
    return result;
}

bool btree_leaf_node::can_borrow()
{
    return this->keys.size() > min_size;
}

bool btree_leaf_node::can_accept()
{
    return this->keys.size() < max_size;
}

btree_internal_node::btree_internal_node(int key, btree_node* left, btree_node* right)
{
    this->keys.push_back(key);
    this->children.push_back(left);
    this->children.push_back(right);
}

btree_internal_node::btree_internal_node()
{

}

btree_internal_node::~btree_internal_node()
{

}

insert_result btree_internal_node::insert(int key, int value)
{
    insert_result result;
    for (size_t upper_index = 0; upper_index <= this->keys.size(); upper_index++)
    {
        int lower_index = upper_index - 1;
        bool lower_is_good = (lower_index == -1) || (this->keys[lower_index] <= key);
        bool upper_is_good = (upper_index == this->keys.size()) || (key < this->keys[upper_index]);
        if (lower_is_good && upper_is_good)
        {
            insert_result children_insert_result = this->children[upper_index]->insert(key, value);
            if (children_insert_result.succeed)
            {
                result.succeed = true;
                if (children_insert_result.overflow)
                {
                    split_result children_split_result = this->children[upper_index]->split();
                    if (upper_index == this->keys.size())
                    {
                        this->children.push_back(children_split_result.sibling);
                        this->keys.push_back(children_split_result.key);
                    }
                    else
                    {
                        this->children.insert(this->children.begin() + upper_index + 1, children_split_result.sibling);
                        this->keys.insert(this->keys.begin() + upper_index, children_split_result.key);
                    }

                    result.overflow = this->children.size() == max_size + 1;
                }
                else
                {
                    result.overflow = false;
                }
            }
            else
            {
                result.succeed = false;
            }

            break;
        }
    }

    return result;
}

split_result btree_internal_node::split()
{
    split_result result;
    btree_internal_node* sibling = new btree_internal_node();
    for (size_t i = min_size; i < this->children.size(); i++)
    {
        sibling->children.push_back(this->children[i]);
    }
    for (size_t i = min_size; i < this->keys.size(); i++)
    {
        sibling->keys.push_back(this->keys[i]);
    }
    result.sibling = sibling;
    result.key = this->keys[min_size - 1];
    this->keys.resize(min_size - 1);
    this->children.resize(min_size);
    return result;
}

bool btree_internal_node::select(int key, int* result)
{
    for (size_t upper_index = 0; upper_index <= this->keys.size(); upper_index++)
    {
        int lower_index = upper_index - 1;
        bool lower_is_good = (lower_index == -1) || (this->keys[lower_index] <= key);
        bool upper_is_good = (upper_index == this->keys.size()) || (key < this->keys[upper_index]);
        if (lower_is_good && upper_is_good)
        {
            return this->children[upper_index]->select(key, result);
        }
    }

    return false;
}

remove_result btree_internal_node::remove(int key)
{
    remove_result result;
    result.succeed = false;
    for (size_t upper_index = 0; upper_index <= this->keys.size(); upper_index++)
    {
        int lower_index = upper_index - 1;
        bool lower_is_good = (lower_index == -1) || (this->keys[lower_index] <= key);
        bool upper_is_good = (upper_index == this->keys.size()) || (key < this->keys[upper_index]);
        if (lower_is_good && upper_is_good)
        {
            remove_result child_remove_result = this->children[upper_index]->remove(key);
            if (child_remove_result.succeed)
            {
                result.succeed = true;
                if (child_remove_result.underflow)
                {
                    bool underflow_solved = false;
                    if (upper_index > 0)
                    {
                        if (this->children[upper_index - 1]->can_borrow())
                        {
                            // The actual borrowing act is a little more complicated
                            // We need to update the internal node that represent the key
                            // How? I am still thinking ...

                            // For leaf, the key must be its left parent key
                            // For internal nodes, the key should not repeat in the ancestors
                        }
                    }
                }
            }

            break;
        }
    }

    return result;
}

bool btree_internal_node::can_borrow()
{
    return this->children.size() > min_size;
}

bool btree_internal_node::can_accept()
{
    return this->children.size() < max_size;
}

bool btree_impl::insert(int key, int value)
{
    if (this->m_root == nullptr)
    {
        this->m_root = new btree_leaf_node();
    }

    insert_result result = this->m_root->insert(key, value);

    if (result.succeed)
    {
        if (result.overflow)
        {
            split_result split_result = this->m_root->split();
            this->m_root = new btree_internal_node(split_result.key, this->m_root, split_result.sibling);
            return true;
        }
        else
        {
            return true;
        }
    }
    else
    {
        return false;
    }
}

bool btree_impl::select(int key, int* result)
{
    if (this->m_root == nullptr)
    {
        return false;
    }
    else
    {
        return this->m_root->select(key, result);
    }
}

bool btree_impl::remove(int key)
{
    if (this->m_root == nullptr)
    {
        return false;
    }
    else
    {
        remove_result result = this->m_root->remove(key);
        if (result.succeed)
        {
            // It is okay for the root to underflow
            return true;
        }
        else
        {
            return false;
        }
    }
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "MultipleSenderTest.h"
#include "EventSender.h"

class MultiEventA:
  public virtual EventReceiver
{
public:
  virtual void EventA(void) = 0;
};

class MultiEventB:
  public virtual EventReceiver
{
public:
  virtual void EventB(void) = 0;
};

class MultiSender:
  public EventSender<MultiEventA, MultiEventB>
{
};

MultipleSenderTest::MultipleSenderTest(void) {}

TEST_F(MultipleSenderTest, VerifyMultiSendA) {
  m_sender->Fire(&MultiEventA::EventA)();
}

TEST_F(MultipleSenderTest, VerifyMultiSendB) {
  m_sender->Fire(&MultiEventB::EventB)();
}
<commit_msg>Test amended to ensure that potential naming collisions do not necessarily affect execution<commit_after>#include "stdafx.h"
#include "MultipleSenderTest.h"
#include "EventSender.h"

class MultiEventA:
  public virtual EventReceiver
{
public:
  virtual void Event(void) = 0;
};

class MultiEventB:
  public virtual EventReceiver
{
public:
  virtual void Event(void) = 0;
};

class MultiSender:
  public EventSender<MultiEventA, MultiEventB>
{
};

MultipleSenderTest::MultipleSenderTest(void) {}

TEST_F(MultipleSenderTest, VerifyMultiSendA) {
  m_sender->Fire(&MultiEventA::Event)();
}

TEST_F(MultipleSenderTest, VerifyMultiSendB) {
  m_sender->Fire(&MultiEventB::Event)();
}
<|endoftext|>


<commit_before><commit_msg>[contiguous-data/reverse-polish-notation] Overflow conditions check functions<commit_after><|endoftext|>