//===-- Attributes.cpp - Implement AttributesList -------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// \file
// \brief This file implements the Attribute, AttributeImpl, AttrBuilder,
// AttributeSetImpl, and AttributeSet classes.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/Attributes.h"
#include "AttributeImpl.h"
#include "LLVMContextImpl.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Atomic.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
using namespace llvm;

//===----------------------------------------------------------------------===//
// Attribute Construction Methods
//===----------------------------------------------------------------------===//

Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
                         uint64_t Val) {
  LLVMContextImpl *pImpl = Context.pImpl;
  FoldingSetNodeID ID;
  ID.AddInteger(Kind);
  if (Val) ID.AddInteger(Val);

  void *InsertPoint;
  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);

  if (!PA) {
    // If we didn't find any existing attributes of the same shape then create a
    // new one and insert it.
    PA = !Val ?
      new AttributeImpl(Context, Kind) :
      new AttributeImpl(Context, Kind, Val);
    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
  }

  // Return the Attribute that we found or created.
  return Attribute(PA);
}

Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
  LLVMContextImpl *pImpl = Context.pImpl;
  FoldingSetNodeID ID;
  ID.AddString(Kind);
  if (!Val.empty()) ID.AddString(Val);

  void *InsertPoint;
  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);

  if (!PA) {
    // If we didn't find any existing attributes of the same shape then create a
    // new one and insert it.
    PA = new AttributeImpl(Context, Kind, Val);
    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
  }

  // Return the Attribute that we found or created.
  return Attribute(PA);
}

Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
  assert(Align <= 0x40000000 && "Alignment too large.");
  return get(Context, Alignment, Align);
}

Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
                                           uint64_t Align) {
  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
  assert(Align <= 0x100 && "Alignment too large.");
  return get(Context, StackAlignment, Align);
}

//===----------------------------------------------------------------------===//
// Attribute Accessor Methods
//===----------------------------------------------------------------------===//

bool Attribute::isEnumAttribute() const {
  return pImpl && pImpl->isEnumAttribute();
}

bool Attribute::isAlignAttribute() const {
  return pImpl && pImpl->isAlignAttribute();
}

bool Attribute::isStringAttribute() const {
  return pImpl && pImpl->isStringAttribute();
}

Attribute::AttrKind Attribute::getKindAsEnum() const {
  assert((isEnumAttribute() || isAlignAttribute()) &&
         "Invalid attribute type to get the kind as an enum!");
  return pImpl ? pImpl->getKindAsEnum() : None;
}

uint64_t Attribute::getValueAsInt() const {
  assert(isAlignAttribute() &&
         "Expected the attribute to be an alignment attribute!");
  return pImpl ? pImpl->getValueAsInt() : 0;
}

StringRef Attribute::getKindAsString() const {
  assert(isStringAttribute() &&
         "Invalid attribute type to get the kind as a string!");
  return pImpl ? pImpl->getKindAsString() : StringRef();
}

StringRef Attribute::getValueAsString() const {
  assert(isStringAttribute() &&
         "Invalid attribute type to get the value as a string!");
  return pImpl ? pImpl->getValueAsString() : StringRef();
}

bool Attribute::hasAttribute(AttrKind Kind) const {
  return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
}

bool Attribute::hasAttribute(StringRef Kind) const {
  if (!isStringAttribute()) return false;
  return pImpl && pImpl->hasAttribute(Kind);
}

/// This returns the alignment field of an attribute as a byte alignment value.
unsigned Attribute::getAlignment() const {
  assert(hasAttribute(Attribute::Alignment) &&
         "Trying to get alignment from non-alignment attribute!");
  return pImpl->getValueAsInt();
}

/// This returns the stack alignment field of an attribute as a byte alignment
/// value.
unsigned Attribute::getStackAlignment() const {
  assert(hasAttribute(Attribute::StackAlignment) &&
         "Trying to get alignment from non-alignment attribute!");
  return pImpl->getValueAsInt();
}

