Attributes.cpp revision 382da62ec274feead85e7be364ab5d4fd0281d98
16508be1224ddec08910c464d2a905c4c2e1f7d80Raphael//===-- Attributes.cpp - Implement AttributesList -------------------------===//
26508be1224ddec08910c464d2a905c4c2e1f7d80Raphael//
36508be1224ddec08910c464d2a905c4c2e1f7d80Raphael//                     The LLVM Compiler Infrastructure
46508be1224ddec08910c464d2a905c4c2e1f7d80Raphael//
56508be1224ddec08910c464d2a905c4c2e1f7d80Raphael// This file is distributed under the University of Illinois Open Source
66508be1224ddec08910c464d2a905c4c2e1f7d80Raphael// License. See LICENSE.TXT for details.
76508be1224ddec08910c464d2a905c4c2e1f7d80Raphael//
86508be1224ddec08910c464d2a905c4c2e1f7d80Raphael//===----------------------------------------------------------------------===//
96508be1224ddec08910c464d2a905c4c2e1f7d80Raphael//
106508be1224ddec08910c464d2a905c4c2e1f7d80Raphael// This file implements the AttributesList class and Attribute utilities.
116508be1224ddec08910c464d2a905c4c2e1f7d80Raphael//
126508be1224ddec08910c464d2a905c4c2e1f7d80Raphael//===----------------------------------------------------------------------===//
136508be1224ddec08910c464d2a905c4c2e1f7d80Raphael
146508be1224ddec08910c464d2a905c4c2e1f7d80Raphael#include "llvm/Attributes.h"
156508be1224ddec08910c464d2a905c4c2e1f7d80Raphael#include "llvm/Type.h"
166508be1224ddec08910c464d2a905c4c2e1f7d80Raphael#include "llvm/ADT/StringExtras.h"
176508be1224ddec08910c464d2a905c4c2e1f7d80Raphael#include "llvm/ADT/FoldingSet.h"
186508be1224ddec08910c464d2a905c4c2e1f7d80Raphael#include "llvm/Support/Streams.h"
196508be1224ddec08910c464d2a905c4c2e1f7d80Raphael#include "llvm/Support/ManagedStatic.h"
206508be1224ddec08910c464d2a905c4c2e1f7d80Raphaelusing namespace llvm;
216508be1224ddec08910c464d2a905c4c2e1f7d80Raphael
226508be1224ddec08910c464d2a905c4c2e1f7d80Raphael//===----------------------------------------------------------------------===//
236508be1224ddec08910c464d2a905c4c2e1f7d80Raphael// Attribute Function Definitions
246508be1224ddec08910c464d2a905c4c2e1f7d80Raphael//===----------------------------------------------------------------------===//
256508be1224ddec08910c464d2a905c4c2e1f7d80Raphael
266508be1224ddec08910c464d2a905c4c2e1f7d80Raphaelstd::string Attribute::getAsString(Attributes Attrs) {
276508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  std::string Result;
286508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  if (Attrs & Attribute::ZExt)
296508be1224ddec08910c464d2a905c4c2e1f7d80Raphael    Result += "zeroext ";
306508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  if (Attrs & Attribute::SExt)
316508be1224ddec08910c464d2a905c4c2e1f7d80Raphael    Result += "signext ";
326508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  if (Attrs & Attribute::NoReturn)
336508be1224ddec08910c464d2a905c4c2e1f7d80Raphael    Result += "noreturn ";
34ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::NoUnwind)
35ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "nounwind ";
36ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::InReg)
37ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "inreg ";
38ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::NoAlias)
39ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "noalias ";
40ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::NoCapture)
41ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "nocapture ";
42ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::StructRet)
43ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "sret ";
44ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::ByVal)
45ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "byval ";
46ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::Nest)
47ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "nest ";
48ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::ReadNone)
49ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "readnone ";
50ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::ReadOnly)
51ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "readonly ";
52ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::OptimizeForSize)
53ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "optsize ";
54ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::NoInline)
55ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "noinline ";
56ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::AlwaysInline)
57ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "alwaysinline ";
58ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::StackProtect)
59ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "ssp ";
60ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::StackProtectReq)
61ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "sspreq ";
62ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (Attrs & Attribute::Alignment) {
63ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += "align ";
64ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += utostr(1ull << (((Attrs & Attribute::Alignment)>>16) - 1));
65ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Result += " ";
66ea66c92f80d9745721cfa28e22f2726b76579158Raphael  }
67ea66c92f80d9745721cfa28e22f2726b76579158Raphael  // Trim the trailing space.
68ea66c92f80d9745721cfa28e22f2726b76579158Raphael  assert(!Result.empty() && "Unknown attribute!");
69ea66c92f80d9745721cfa28e22f2726b76579158Raphael  Result.erase(Result.end()-1);
70ea66c92f80d9745721cfa28e22f2726b76579158Raphael  return Result;
71ea66c92f80d9745721cfa28e22f2726b76579158Raphael}
72ea66c92f80d9745721cfa28e22f2726b76579158Raphael
73ea66c92f80d9745721cfa28e22f2726b76579158RaphaelAttributes Attribute::typeIncompatible(const Type *Ty) {
74ea66c92f80d9745721cfa28e22f2726b76579158Raphael  Attributes Incompatible = None;
75ea66c92f80d9745721cfa28e22f2726b76579158Raphael
76ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (!Ty->isInteger())
77ea66c92f80d9745721cfa28e22f2726b76579158Raphael    // Attributes that only apply to integers.
78ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Incompatible |= SExt | ZExt;
79ea66c92f80d9745721cfa28e22f2726b76579158Raphael
80ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (!isa<PointerType>(Ty))
81ea66c92f80d9745721cfa28e22f2726b76579158Raphael    // Attributes that only apply to pointers.
82ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Incompatible |= ByVal | Nest | NoAlias | StructRet | NoCapture;
83ea66c92f80d9745721cfa28e22f2726b76579158Raphael
84ea66c92f80d9745721cfa28e22f2726b76579158Raphael  return Incompatible;
85ea66c92f80d9745721cfa28e22f2726b76579158Raphael}
86ea66c92f80d9745721cfa28e22f2726b76579158Raphael
87ea66c92f80d9745721cfa28e22f2726b76579158Raphael//===----------------------------------------------------------------------===//
88ea66c92f80d9745721cfa28e22f2726b76579158Raphael// AttributeListImpl Definition
89ea66c92f80d9745721cfa28e22f2726b76579158Raphael//===----------------------------------------------------------------------===//
90ea66c92f80d9745721cfa28e22f2726b76579158Raphael
91ea66c92f80d9745721cfa28e22f2726b76579158Raphaelnamespace llvm {
92ea66c92f80d9745721cfa28e22f2726b76579158Raphaelclass AttributeListImpl : public FoldingSetNode {
93ea66c92f80d9745721cfa28e22f2726b76579158Raphael  unsigned RefCount;
94ea66c92f80d9745721cfa28e22f2726b76579158Raphael
95ea66c92f80d9745721cfa28e22f2726b76579158Raphael  // AttributesList is uniqued, these should not be publicly available.
96ea66c92f80d9745721cfa28e22f2726b76579158Raphael  void operator=(const AttributeListImpl &); // Do not implement
97ea66c92f80d9745721cfa28e22f2726b76579158Raphael  AttributeListImpl(const AttributeListImpl &); // Do not implement
98ea66c92f80d9745721cfa28e22f2726b76579158Raphael  ~AttributeListImpl();                        // Private implementation
99ea66c92f80d9745721cfa28e22f2726b76579158Raphaelpublic:
100ea66c92f80d9745721cfa28e22f2726b76579158Raphael  SmallVector<AttributeWithIndex, 4> Attrs;
101ea66c92f80d9745721cfa28e22f2726b76579158Raphael
102ea66c92f80d9745721cfa28e22f2726b76579158Raphael  AttributeListImpl(const AttributeWithIndex *Attr, unsigned NumAttrs)
103ea66c92f80d9745721cfa28e22f2726b76579158Raphael    : Attrs(Attr, Attr+NumAttrs) {
104ea66c92f80d9745721cfa28e22f2726b76579158Raphael    RefCount = 0;
105ea66c92f80d9745721cfa28e22f2726b76579158Raphael  }
106ea66c92f80d9745721cfa28e22f2726b76579158Raphael
107ea66c92f80d9745721cfa28e22f2726b76579158Raphael  void AddRef() { ++RefCount; }
108ea66c92f80d9745721cfa28e22f2726b76579158Raphael  void DropRef() { if (--RefCount == 0) delete this; }
109ea66c92f80d9745721cfa28e22f2726b76579158Raphael
110ea66c92f80d9745721cfa28e22f2726b76579158Raphael  void Profile(FoldingSetNodeID &ID) const {
111ea66c92f80d9745721cfa28e22f2726b76579158Raphael    Profile(ID, &Attrs[0], Attrs.size());
112ea66c92f80d9745721cfa28e22f2726b76579158Raphael  }
113ea66c92f80d9745721cfa28e22f2726b76579158Raphael  static void Profile(FoldingSetNodeID &ID, const AttributeWithIndex *Attr,
114ea66c92f80d9745721cfa28e22f2726b76579158Raphael                      unsigned NumAttrs) {
115ea66c92f80d9745721cfa28e22f2726b76579158Raphael    for (unsigned i = 0; i != NumAttrs; ++i)
116ea66c92f80d9745721cfa28e22f2726b76579158Raphael      ID.AddInteger(uint64_t(Attr[i].Attrs) << 32 | unsigned(Attr[i].Index));
117ea66c92f80d9745721cfa28e22f2726b76579158Raphael  }
118ea66c92f80d9745721cfa28e22f2726b76579158Raphael};
119ea66c92f80d9745721cfa28e22f2726b76579158Raphael}
120ea66c92f80d9745721cfa28e22f2726b76579158Raphael
121ea66c92f80d9745721cfa28e22f2726b76579158Raphaelstatic ManagedStatic<FoldingSet<AttributeListImpl> > AttributesLists;
122ea66c92f80d9745721cfa28e22f2726b76579158Raphael
123ea66c92f80d9745721cfa28e22f2726b76579158RaphaelAttributeListImpl::~AttributeListImpl() {
124ea66c92f80d9745721cfa28e22f2726b76579158Raphael  AttributesLists->RemoveNode(this);
125ea66c92f80d9745721cfa28e22f2726b76579158Raphael}
126ea66c92f80d9745721cfa28e22f2726b76579158Raphael
127ea66c92f80d9745721cfa28e22f2726b76579158Raphael
128ea66c92f80d9745721cfa28e22f2726b76579158RaphaelAttrListPtr AttrListPtr::get(const AttributeWithIndex *Attrs, unsigned NumAttrs) {
129ea66c92f80d9745721cfa28e22f2726b76579158Raphael  // If there are no attributes then return a null AttributesList pointer.
130ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (NumAttrs == 0)
131ea66c92f80d9745721cfa28e22f2726b76579158Raphael    return AttrListPtr();
132ea66c92f80d9745721cfa28e22f2726b76579158Raphael
133ea66c92f80d9745721cfa28e22f2726b76579158Raphael#ifndef NDEBUG
134ea66c92f80d9745721cfa28e22f2726b76579158Raphael  for (unsigned i = 0; i != NumAttrs; ++i) {
135ea66c92f80d9745721cfa28e22f2726b76579158Raphael    assert(Attrs[i].Attrs != Attribute::None &&
136ea66c92f80d9745721cfa28e22f2726b76579158Raphael           "Pointless attribute!");
137ea66c92f80d9745721cfa28e22f2726b76579158Raphael    assert((!i || Attrs[i-1].Index < Attrs[i].Index) &&
138ea66c92f80d9745721cfa28e22f2726b76579158Raphael           "Misordered AttributesList!");
139ea66c92f80d9745721cfa28e22f2726b76579158Raphael  }
140ea66c92f80d9745721cfa28e22f2726b76579158Raphael#endif
141ea66c92f80d9745721cfa28e22f2726b76579158Raphael
142ea66c92f80d9745721cfa28e22f2726b76579158Raphael  // Otherwise, build a key to look up the existing attributes.
143ea66c92f80d9745721cfa28e22f2726b76579158Raphael  FoldingSetNodeID ID;
144ea66c92f80d9745721cfa28e22f2726b76579158Raphael  AttributeListImpl::Profile(ID, Attrs, NumAttrs);
145ea66c92f80d9745721cfa28e22f2726b76579158Raphael  void *InsertPos;
146ea66c92f80d9745721cfa28e22f2726b76579158Raphael  AttributeListImpl *PAL =
147ea66c92f80d9745721cfa28e22f2726b76579158Raphael    AttributesLists->FindNodeOrInsertPos(ID, InsertPos);
148ea66c92f80d9745721cfa28e22f2726b76579158Raphael
149ea66c92f80d9745721cfa28e22f2726b76579158Raphael  // If we didn't find any existing attributes of the same shape then
150ea66c92f80d9745721cfa28e22f2726b76579158Raphael  // create a new one and insert it.
151ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (!PAL) {
152ea66c92f80d9745721cfa28e22f2726b76579158Raphael    PAL = new AttributeListImpl(Attrs, NumAttrs);
153ea66c92f80d9745721cfa28e22f2726b76579158Raphael    AttributesLists->InsertNode(PAL, InsertPos);
154ea66c92f80d9745721cfa28e22f2726b76579158Raphael  }
155ea66c92f80d9745721cfa28e22f2726b76579158Raphael
156ea66c92f80d9745721cfa28e22f2726b76579158Raphael  // Return the AttributesList that we found or created.
157ea66c92f80d9745721cfa28e22f2726b76579158Raphael  return AttrListPtr(PAL);
158ea66c92f80d9745721cfa28e22f2726b76579158Raphael}
159ea66c92f80d9745721cfa28e22f2726b76579158Raphael
160ea66c92f80d9745721cfa28e22f2726b76579158Raphael
161ea66c92f80d9745721cfa28e22f2726b76579158Raphael//===----------------------------------------------------------------------===//
162ea66c92f80d9745721cfa28e22f2726b76579158Raphael// AttrListPtr Method Implementations
163ea66c92f80d9745721cfa28e22f2726b76579158Raphael//===----------------------------------------------------------------------===//
164ea66c92f80d9745721cfa28e22f2726b76579158Raphael
165ea66c92f80d9745721cfa28e22f2726b76579158RaphaelAttrListPtr::AttrListPtr(AttributeListImpl *LI) : AttrList(LI) {
166ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (LI) LI->AddRef();
167ea66c92f80d9745721cfa28e22f2726b76579158Raphael}
168ea66c92f80d9745721cfa28e22f2726b76579158Raphael
1696508be1224ddec08910c464d2a905c4c2e1f7d80RaphaelAttrListPtr::AttrListPtr(const AttrListPtr &P) : AttrList(P.AttrList) {
170ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (AttrList) AttrList->AddRef();
1716508be1224ddec08910c464d2a905c4c2e1f7d80Raphael}
1726508be1224ddec08910c464d2a905c4c2e1f7d80Raphael
173ea66c92f80d9745721cfa28e22f2726b76579158Raphaelconst AttrListPtr &AttrListPtr::operator=(const AttrListPtr &RHS) {
1746508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  if (AttrList == RHS.AttrList) return *this;
175ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (AttrList) AttrList->DropRef();
176ea66c92f80d9745721cfa28e22f2726b76579158Raphael  AttrList = RHS.AttrList;
177ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (AttrList) AttrList->AddRef();
178ea66c92f80d9745721cfa28e22f2726b76579158Raphael  return *this;
179ea66c92f80d9745721cfa28e22f2726b76579158Raphael}
180ea66c92f80d9745721cfa28e22f2726b76579158Raphael
181ea66c92f80d9745721cfa28e22f2726b76579158RaphaelAttrListPtr::~AttrListPtr() {
182ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (AttrList) AttrList->DropRef();
183ea66c92f80d9745721cfa28e22f2726b76579158Raphael}
1846508be1224ddec08910c464d2a905c4c2e1f7d80Raphael
1856508be1224ddec08910c464d2a905c4c2e1f7d80Raphael/// getNumSlots - Return the number of slots used in this attribute list.
1866508be1224ddec08910c464d2a905c4c2e1f7d80Raphael/// This is the number of arguments that have an attribute set on them
187ea66c92f80d9745721cfa28e22f2726b76579158Raphael/// (including the function itself).
188ea66c92f80d9745721cfa28e22f2726b76579158Raphaelunsigned AttrListPtr::getNumSlots() const {
189ea66c92f80d9745721cfa28e22f2726b76579158Raphael  return AttrList ? AttrList->Attrs.size() : 0;
190ea66c92f80d9745721cfa28e22f2726b76579158Raphael}
1916508be1224ddec08910c464d2a905c4c2e1f7d80Raphael
1926508be1224ddec08910c464d2a905c4c2e1f7d80Raphael/// getSlot - Return the AttributeWithIndex at the specified slot.  This
1936508be1224ddec08910c464d2a905c4c2e1f7d80Raphael/// holds a number plus a set of attributes.
1946508be1224ddec08910c464d2a905c4c2e1f7d80Raphaelconst AttributeWithIndex &AttrListPtr::getSlot(unsigned Slot) const {
1956508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  assert(AttrList && Slot < AttrList->Attrs.size() && "Slot # out of range!");
196ea66c92f80d9745721cfa28e22f2726b76579158Raphael  return AttrList->Attrs[Slot];
197ea66c92f80d9745721cfa28e22f2726b76579158Raphael}
1986508be1224ddec08910c464d2a905c4c2e1f7d80Raphael
1996508be1224ddec08910c464d2a905c4c2e1f7d80Raphael
2006508be1224ddec08910c464d2a905c4c2e1f7d80Raphael/// getAttributes - The attributes for the specified index are
2016508be1224ddec08910c464d2a905c4c2e1f7d80Raphael/// returned.  Attributes for the result are denoted with Idx = 0.
2026508be1224ddec08910c464d2a905c4c2e1f7d80Raphael/// Function notes are denoted with idx = ~0.
2036508be1224ddec08910c464d2a905c4c2e1f7d80RaphaelAttributes AttrListPtr::getAttributes(unsigned Idx) const {
2046508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  if (AttrList == 0) return Attribute::None;
2056508be1224ddec08910c464d2a905c4c2e1f7d80Raphael
2066508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  const SmallVector<AttributeWithIndex, 4> &Attrs = AttrList->Attrs;
2076508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  for (unsigned i = 0, e = Attrs.size(); i != e && Attrs[i].Index <= Idx; ++i)
208ea66c92f80d9745721cfa28e22f2726b76579158Raphael    if (Attrs[i].Index == Idx)
209ea66c92f80d9745721cfa28e22f2726b76579158Raphael      return Attrs[i].Attrs;
210ea66c92f80d9745721cfa28e22f2726b76579158Raphael  return Attribute::None;
211ea66c92f80d9745721cfa28e22f2726b76579158Raphael}
212ea66c92f80d9745721cfa28e22f2726b76579158Raphael
213ea66c92f80d9745721cfa28e22f2726b76579158Raphael/// hasAttrSomewhere - Return true if the specified attribute is set for at
214ea66c92f80d9745721cfa28e22f2726b76579158Raphael/// least one parameter or for the return value.
215ea66c92f80d9745721cfa28e22f2726b76579158Raphaelbool AttrListPtr::hasAttrSomewhere(Attributes Attr) const {
216ea66c92f80d9745721cfa28e22f2726b76579158Raphael  if (AttrList == 0) return false;
217ea66c92f80d9745721cfa28e22f2726b76579158Raphael
218ea66c92f80d9745721cfa28e22f2726b76579158Raphael  const SmallVector<AttributeWithIndex, 4> &Attrs = AttrList->Attrs;
219ea66c92f80d9745721cfa28e22f2726b76579158Raphael  for (unsigned i = 0, e = Attrs.size(); i != e; ++i)
220ea66c92f80d9745721cfa28e22f2726b76579158Raphael    if (Attrs[i].Attrs & Attr)
221ea66c92f80d9745721cfa28e22f2726b76579158Raphael      return true;
222ea66c92f80d9745721cfa28e22f2726b76579158Raphael  return false;
2236508be1224ddec08910c464d2a905c4c2e1f7d80Raphael}
224ea66c92f80d9745721cfa28e22f2726b76579158Raphael
225ea66c92f80d9745721cfa28e22f2726b76579158Raphael
2266508be1224ddec08910c464d2a905c4c2e1f7d80RaphaelAttrListPtr AttrListPtr::addAttr(unsigned Idx, Attributes Attrs) const {
2276508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  Attributes OldAttrs = getAttributes(Idx);
228ea66c92f80d9745721cfa28e22f2726b76579158Raphael#ifndef NDEBUG
2296508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  // FIXME it is not obvious how this should work for alignment.
2306508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  // For now, say we can't change a known alignment.
2316508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  Attributes OldAlign = OldAttrs & Attribute::Alignment;
2326508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  Attributes NewAlign = Attrs & Attribute::Alignment;
2336508be1224ddec08910c464d2a905c4c2e1f7d80Raphael  assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
2346508be1224ddec08910c464d2a905c4c2e1f7d80Raphael         "Attempt to change alignment!");
2356508be1224ddec08910c464d2a905c4c2e1f7d80Raphael#endif
236
237  Attributes NewAttrs = OldAttrs | Attrs;
238  if (NewAttrs == OldAttrs)
239    return *this;
240
241  SmallVector<AttributeWithIndex, 8> NewAttrList;
242  if (AttrList == 0)
243    NewAttrList.push_back(AttributeWithIndex::get(Idx, Attrs));
244  else {
245    const SmallVector<AttributeWithIndex, 4> &OldAttrList = AttrList->Attrs;
246    unsigned i = 0, e = OldAttrList.size();
247    // Copy attributes for arguments before this one.
248    for (; i != e && OldAttrList[i].Index < Idx; ++i)
249      NewAttrList.push_back(OldAttrList[i]);
250
251    // If there are attributes already at this index, merge them in.
252    if (i != e && OldAttrList[i].Index == Idx) {
253      Attrs |= OldAttrList[i].Attrs;
254      ++i;
255    }
256
257    NewAttrList.push_back(AttributeWithIndex::get(Idx, Attrs));
258
259    // Copy attributes for arguments after this one.
260    NewAttrList.insert(NewAttrList.end(),
261                       OldAttrList.begin()+i, OldAttrList.end());
262  }
263
264  return get(&NewAttrList[0], NewAttrList.size());
265}
266
267AttrListPtr AttrListPtr::removeAttr(unsigned Idx, Attributes Attrs) const {
268#ifndef NDEBUG
269  // FIXME it is not obvious how this should work for alignment.
270  // For now, say we can't pass in alignment, which no current use does.
271  assert(!(Attrs & Attribute::Alignment) && "Attempt to exclude alignment!");
272#endif
273  if (AttrList == 0) return AttrListPtr();
274
275  Attributes OldAttrs = getAttributes(Idx);
276  Attributes NewAttrs = OldAttrs & ~Attrs;
277  if (NewAttrs == OldAttrs)
278    return *this;
279
280  SmallVector<AttributeWithIndex, 8> NewAttrList;
281  const SmallVector<AttributeWithIndex, 4> &OldAttrList = AttrList->Attrs;
282  unsigned i = 0, e = OldAttrList.size();
283
284  // Copy attributes for arguments before this one.
285  for (; i != e && OldAttrList[i].Index < Idx; ++i)
286    NewAttrList.push_back(OldAttrList[i]);
287
288  // If there are attributes already at this index, merge them in.
289  assert(OldAttrList[i].Index == Idx && "Attribute isn't set?");
290  Attrs = OldAttrList[i].Attrs & ~Attrs;
291  ++i;
292  if (Attrs)  // If any attributes left for this parameter, add them.
293    NewAttrList.push_back(AttributeWithIndex::get(Idx, Attrs));
294
295  // Copy attributes for arguments after this one.
296  NewAttrList.insert(NewAttrList.end(),
297                     OldAttrList.begin()+i, OldAttrList.end());
298
299  return get(&NewAttrList[0], NewAttrList.size());
300}
301
302void AttrListPtr::dump() const {
303  cerr << "PAL[ ";
304  for (unsigned i = 0; i < getNumSlots(); ++i) {
305    const AttributeWithIndex &PAWI = getSlot(i);
306    cerr << "{" << PAWI.Index << "," << PAWI.Attrs << "} ";
307  }
308
309  cerr << "]\n";
310}
311