#include "AliasAnalysisSummary.h"
#include "llvm/IR/Argument.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Compiler.h"

namespace llvm {
namespace cflaa {

namespace {
const unsigned AttrEscapedIndex = 0;
const unsigned AttrUnknownIndex = 1;
const unsigned AttrGlobalIndex = 2;
const unsigned AttrCallerIndex = 3;
const unsigned AttrFirstArgIndex = 4;
const unsigned AttrLastArgIndex = NumAliasAttrs;
const unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex;

// It would be *slightly* prettier if we changed these to AliasAttrs, but it
// seems that both GCC and MSVC emit dynamic initializers for const bitsets.
using AliasAttr = unsigned;
const AliasAttr AttrNone = 0;
const AliasAttr AttrEscaped = 1 << AttrEscapedIndex;
const AliasAttr AttrUnknown = 1 << AttrUnknownIndex;
const AliasAttr AttrGlobal = 1 << AttrGlobalIndex;
const AliasAttr AttrCaller = 1 << AttrCallerIndex;
const AliasAttr ExternalAttrMask = AttrEscaped | AttrUnknown | AttrGlobal;
}

AliasAttrs getAttrNone() { return AttrNone; }

AliasAttrs getAttrUnknown() { return AttrUnknown; }
bool hasUnknownAttr(AliasAttrs Attr) { return Attr.test(AttrUnknownIndex); }

AliasAttrs getAttrCaller() { return AttrCaller; }
bool hasCallerAttr(AliasAttrs Attr) { return Attr.test(AttrCaller); }
bool hasUnknownOrCallerAttr(AliasAttrs Attr) {
  return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex);
}

AliasAttrs getAttrEscaped() { return AttrEscaped; }
bool hasEscapedAttr(AliasAttrs Attr) { return Attr.test(AttrEscapedIndex); }

static AliasAttr argNumberToAttr(unsigned ArgNum) {
  if (ArgNum >= AttrMaxNumArgs)
    return AttrUnknown;
  // N.B. MSVC complains if we use `1U` here, since AliasAttr' ctor takes
  // an unsigned long long.
  return AliasAttr(1ULL << (ArgNum + AttrFirstArgIndex));
}

AliasAttrs getGlobalOrArgAttrFromValue(const Value &Val) {
  if (isa<GlobalValue>(Val))
    return AttrGlobal;

  if (auto *Arg = dyn_cast<Argument>(&Val))
    // Only pointer arguments should have the argument attribute,
    // because things can't escape through scalars without us seeing a
    // cast, and thus, interaction with them doesn't matter.
    if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy())
      return argNumberToAttr(Arg->getArgNo());
  return AttrNone;
}

bool isGlobalOrArgAttr(AliasAttrs Attr) {
  return Attr.reset(AttrEscapedIndex)
      .reset(AttrUnknownIndex)
      .reset(AttrCallerIndex)
      .any();
}

AliasAttrs getExternallyVisibleAttrs(AliasAttrs Attr) {
  return Attr & AliasAttrs(ExternalAttrMask);
}

Optional<InstantiatedValue> instantiateInterfaceValue(InterfaceValue IValue,
                                                      CallBase &Call) {
  auto Index = IValue.Index;
  auto *V = (Index == 0) ? &Call : Call.getArgOperand(Index - 1);
  if (V->getType()->isPointerTy())
    return InstantiatedValue{V, IValue.DerefLevel};
  return None;
}

Optional<InstantiatedRelation>
instantiateExternalRelation(ExternalRelation ERelation, CallBase &Call) {
  auto From = instantiateInterfaceValue(ERelation.From, Call);
  if (!From)
    return None;
  auto To = instantiateInterfaceValue(ERelation.To, Call);
  if (!To)
    return None;
  return InstantiatedRelation{*From, *To, ERelation.Offset};
}

Optional<InstantiatedAttr> instantiateExternalAttribute(ExternalAttribute EAttr,
                                                        CallBase &Call) {
  auto Value = instantiateInterfaceValue(EAttr.IValue, Call);
  if (!Value)
    return None;
  return InstantiatedAttr{*Value, EAttr.Attr};
}
}
}