std::string Attribute::getAsString(bool InAttrGrp) const {
  if (!pImpl) return "";

  if (hasAttribute(Attribute::SanitizeAddress))
    return "sanitize_address";
  if (hasAttribute(Attribute::AlwaysInline))
    return "alwaysinline";
  if (hasAttribute(Attribute::ByVal))
    return "byval";
  if (hasAttribute(Attribute::InlineHint))
    return "inlinehint";
  if (hasAttribute(Attribute::InReg))
    return "inreg";
  if (hasAttribute(Attribute::MinSize))
    return "minsize";
  if (hasAttribute(Attribute::Naked))
    return "naked";
  if (hasAttribute(Attribute::Nest))
    return "nest";
  if (hasAttribute(Attribute::NoAlias))
    return "noalias";
  if (hasAttribute(Attribute::NoBuiltin))
    return "nobuiltin";
  if (hasAttribute(Attribute::NoCapture))
    return "nocapture";
  if (hasAttribute(Attribute::NoDuplicate))
    return "noduplicate";
  if (hasAttribute(Attribute::NoImplicitFloat))
    return "noimplicitfloat";
  if (hasAttribute(Attribute::NoInline))
    return "noinline";
  if (hasAttribute(Attribute::NonLazyBind))
    return "nonlazybind";
  if (hasAttribute(Attribute::NoRedZone))
    return "noredzone";
  if (hasAttribute(Attribute::NoReturn))
    return "noreturn";
  if (hasAttribute(Attribute::NoUnwind))
    return "nounwind";
  if (hasAttribute(Attribute::OptimizeForSize))
    return "optsize";
  if (hasAttribute(Attribute::ReadNone))
    return "readnone";
  if (hasAttribute(Attribute::ReadOnly))
    return "readonly";
  if (hasAttribute(Attribute::ReturnsTwice))
    return "returns_twice";
  if (hasAttribute(Attribute::SExt))
    return "signext";
  if (hasAttribute(Attribute::StackProtect))
    return "ssp";
  if (hasAttribute(Attribute::StackProtectReq))
    return "sspreq";
  if (hasAttribute(Attribute::StackProtectStrong))
    return "sspstrong";
  if (hasAttribute(Attribute::StructRet))
    return "sret";
  if (hasAttribute(Attribute::SanitizeThread))
    return "sanitize_thread";
  if (hasAttribute(Attribute::SanitizeMemory))
    return "sanitize_memory";
  if (hasAttribute(Attribute::UWTable))
    return "uwtable";
  if (hasAttribute(Attribute::ZExt))
    return "zeroext";

  // FIXME: These should be output like this:
  //
  //   align=4
  //   alignstack=8
  //
  if (hasAttribute(Attribute::Alignment)) {
    std::string Result;
    Result += "align";
    Result += (InAttrGrp) ? "=" : " ";
    Result += utostr(getValueAsInt());
    return Result;
  }

  if (hasAttribute(Attribute::StackAlignment)) {
    std::string Result;
    Result += "alignstack";
    if (InAttrGrp) {
      Result += "=";
      Result += utostr(getValueAsInt());
    } else {
      Result += "(";
      Result += utostr(getValueAsInt());
      Result += ")";
    }
    return Result;
  }

  // Convert target-dependent attributes to strings of the form:
  //
  //   "kind"
  //   "kind" = "value"
  //
  if (isStringAttribute()) {
    std::string Result;
    Result += '\"' + getKindAsString().str() + '"';

    StringRef Val = pImpl->getValueAsString();
    if (Val.empty()) return Result;

    Result += "=\"" + Val.str() + '"';
    return Result;
  }

  llvm_unreachable("Unknown attribute");
}

bool Attribute::operator<(Attribute A) const {
  if (!pImpl && !A.pImpl) return false;
  if (!pImpl) return true;
  if (!A.pImpl) return false;
  return *pImpl < *A.pImpl;
}

//===----------------------------------------------------------------------===//
// AttributeImpl Definition
//===----------------------------------------------------------------------===//

AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind Kind)
  : Context(C), Entry(new EnumAttributeEntry(Kind)) {}

AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind Kind,
                             unsigned Align)
  : Context(C) {
  assert((Kind == Attribute::Alignment || Kind == Attribute::StackAlignment) &&
         "Wrong kind for alignment attribute!");
  Entry = new AlignAttributeEntry(Kind, Align);
}

AttributeImpl::AttributeImpl(LLVMContext &C, StringRef Kind, StringRef Val)
  : Context(C), Entry(new StringAttributeEntry(Kind, Val)) {}

AttributeImpl::~AttributeImpl() {
  delete Entry;
}

bool AttributeImpl::isEnumAttribute() const {
  return isa<EnumAttributeEntry>(Entry);
}

bool AttributeImpl::isAlignAttribute() const {
  return isa<AlignAttributeEntry>(Entry);
}

bool AttributeImpl::isStringAttribute() const {
  return isa<StringAttributeEntry>(Entry);
}

bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
  if (isStringAttribute()) return false;
  return getKindAsEnum() == A;
}

bool AttributeImpl::hasAttribute(StringRef Kind) const {
  if (!isStringAttribute()) return false;
  return getKindAsString() == Kind;
}

Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
  if (EnumAttributeEntry *E = dyn_cast<EnumAttributeEntry>(Entry))
    return E->getEnumKind();
  return cast<AlignAttributeEntry>(Entry)->getEnumKind();
}

