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