uint64_t AttributeImpl::getValueAsInt() const {
  return cast<AlignAttributeEntry>(Entry)->getAlignment();
}

StringRef AttributeImpl::getKindAsString() const {
  return cast<StringAttributeEntry>(Entry)->getStringKind();
}

StringRef AttributeImpl::getValueAsString() const {
  return cast<StringAttributeEntry>(Entry)->getStringValue();
}

bool AttributeImpl::operator<(const AttributeImpl &AI) const {
  // This sorts the attributes with Attribute::AttrKinds coming first (sorted
  // relative to their enum value) and then strings.
  if (isEnumAttribute()) {
    if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
    if (AI.isAlignAttribute()) return true;
    if (AI.isStringAttribute()) return true;
  }

  if (isAlignAttribute()) {
    if (AI.isEnumAttribute()) return false;
    if (AI.isAlignAttribute()) return getValueAsInt() < AI.getValueAsInt();
    if (AI.isStringAttribute()) return true;
  }

  if (AI.isEnumAttribute()) return false;
  if (AI.isAlignAttribute()) return false;
  if (getKindAsString() == AI.getKindAsString())
    return getValueAsString() < AI.getValueAsString();
  return getKindAsString() < AI.getKindAsString();
}

uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) {
  // FIXME: Remove this.
  switch (Val) {
  case Attribute::EndAttrKinds:
    llvm_unreachable("Synthetic enumerators which should never get here");

  case Attribute::None:            return 0;
  case Attribute::ZExt:            return 1 << 0;
  case Attribute::SExt:            return 1 << 1;
  case Attribute::NoReturn:        return 1 << 2;
  case Attribute::InReg:           return 1 << 3;
  case Attribute::StructRet:       return 1 << 4;
  case Attribute::NoUnwind:        return 1 << 5;
  case Attribute::NoAlias:         return 1 << 6;
  case Attribute::ByVal:           return 1 << 7;
  case Attribute::Nest:            return 1 << 8;
  case Attribute::ReadNone:        return 1 << 9;
  case Attribute::ReadOnly:        return 1 << 10;
  case Attribute::NoInline:        return 1 << 11;
  case Attribute::AlwaysInline:    return 1 << 12;
  case Attribute::OptimizeForSize: return 1 << 13;
  case Attribute::StackProtect:    return 1 << 14;
  case Attribute::StackProtectReq: return 1 << 15;
  case Attribute::Alignment:       return 31 << 16;
  case Attribute::NoCapture:       return 1 << 21;
  case Attribute::NoRedZone:       return 1 << 22;
  case Attribute::NoImplicitFloat: return 1 << 23;
  case Attribute::Naked:           return 1 << 24;
  case Attribute::InlineHint:      return 1 << 25;
  case Attribute::StackAlignment:  return 7 << 26;
  case Attribute::ReturnsTwice:    return 1 << 29;
  case Attribute::UWTable:         return 1 << 30;
  case Attribute::NonLazyBind:     return 1U << 31;
  case Attribute::SanitizeAddress: return 1ULL << 32;
  case Attribute::MinSize:         return 1ULL << 33;
  case Attribute::NoDuplicate:     return 1ULL << 34;
  case Attribute::StackProtectStrong: return 1ULL << 35;
  case Attribute::SanitizeThread:  return 1ULL << 36;
  case Attribute::SanitizeMemory:  return 1ULL << 37;
  case Attribute::NoBuiltin:       return 1ULL << 38;
  }
  llvm_unreachable("Unsupported attribute type");
}

//===----------------------------------------------------------------------===//
// AttributeSetNode Definition
//===----------------------------------------------------------------------===//

AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
                                        ArrayRef<Attribute> Attrs) {
  if (Attrs.empty())
    return 0;

  // Otherwise, build a key to look up the existing attributes.
  LLVMContextImpl *pImpl = C.pImpl;
  FoldingSetNodeID ID;

  SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
  array_pod_sort(SortedAttrs.begin(), SortedAttrs.end());

  for (SmallVectorImpl<Attribute>::iterator I = SortedAttrs.begin(),
         E = SortedAttrs.end(); I != E; ++I)
    I->Profile(ID);

  void *InsertPoint;
  AttributeSetNode *PA =
    pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);

  // If we didn't find any existing attributes of the same shape then create a
  // new one and insert it.
  if (!PA) {
    PA = new AttributeSetNode(SortedAttrs);
    pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
  }

  // Return the AttributesListNode that we found or created.
  return PA;
}

bool AttributeSetNode::hasAttribute(Attribute::AttrKind Kind) const {
  for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(),
         E = AttrList.end(); I != E; ++I)
    if (I->hasAttribute(Kind))
      return true;
  return false;
}

bool AttributeSetNode::hasAttribute(StringRef Kind) const {
  for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(),
         E = AttrList.end(); I != E; ++I)
    if (I->hasAttribute(Kind))
      return true;
  return false;
}

Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
  for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(),
         E = AttrList.end(); I != E; ++I)
    if (I->hasAttribute(Kind))
      return *I;
  return Attribute();
}

Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
  for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(),
         E = AttrList.end(); I != E; ++I)
    if (I->hasAttribute(Kind))
      return *I;
  return Attribute();
}

unsigned AttributeSetNode::getAlignment() const {
  for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(),
         E = AttrList.end(); I != E; ++I)
    if (I->hasAttribute(Attribute::Alignment))
      return I->getAlignment();
  return 0;
}

unsigned AttributeSetNode::getStackAlignment() const {
  for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(),
         E = AttrList.end(); I != E; ++I)
    if (I->hasAttribute(Attribute::StackAlignment))
      return I->getStackAlignment();
  return 0;
}

std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
  std::string Str = "";
  for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(),
         E = AttrList.end(); I != E; ) {
    Str += I->getAsString(InAttrGrp);
    if (++I != E) Str += " ";
  }
  return Str;
}

//===----------------------------------------------------------------------===//
// AttributeSetImpl Definition
//===----------------------------------------------------------------------===//

uint64_t AttributeSetImpl::Raw(uint64_t Index) const {
  for (unsigned I = 0, E = getNumAttributes(); I != E; ++I) {
    if (getSlotIndex(I) != Index) continue;
    const AttributeSetNode *ASN = AttrNodes[I].second;
    uint64_t Mask = 0;

    for (AttributeSetNode::const_iterator II = ASN->begin(),
           IE = ASN->end(); II != IE; ++II) {
      Attribute Attr = *II;

      // This cannot handle string attributes.
      if (Attr.isStringAttribute()) continue;

      Attribute::AttrKind Kind = Attr.getKindAsEnum();

      if (Kind == Attribute::Alignment)
        Mask |= (Log2_32(ASN->getAlignment()) + 1) << 16;
      else if (Kind == Attribute::StackAlignment)
        Mask |= (Log2_32(ASN->getStackAlignment()) + 1) << 26;
      else
        Mask |= AttributeImpl::getAttrMask(Kind);
    }

    return Mask;
  }

  return 0;
}

//===----------------------------------------------------------------------===//
// AttributeSet Construction and Mutation Methods
//===----------------------------------------------------------------------===//

AttributeSet
AttributeSet::getImpl(LLVMContext &C,
                      ArrayRef<std::pair<unsigned, AttributeSetNode*> > Attrs) {
  LLVMContextImpl *pImpl = C.pImpl;
  FoldingSetNodeID ID;
  AttributeSetImpl::Profile(ID, Attrs);

  void *InsertPoint;
  AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);

  // If we didn't find any existing attributes of the same shape then
  // create a new one and insert it.
  if (!PA) {
    PA = new AttributeSetImpl(C, Attrs);
    pImpl->AttrsLists.InsertNode(PA, InsertPoint);
  }

  // Return the AttributesList that we found or created.
  return AttributeSet(PA);
}

AttributeSet AttributeSet::get(LLVMContext &C,
                               ArrayRef<std::pair<unsigned, Attribute> > Attrs){
  // If there are no attributes then return a null AttributesList pointer.
  if (Attrs.empty())
    return AttributeSet();

#ifndef NDEBUG
  for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
    assert((!i || Attrs[i-1].first <= Attrs[i].first) &&
           "Misordered Attributes list!");
    assert(!Attrs[i].second.hasAttribute(Attribute::None) &&
           "Pointless attribute!");
  }
#endif

  // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
  // list.
  SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrPairVec;
  for (ArrayRef<std::pair<unsigned, Attribute> >::iterator I = Attrs.begin(),
         E = Attrs.end(); I != E; ) {
    unsigned Index = I->first;
    SmallVector<Attribute, 4> AttrVec;
    while (I != E && I->first == Index) {
      AttrVec.push_back(I->second);
      ++I;
    }

    AttrPairVec.push_back(std::make_pair(Index,
                                         AttributeSetNode::get(C, AttrVec)));
  }

  return getImpl(C, AttrPairVec);
}

AttributeSet AttributeSet::get(LLVMContext &C,
                               ArrayRef<std::pair<unsigned,
                                                  AttributeSetNode*> > Attrs) {
  // If there are no attributes then return a null AttributesList pointer.
  if (Attrs.empty())
    return AttributeSet();

  return getImpl(C, Attrs);
}

AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, AttrBuilder &B) {
  if (!B.hasAttributes())
    return AttributeSet();

  // Add target-independent attributes.
  SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
  for (Attribute::AttrKind Kind = Attribute::None;
       Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) {
    if (!B.contains(Kind))
      continue;

    if (Kind == Attribute::Alignment)
      Attrs.push_back(std::make_pair(Idx, Attribute::
                                     getWithAlignment(C, B.getAlignment())));
    else if (Kind == Attribute::StackAlignment)
      Attrs.push_back(std::make_pair(Idx, Attribute::
                              getWithStackAlignment(C, B.getStackAlignment())));
    else
      Attrs.push_back(std::make_pair(Idx, Attribute::get(C, Kind)));
  }

  // Add target-dependent (string) attributes.
  for (AttrBuilder::td_iterator I = B.td_begin(), E = B.td_end();
       I != E; ++I)
    Attrs.push_back(std::make_pair(Idx, Attribute::get(C, I->first,I->second)));

  return get(C, Attrs);
}

AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx,
                               ArrayRef<Attribute::AttrKind> Kind) {
  SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
  for (ArrayRef<Attribute::AttrKind>::iterator I = Kind.begin(),
         E = Kind.end(); I != E; ++I)
    Attrs.push_back(std::make_pair(Idx, Attribute::get(C, *I)));
  return get(C, Attrs);
}

AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) {
  if (Attrs.empty()) return AttributeSet();

  SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrNodeVec;
  for (unsigned I = 0, E = Attrs.size(); I != E; ++I) {
    AttributeSet AS = Attrs[I];
    if (!AS.pImpl) continue;
    AttrNodeVec.append(AS.pImpl->AttrNodes.begin(), AS.pImpl->AttrNodes.end());
  }

  return getImpl(C, AttrNodeVec);
}

AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Idx,
                                        Attribute::AttrKind Attr) const {
  if (hasAttribute(Idx, Attr)) return *this;
  return addAttributes(C, Idx, AttributeSet::get(C, Idx, Attr));
}

AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Idx,
                                         AttributeSet Attrs) const {
  if (!pImpl) return Attrs;
  if (!Attrs.pImpl) return *this;

#ifndef NDEBUG
  // FIXME it is not obvious how this should work for alignment. For now, say
  // we can't change a known alignment.
  unsigned OldAlign = getParamAlignment(Idx);
  unsigned NewAlign = Attrs.getParamAlignment(Idx);
  assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
         "Attempt to change alignment!");
#endif

  // Add the attribute slots before the one we're trying to add.
  SmallVector<AttributeSet, 4> AttrSet;
  uint64_t NumAttrs = pImpl->getNumAttributes();
  AttributeSet AS;
  uint64_t LastIndex = 0;
  for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
    if (getSlotIndex(I) >= Idx) {
      if (getSlotIndex(I) == Idx) AS = getSlotAttributes(LastIndex++);
      break;
    }
    LastIndex = I + 1;
    AttrSet.push_back(getSlotAttributes(I));
  }

  // Now add the attribute into the correct slot. There may already be an
  // AttributeSet there.
  AttrBuilder B(AS, Idx);

  for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I)
    if (Attrs.getSlotIndex(I) == Idx) {
      for (AttributeSetImpl::const_iterator II = Attrs.pImpl->begin(I),
             IE = Attrs.pImpl->end(I); II != IE; ++II)
        B.addAttribute(*II);
      break;
    }

  AttrSet.push_back(AttributeSet::get(C, Idx, B));

  // Add the remaining attribute slots.
  for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
    AttrSet.push_back(getSlotAttributes(I));

  return get(C, AttrSet);
}

AttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Idx,
                                           Attribute::AttrKind Attr) const {
  if (!hasAttribute(Idx, Attr)) return *this;
  return removeAttributes(C, Idx, AttributeSet::get(C, Idx, Attr));
}

AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Idx,
                                            AttributeSet Attrs) const {
  if (!pImpl) return AttributeSet();
  if (!Attrs.pImpl) return *this;

#ifndef NDEBUG
  // FIXME it is not obvious how this should work for alignment.
  // For now, say we can't pass in alignment, which no current use does.
  assert(!Attrs.hasAttribute(Idx, Attribute::Alignment) &&
         "Attempt to change alignment!");
#endif

  // Add the attribute slots before the one we're trying to add.
  SmallVector<AttributeSet, 4> AttrSet;
  uint64_t NumAttrs = pImpl->getNumAttributes();
  AttributeSet AS;
  uint64_t LastIndex = 0;
  for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
    if (getSlotIndex(I) >= Idx) {
      if (getSlotIndex(I) == Idx) AS = getSlotAttributes(LastIndex++);
      break;
    }
    LastIndex = I + 1;
    AttrSet.push_back(getSlotAttributes(I));
  }

  // Now remove the attribute from the correct slot. There may already be an
  // AttributeSet there.
  AttrBuilder B(AS, Idx);

  for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I)
    if (Attrs.getSlotIndex(I) == Idx) {
      B.removeAttributes(Attrs.pImpl->getSlotAttributes(I), Idx);
      break;
    }

  AttrSet.push_back(AttributeSet::get(C, Idx, B));

  // Add the remaining attribute slots.
  for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
    AttrSet.push_back(getSlotAttributes(I));

  return get(C, AttrSet);
}

//===----------------------------------------------------------------------===//
// AttributeSet Accessor Methods
//===----------------------------------------------------------------------===//

LLVMContext &AttributeSet::getContext() const {
  return pImpl->getContext();
}

AttributeSet AttributeSet::getParamAttributes(unsigned Idx) const {
  return pImpl && hasAttributes(Idx) ?
    AttributeSet::get(pImpl->getContext(),
                      ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
                        std::make_pair(Idx, getAttributes(Idx)))) :
    AttributeSet();
}

AttributeSet AttributeSet::getRetAttributes() const {
  return pImpl && hasAttributes(ReturnIndex) ?
    AttributeSet::get(pImpl->getContext(),
                      ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
                        std::make_pair(ReturnIndex,
                                       getAttributes(ReturnIndex)))) :
    AttributeSet();
}

AttributeSet AttributeSet::getFnAttributes() const {
  return pImpl && hasAttributes(FunctionIndex) ?
    AttributeSet::get(pImpl->getContext(),
                      ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
                        std::make_pair(FunctionIndex,
                                       getAttributes(FunctionIndex)))) :
    AttributeSet();
}

bool AttributeSet::hasAttribute(unsigned Index, Attribute::AttrKind Kind) const{
  AttributeSetNode *ASN = getAttributes(Index);
  return ASN ? ASN->hasAttribute(Kind) : false;
}

bool AttributeSet::hasAttribute(unsigned Index, StringRef Kind) const {
  AttributeSetNode *ASN = getAttributes(Index);
  return ASN ? ASN->hasAttribute(Kind) : false;
}

bool AttributeSet::hasAttributes(unsigned Index) const {
  AttributeSetNode *ASN = getAttributes(Index);
  return ASN ? ASN->hasAttributes() : false;
}

/// \brief Return true if the specified attribute is set for at least one
/// parameter or for the return value.
bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr) const {
  if (pImpl == 0) return false;

  for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I)
    for (AttributeSetImpl::const_iterator II = pImpl->begin(I),
           IE = pImpl->end(I); II != IE; ++II)
      if (II->hasAttribute(Attr))
        return true;

  return false;
}

Attribute AttributeSet::getAttribute(unsigned Index,
                                     Attribute::AttrKind Kind) const {
  AttributeSetNode *ASN = getAttributes(Index);
  return ASN ? ASN->getAttribute(Kind) : Attribute();
}

Attribute AttributeSet::getAttribute(unsigned Index,
                                     StringRef Kind) const {
  AttributeSetNode *ASN = getAttributes(Index);
  return ASN ? ASN->getAttribute(Kind) : Attribute();
}

unsigned AttributeSet::getParamAlignment(unsigned Index) const {
  AttributeSetNode *ASN = getAttributes(Index);
  return ASN ? ASN->getAlignment() : 0;
}

unsigned AttributeSet::getStackAlignment(unsigned Index) const {
  AttributeSetNode *ASN = getAttributes(Index);
  return ASN ? ASN->getStackAlignment() : 0;
}

std::string AttributeSet::getAsString(unsigned Index,
                                      bool InAttrGrp) const {
  AttributeSetNode *ASN = getAttributes(Index);
  return ASN ? ASN->getAsString(InAttrGrp) : std::string("");
}

/// \brief The attributes for the specified index are returned.
AttributeSetNode *AttributeSet::getAttributes(unsigned Idx) const {
  if (!pImpl) return 0;

  // Loop through to find the attribute node we want.
  for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I)
    if (pImpl->getSlotIndex(I) == Idx)
      return pImpl->getSlotNode(I);

  return 0;
}

AttributeSet::iterator AttributeSet::begin(unsigned Idx) const {
  if (!pImpl)
    return ArrayRef<Attribute>().begin();
  return pImpl->begin(Idx);
}

AttributeSet::iterator AttributeSet::end(unsigned Idx) const {
  if (!pImpl)
    return ArrayRef<Attribute>().end();
  return pImpl->end(Idx);
}

//===----------------------------------------------------------------------===//
// AttributeSet Introspection Methods
//===----------------------------------------------------------------------===//

/// \brief Return the number of slots used in this attribute list.  This is the
/// number of arguments that have an attribute set on them (including the
/// function itself).
unsigned AttributeSet::getNumSlots() const {
  return pImpl ? pImpl->getNumAttributes() : 0;
}

uint64_t AttributeSet::getSlotIndex(unsigned Slot) const {
  assert(pImpl && Slot < pImpl->getNumAttributes() &&
         "Slot # out of range!");
  return pImpl->getSlotIndex(Slot);
}

AttributeSet AttributeSet::getSlotAttributes(unsigned Slot) const {
  assert(pImpl && Slot < pImpl->getNumAttributes() &&
         "Slot # out of range!");
  return pImpl->getSlotAttributes(Slot);
}

uint64_t AttributeSet::Raw(unsigned Index) const {
  // FIXME: Remove this.
  return pImpl ? pImpl->Raw(Index) : 0;
}

void AttributeSet::dump() const {
  dbgs() << "PAL[\n";

  for (unsigned i = 0, e = getNumSlots(); i < e; ++i) {
    uint64_t Index = getSlotIndex(i);
    dbgs() << "  { ";
    if (Index == ~0U)
      dbgs() << "~0U";
    else
      dbgs() << Index;
    dbgs() << " => " << getAsString(Index) << " }\n";
  }

  dbgs() << "]\n";
}

//===----------------------------------------------------------------------===//
// AttrBuilder Method Implementations
//===----------------------------------------------------------------------===//

AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx)
  : Attrs(0), Alignment(0), StackAlignment(0) {
  AttributeSetImpl *pImpl = AS.pImpl;
  if (!pImpl) return;

  for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) {
    if (pImpl->getSlotIndex(I) != Idx) continue;

    for (AttributeSetImpl::const_iterator II = pImpl->begin(I),
           IE = pImpl->end(I); II != IE; ++II)
      addAttribute(*II);

    break;
  }
}

void AttrBuilder::clear() {
  Attrs.reset();
  Alignment = StackAlignment = 0;
}

AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
  assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
  assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
         "Adding alignment attribute without adding alignment value!");
  Attrs[Val] = true;
  return *this;
}

AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
  if (Attr.isStringAttribute()) {
    addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
    return *this;
  }

  Attribute::AttrKind Kind = Attr.getKindAsEnum();
  Attrs[Kind] = true;

  if (Kind == Attribute::Alignment)
    Alignment = Attr.getAlignment();
  else if (Kind == Attribute::StackAlignment)
    StackAlignment = Attr.getStackAlignment();
  return *this;
}

AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
  TargetDepAttrs[A] = V;
  return *this;
}

AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
  assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
  Attrs[Val] = false;

  if (Val == Attribute::Alignment)
    Alignment = 0;
  else if (Val == Attribute::StackAlignment)
    StackAlignment = 0;

  return *this;
}

AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) {
  unsigned Idx = ~0U;
  for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I)
    if (A.getSlotIndex(I) == Index) {
      Idx = I;
      break;
    }

  assert(Idx != ~0U && "Couldn't find index in AttributeSet!");

  for (AttributeSet::iterator I = A.begin(Idx), E = A.end(Idx); I != E; ++I) {
    Attribute Attr = *I;
    if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) {
      Attribute::AttrKind Kind = I->getKindAsEnum();
      Attrs[Kind] = false;

      if (Kind == Attribute::Alignment)
        Alignment = 0;
      else if (Kind == Attribute::StackAlignment)
        StackAlignment = 0;
    } else {
      assert(Attr.isStringAttribute() && "Invalid attribute type!");
      std::map<std::string, std::string>::iterator
        Iter = TargetDepAttrs.find(Attr.getKindAsString());
      if (Iter != TargetDepAttrs.end())
        TargetDepAttrs.erase(Iter);
    }
  }

  return *this;
}

AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
  std::map<std::string, std::string>::iterator I = TargetDepAttrs.find(A);
  if (I != TargetDepAttrs.end())
    TargetDepAttrs.erase(I);
  return *this;
}

AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
  if (Align == 0) return *this;

  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
  assert(Align <= 0x40000000 && "Alignment too large.");

  Attrs[Attribute::Alignment] = true;
  Alignment = Align;
  return *this;
}

AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) {
  // Default alignment, allow the target to define how to align it.
  if (Align == 0) return *this;

  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
  assert(Align <= 0x100 && "Alignment too large.");

  Attrs[Attribute::StackAlignment] = true;
  StackAlignment = Align;
  return *this;
}

AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
  // FIXME: What if both have alignments, but they don't match?!
  if (!Alignment)
    Alignment = B.Alignment;

  if (!StackAlignment)
    StackAlignment = B.StackAlignment;

  Attrs |= B.Attrs;

  for (td_const_iterator I = B.TargetDepAttrs.begin(),
         E = B.TargetDepAttrs.end(); I != E; ++I)
    TargetDepAttrs[I->first] = I->second;

  return *this;
}

bool AttrBuilder::contains(StringRef A) const {
  return TargetDepAttrs.find(A) != TargetDepAttrs.end();
}

bool AttrBuilder::hasAttributes() const {
  return !Attrs.none() || !TargetDepAttrs.empty();
}

bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const {
  unsigned Idx = ~0U;
  for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I)
    if (A.getSlotIndex(I) == Index) {
      Idx = I;
      break;
    }

  assert(Idx != ~0U && "Couldn't find the index!");

  for (AttributeSet::iterator I = A.begin(Idx), E = A.end(Idx);
       I != E; ++I) {
    Attribute Attr = *I;
    if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) {
      if (Attrs[I->getKindAsEnum()])
        return true;
    } else {
      assert(Attr.isStringAttribute() && "Invalid attribute kind!");
      return TargetDepAttrs.find(Attr.getKindAsString())!=TargetDepAttrs.end();
    }
  }

  return false;
}

bool AttrBuilder::hasAlignmentAttr() const {
  return Alignment != 0;
}

bool AttrBuilder::operator==(const AttrBuilder &B) {
  if (Attrs != B.Attrs)
    return false;

  for (td_const_iterator I = TargetDepAttrs.begin(),
         E = TargetDepAttrs.end(); I != E; ++I)
    if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
      return false;

  return Alignment == B.Alignment && StackAlignment == B.StackAlignment;
}

void AttrBuilder::removeFunctionOnlyAttrs() {
  removeAttribute(Attribute::NoReturn)
    .removeAttribute(Attribute::NoUnwind)
    .removeAttribute(Attribute::ReadNone)
    .removeAttribute(Attribute::ReadOnly)
    .removeAttribute(Attribute::NoInline)
    .removeAttribute(Attribute::AlwaysInline)
    .removeAttribute(Attribute::OptimizeForSize)
    .removeAttribute(Attribute::StackProtect)
    .removeAttribute(Attribute::StackProtectReq)
    .removeAttribute(Attribute::StackProtectStrong)
    .removeAttribute(Attribute::NoRedZone)
    .removeAttribute(Attribute::NoImplicitFloat)
    .removeAttribute(Attribute::Naked)
    .removeAttribute(Attribute::InlineHint)
    .removeAttribute(Attribute::StackAlignment)
    .removeAttribute(Attribute::UWTable)
    .removeAttribute(Attribute::NonLazyBind)
    .removeAttribute(Attribute::ReturnsTwice)
    .removeAttribute(Attribute::SanitizeAddress)
    .removeAttribute(Attribute::SanitizeThread)
    .removeAttribute(Attribute::SanitizeMemory)
    .removeAttribute(Attribute::MinSize)
    .removeAttribute(Attribute::NoDuplicate)
    .removeAttribute(Attribute::NoBuiltin);
}

AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) {
  // FIXME: Remove this in 4.0.
  if (!Val) return *this;

  for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
       I = Attribute::AttrKind(I + 1)) {
    if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) {
      Attrs[I] = true;
 
      if (I == Attribute::Alignment)
        Alignment = 1ULL << ((A >> 16) - 1);
      else if (I == Attribute::StackAlignment)
        StackAlignment = 1ULL << ((A >> 26)-1);
    }
  }
 
  return *this;
}

//===----------------------------------------------------------------------===//
// AttributeFuncs Function Defintions
//===----------------------------------------------------------------------===//

/// \brief Which attributes cannot be applied to a type.
AttributeSet AttributeFuncs::typeIncompatible(Type *Ty, uint64_t Index) {
  AttrBuilder Incompatible;

  if (!Ty->isIntegerTy())
    // Attribute that only apply to integers.
    Incompatible.addAttribute(Attribute::SExt)
      .addAttribute(Attribute::ZExt);

  if (!Ty->isPointerTy())
    // Attribute that only apply to pointers.
    Incompatible.addAttribute(Attribute::ByVal)
      .addAttribute(Attribute::Nest)
      .addAttribute(Attribute::NoAlias)
      .addAttribute(Attribute::NoCapture)
      .addAttribute(Attribute::StructRet);

  return AttributeSet::get(Ty->getContext(), Index, Incompatible);
}
