Attributes.cpp revision 6f78fbbc630d2b86fb752574f5ad74473f57dfb1
1//===-- Attribute.cpp - Implement AttributesList -------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the Attribute, AttributeImpl, AttrBuilder, 11// AttributeSetImpl, and AttributeSet classes. 12// 13//===----------------------------------------------------------------------===// 14 15#include "llvm/IR/Attributes.h" 16#include "AttributeImpl.h" 17#include "LLVMContextImpl.h" 18#include "llvm/ADT/FoldingSet.h" 19#include "llvm/ADT/StringExtras.h" 20#include "llvm/IR/Type.h" 21#include "llvm/Support/Atomic.h" 22#include "llvm/Support/Debug.h" 23#include "llvm/Support/ManagedStatic.h" 24#include "llvm/Support/Mutex.h" 25#include "llvm/Support/raw_ostream.h" 26using namespace llvm; 27 28//===----------------------------------------------------------------------===// 29// Attribute Implementation 30//===----------------------------------------------------------------------===// 31 32Attribute Attribute::get(LLVMContext &Context, ArrayRef<AttrKind> Vals) { 33 AttrBuilder B; 34 for (ArrayRef<AttrKind>::iterator I = Vals.begin(), E = Vals.end(); 35 I != E; ++I) 36 B.addAttribute(*I); 37 return Attribute::get(Context, B); 38} 39 40Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) { 41 // If there are no attributes, return an empty Attribute class. 42 if (!B.hasAttributes()) 43 return Attribute(); 44 45 // Otherwise, build a key to look up the existing attributes. 46 LLVMContextImpl *pImpl = Context.pImpl; 47 FoldingSetNodeID ID; 48 ID.AddInteger(B.getBitMask()); 49 50 void *InsertPoint; 51 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); 52 53 if (!PA) { 54 // If we didn't find any existing attributes of the same shape then create a 55 // new one and insert it. 56 PA = new AttributeImpl(Context, B.getBitMask()); 57 pImpl->AttrsSet.InsertNode(PA, InsertPoint); 58 } 59 60 // Return the AttributesList that we found or created. 61 return Attribute(PA); 62} 63 64bool Attribute::hasAttribute(AttrKind Val) const { 65 return pImpl && pImpl->hasAttribute(Val); 66} 67 68bool Attribute::hasAttributes() const { 69 return pImpl && pImpl->hasAttributes(); 70} 71 72/// This returns the alignment field of an attribute as a byte alignment value. 73unsigned Attribute::getAlignment() const { 74 if (!hasAttribute(Attribute::Alignment)) 75 return 0; 76 return 1U << ((pImpl->getAlignment() >> 16) - 1); 77} 78 79void Attribute::setAlignment(unsigned Align) { 80 assert(hasAttribute(Attribute::Alignment) && 81 "Trying to set the alignment on a non-alignment attribute!"); 82 pImpl->setAlignment(Align); 83} 84 85/// This returns the stack alignment field of an attribute as a byte alignment 86/// value. 87unsigned Attribute::getStackAlignment() const { 88 if (!hasAttribute(Attribute::StackAlignment)) 89 return 0; 90 return 1U << ((pImpl->getStackAlignment() >> 26) - 1); 91} 92 93void Attribute::setStackAlignment(unsigned Align) { 94 assert(hasAttribute(Attribute::StackAlignment) && 95 "Trying to set the stack alignment on a non-alignment attribute!"); 96 pImpl->setStackAlignment(Align); 97} 98 99bool Attribute::operator==(AttrKind K) const { 100 return pImpl && *pImpl == K; 101} 102bool Attribute::operator!=(AttrKind K) const { 103 return !(*this == K); 104} 105 106uint64_t Attribute::getBitMask() const { 107 return pImpl ? pImpl->getBitMask() : 0; 108} 109 110Attribute Attribute::typeIncompatible(Type *Ty) { 111 AttrBuilder Incompatible; 112 113 if (!Ty->isIntegerTy()) 114 // Attribute that only apply to integers. 115 Incompatible.addAttribute(Attribute::SExt) 116 .addAttribute(Attribute::ZExt); 117 118 if (!Ty->isPointerTy()) 119 // Attribute that only apply to pointers. 120 Incompatible.addAttribute(Attribute::ByVal) 121 .addAttribute(Attribute::Nest) 122 .addAttribute(Attribute::NoAlias) 123 .addAttribute(Attribute::NoCapture) 124 .addAttribute(Attribute::StructRet); 125 126 return Attribute::get(Ty->getContext(), Incompatible); 127} 128 129/// encodeLLVMAttributesForBitcode - This returns an integer containing an 130/// encoding of all the LLVM attributes found in the given attribute bitset. 131/// Any change to this encoding is a breaking change to bitcode compatibility. 132uint64_t Attribute::encodeLLVMAttributesForBitcode(Attribute Attrs) { 133 // FIXME: It doesn't make sense to store the alignment information as an 134 // expanded out value, we should store it as a log2 value. However, we can't 135 // just change that here without breaking bitcode compatibility. If this ever 136 // becomes a problem in practice, we should introduce new tag numbers in the 137 // bitcode file and have those tags use a more efficiently encoded alignment 138 // field. 139 140 // Store the alignment in the bitcode as a 16-bit raw value instead of a 5-bit 141 // log2 encoded value. Shift the bits above the alignment up by 11 bits. 142 uint64_t EncodedAttrs = Attrs.getBitMask() & 0xffff; 143 if (Attrs.hasAttribute(Attribute::Alignment)) 144 EncodedAttrs |= Attrs.getAlignment() << 16; 145 EncodedAttrs |= (Attrs.getBitMask() & (0xffffULL << 21)) << 11; 146 return EncodedAttrs; 147} 148 149/// decodeLLVMAttributesForBitcode - This returns an attribute bitset containing 150/// the LLVM attributes that have been decoded from the given integer. This 151/// function must stay in sync with 'encodeLLVMAttributesForBitcode'. 152Attribute Attribute::decodeLLVMAttributesForBitcode(LLVMContext &C, 153 uint64_t EncodedAttrs) { 154 // The alignment is stored as a 16-bit raw value from bits 31--16. We shift 155 // the bits above 31 down by 11 bits. 156 unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16; 157 assert((!Alignment || isPowerOf2_32(Alignment)) && 158 "Alignment must be a power of two."); 159 160 AttrBuilder B(EncodedAttrs & 0xffff); 161 if (Alignment) 162 B.addAlignmentAttr(Alignment); 163 B.addRawValue((EncodedAttrs & (0xffffULL << 32)) >> 11); 164 return Attribute::get(C, B); 165} 166 167std::string Attribute::getAsString() const { 168 std::string Result; 169 if (hasAttribute(Attribute::ZExt)) 170 Result += "zeroext "; 171 if (hasAttribute(Attribute::SExt)) 172 Result += "signext "; 173 if (hasAttribute(Attribute::NoReturn)) 174 Result += "noreturn "; 175 if (hasAttribute(Attribute::NoUnwind)) 176 Result += "nounwind "; 177 if (hasAttribute(Attribute::UWTable)) 178 Result += "uwtable "; 179 if (hasAttribute(Attribute::ReturnsTwice)) 180 Result += "returns_twice "; 181 if (hasAttribute(Attribute::InReg)) 182 Result += "inreg "; 183 if (hasAttribute(Attribute::NoAlias)) 184 Result += "noalias "; 185 if (hasAttribute(Attribute::NoCapture)) 186 Result += "nocapture "; 187 if (hasAttribute(Attribute::StructRet)) 188 Result += "sret "; 189 if (hasAttribute(Attribute::ByVal)) 190 Result += "byval "; 191 if (hasAttribute(Attribute::Nest)) 192 Result += "nest "; 193 if (hasAttribute(Attribute::ReadNone)) 194 Result += "readnone "; 195 if (hasAttribute(Attribute::ReadOnly)) 196 Result += "readonly "; 197 if (hasAttribute(Attribute::OptimizeForSize)) 198 Result += "optsize "; 199 if (hasAttribute(Attribute::NoInline)) 200 Result += "noinline "; 201 if (hasAttribute(Attribute::InlineHint)) 202 Result += "inlinehint "; 203 if (hasAttribute(Attribute::AlwaysInline)) 204 Result += "alwaysinline "; 205 if (hasAttribute(Attribute::StackProtect)) 206 Result += "ssp "; 207 if (hasAttribute(Attribute::StackProtectReq)) 208 Result += "sspreq "; 209 if (hasAttribute(Attribute::NoRedZone)) 210 Result += "noredzone "; 211 if (hasAttribute(Attribute::NoImplicitFloat)) 212 Result += "noimplicitfloat "; 213 if (hasAttribute(Attribute::Naked)) 214 Result += "naked "; 215 if (hasAttribute(Attribute::NonLazyBind)) 216 Result += "nonlazybind "; 217 if (hasAttribute(Attribute::AddressSafety)) 218 Result += "address_safety "; 219 if (hasAttribute(Attribute::MinSize)) 220 Result += "minsize "; 221 if (hasAttribute(Attribute::StackAlignment)) { 222 Result += "alignstack("; 223 Result += utostr(getStackAlignment()); 224 Result += ") "; 225 } 226 if (hasAttribute(Attribute::Alignment)) { 227 Result += "align "; 228 Result += utostr(getAlignment()); 229 Result += " "; 230 } 231 if (hasAttribute(Attribute::NoDuplicate)) 232 Result += "noduplicate "; 233 // Trim the trailing space. 234 assert(!Result.empty() && "Unknown attribute!"); 235 Result.erase(Result.end()-1); 236 return Result; 237} 238 239//===----------------------------------------------------------------------===// 240// AttrBuilder Method Implementations 241//===----------------------------------------------------------------------===// 242 243void AttrBuilder::clear() { 244 Attrs.clear(); 245 Alignment = StackAlignment = 0; 246} 247 248AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { 249 Attrs.insert(Val); 250 return *this; 251} 252 253AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { 254 Attrs.erase(Val); 255 if (Val == Attribute::Alignment) 256 Alignment = 0; 257 else if (Val == Attribute::StackAlignment) 258 StackAlignment = 0; 259 260 return *this; 261} 262 263AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) { 264 if (Align == 0) return *this; 265 266 assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); 267 assert(Align <= 0x40000000 && "Alignment too large."); 268 269 Attrs.insert(Attribute::Alignment); 270 Alignment = Align; 271 return *this; 272} 273 274AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) { 275 // Default alignment, allow the target to define how to align it. 276 if (Align == 0) return *this; 277 278 assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); 279 assert(Align <= 0x100 && "Alignment too large."); 280 281 Attrs.insert(Attribute::StackAlignment); 282 StackAlignment = Align; 283 return *this; 284} 285 286AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { 287 for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; 288 I = Attribute::AttrKind(I + 1)) { 289 if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) { 290 Attrs.insert(I); 291 292 if (I == Attribute::Alignment) 293 Alignment = 1ULL << ((A >> 16) - 1); 294 else if (I == Attribute::StackAlignment) 295 StackAlignment = 1ULL << ((A >> 26)-1); 296 } 297 } 298 299 return *this; 300} 301 302AttrBuilder &AttrBuilder::addAttributes(const Attribute &A) { 303 uint64_t Mask = A.getBitMask(); 304 305 for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; 306 I = Attribute::AttrKind(I + 1)) { 307 if (uint64_t A = (Mask & AttributeImpl::getAttrMask(I))) { 308 Attrs.insert(I); 309 310 if (I == Attribute::Alignment) 311 Alignment = 1ULL << ((A >> 16) - 1); 312 else if (I == Attribute::StackAlignment) 313 StackAlignment = 1ULL << ((A >> 26)-1); 314 } 315 } 316 317 return *this; 318} 319 320AttrBuilder &AttrBuilder::removeAttributes(const Attribute &A){ 321 uint64_t Mask = A.getBitMask(); 322 323 for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; 324 I = Attribute::AttrKind(I + 1)) { 325 if (Mask & AttributeImpl::getAttrMask(I)) { 326 Attrs.erase(I); 327 328 if (I == Attribute::Alignment) 329 Alignment = 0; 330 else if (I == Attribute::StackAlignment) 331 StackAlignment = 0; 332 } 333 } 334 335 return *this; 336} 337 338bool AttrBuilder::contains(Attribute::AttrKind A) const { 339 return Attrs.count(A); 340} 341 342bool AttrBuilder::hasAttributes() const { 343 return !Attrs.empty(); 344} 345 346bool AttrBuilder::hasAttributes(const Attribute &A) const { 347 return getBitMask() & A.getBitMask(); 348} 349 350bool AttrBuilder::hasAlignmentAttr() const { 351 return Alignment != 0; 352} 353 354uint64_t AttrBuilder::getBitMask() const { 355 uint64_t Mask = 0; 356 357 for (DenseSet<Attribute::AttrKind>::const_iterator I = Attrs.begin(), 358 E = Attrs.end(); I != E; ++I) { 359 Attribute::AttrKind Kind = *I; 360 361 if (Kind == Attribute::Alignment) 362 Mask |= (Log2_32(Alignment) + 1) << 16; 363 else if (Kind == Attribute::StackAlignment) 364 Mask |= (Log2_32(StackAlignment) + 1) << 26; 365 else 366 Mask |= AttributeImpl::getAttrMask(Kind); 367 } 368 369 return Mask; 370} 371 372bool AttrBuilder::operator==(const AttrBuilder &B) { 373 SmallVector<Attribute::AttrKind, 8> This(Attrs.begin(), Attrs.end()); 374 SmallVector<Attribute::AttrKind, 8> That(B.Attrs.begin(), B.Attrs.end()); 375 return This == That; 376} 377 378//===----------------------------------------------------------------------===// 379// AttributeImpl Definition 380//===----------------------------------------------------------------------===// 381 382AttributeImpl::AttributeImpl(LLVMContext &C, uint64_t data) 383 : Context(C) { 384 Data = ConstantInt::get(Type::getInt64Ty(C), data); 385} 386AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data) 387 : Context(C) { 388 Data = ConstantInt::get(Type::getInt64Ty(C), data); 389} 390AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data, 391 ArrayRef<Constant*> values) 392 : Context(C) { 393 Data = ConstantInt::get(Type::getInt64Ty(C), data); 394 Vals.reserve(values.size()); 395 Vals.append(values.begin(), values.end()); 396} 397AttributeImpl::AttributeImpl(LLVMContext &C, StringRef data) 398 : Context(C) { 399 Data = ConstantDataArray::getString(C, data); 400} 401 402bool AttributeImpl::operator==(Attribute::AttrKind Kind) const { 403 if (ConstantInt *CI = dyn_cast<ConstantInt>(Data)) 404 return CI->getZExtValue() == Kind; 405 return false; 406} 407bool AttributeImpl::operator!=(Attribute::AttrKind Kind) const { 408 return !(*this == Kind); 409} 410 411bool AttributeImpl::operator==(StringRef Kind) const { 412 if (ConstantDataArray *CDA = dyn_cast<ConstantDataArray>(Data)) 413 if (CDA->isString()) 414 return CDA->getAsString() == Kind; 415 return false; 416} 417bool AttributeImpl::operator!=(StringRef Kind) const { 418 return !(*this == Kind); 419} 420 421uint64_t AttributeImpl::getBitMask() const { 422 // FIXME: Remove this. 423 return cast<ConstantInt>(Data)->getZExtValue(); 424} 425 426uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { 427 switch (Val) { 428 case Attribute::EndAttrKinds: 429 case Attribute::AttrKindEmptyKey: 430 case Attribute::AttrKindTombstoneKey: 431 llvm_unreachable("Synthetic enumerators which should never get here"); 432 433 case Attribute::None: return 0; 434 case Attribute::ZExt: return 1 << 0; 435 case Attribute::SExt: return 1 << 1; 436 case Attribute::NoReturn: return 1 << 2; 437 case Attribute::InReg: return 1 << 3; 438 case Attribute::StructRet: return 1 << 4; 439 case Attribute::NoUnwind: return 1 << 5; 440 case Attribute::NoAlias: return 1 << 6; 441 case Attribute::ByVal: return 1 << 7; 442 case Attribute::Nest: return 1 << 8; 443 case Attribute::ReadNone: return 1 << 9; 444 case Attribute::ReadOnly: return 1 << 10; 445 case Attribute::NoInline: return 1 << 11; 446 case Attribute::AlwaysInline: return 1 << 12; 447 case Attribute::OptimizeForSize: return 1 << 13; 448 case Attribute::StackProtect: return 1 << 14; 449 case Attribute::StackProtectReq: return 1 << 15; 450 case Attribute::Alignment: return 31 << 16; 451 case Attribute::NoCapture: return 1 << 21; 452 case Attribute::NoRedZone: return 1 << 22; 453 case Attribute::NoImplicitFloat: return 1 << 23; 454 case Attribute::Naked: return 1 << 24; 455 case Attribute::InlineHint: return 1 << 25; 456 case Attribute::StackAlignment: return 7 << 26; 457 case Attribute::ReturnsTwice: return 1 << 29; 458 case Attribute::UWTable: return 1 << 30; 459 case Attribute::NonLazyBind: return 1U << 31; 460 case Attribute::AddressSafety: return 1ULL << 32; 461 case Attribute::MinSize: return 1ULL << 33; 462 case Attribute::NoDuplicate: return 1ULL << 34; 463 } 464 llvm_unreachable("Unsupported attribute type"); 465} 466 467bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { 468 return (getBitMask() & getAttrMask(A)) != 0; 469} 470 471bool AttributeImpl::hasAttributes() const { 472 return getBitMask() != 0; 473} 474 475uint64_t AttributeImpl::getAlignment() const { 476 return getBitMask() & getAttrMask(Attribute::Alignment); 477} 478 479void AttributeImpl::setAlignment(unsigned Align) { 480 Vals.push_back(ConstantInt::get(Type::getInt64Ty(Context), Align)); 481} 482 483uint64_t AttributeImpl::getStackAlignment() const { 484 return getBitMask() & getAttrMask(Attribute::StackAlignment); 485} 486 487void AttributeImpl::setStackAlignment(unsigned Align) { 488 Vals.push_back(ConstantInt::get(Type::getInt64Ty(Context), Align)); 489} 490 491//===----------------------------------------------------------------------===// 492// AttributeSetImpl Definition 493//===----------------------------------------------------------------------===// 494 495AttributeSet AttributeSet::get(LLVMContext &C, 496 ArrayRef<AttributeWithIndex> Attrs) { 497 // If there are no attributes then return a null AttributesList pointer. 498 if (Attrs.empty()) 499 return AttributeSet(); 500 501#ifndef NDEBUG 502 for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { 503 assert(Attrs[i].Attrs.hasAttributes() && 504 "Pointless attribute!"); 505 assert((!i || Attrs[i-1].Index < Attrs[i].Index) && 506 "Misordered AttributesList!"); 507 } 508#endif 509 510 // Otherwise, build a key to look up the existing attributes. 511 LLVMContextImpl *pImpl = C.pImpl; 512 FoldingSetNodeID ID; 513 AttributeSetImpl::Profile(ID, Attrs); 514 515 void *InsertPoint; 516 AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint); 517 518 // If we didn't find any existing attributes of the same shape then 519 // create a new one and insert it. 520 if (!PA) { 521 PA = new AttributeSetImpl(C, Attrs); 522 pImpl->AttrsLists.InsertNode(PA, InsertPoint); 523 } 524 525 // Return the AttributesList that we found or created. 526 return AttributeSet(PA); 527} 528 529AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, AttrBuilder &B) { 530 SmallVector<AttributeWithIndex, 8> Attrs; 531 for (AttrBuilder::iterator I = B.begin(), E = B.end(); I != E; ++I) { 532 Attribute::AttrKind Kind = *I; 533 Attribute A = Attribute::get(C, Kind); 534 535 if (Kind == Attribute::Alignment) 536 A.setAlignment(B.getAlignment()); 537 else if (Kind == Attribute::StackAlignment) 538 A.setStackAlignment(B.getStackAlignment()); 539 540 Attrs.push_back(AttributeWithIndex::get(Idx, A)); 541 } 542 543 return get(C, Attrs); 544} 545 546//===----------------------------------------------------------------------===// 547// AttributeSet Method Implementations 548//===----------------------------------------------------------------------===// 549 550const AttributeSet &AttributeSet::operator=(const AttributeSet &RHS) { 551 AttrList = RHS.AttrList; 552 return *this; 553} 554 555/// getNumSlots - Return the number of slots used in this attribute list. 556/// This is the number of arguments that have an attribute set on them 557/// (including the function itself). 558unsigned AttributeSet::getNumSlots() const { 559 return AttrList ? AttrList->getNumAttributes() : 0; 560} 561 562/// getSlot - Return the AttributeWithIndex at the specified slot. This 563/// holds a number plus a set of attributes. 564const AttributeWithIndex &AttributeSet::getSlot(unsigned Slot) const { 565 assert(AttrList && Slot < AttrList->getNumAttributes() && 566 "Slot # out of range!"); 567 return AttrList->getAttributes()[Slot]; 568} 569 570bool AttributeSet::hasAttribute(unsigned Index, Attribute::AttrKind Kind) const{ 571 return getAttributes(Index).hasAttribute(Kind); 572} 573 574bool AttributeSet::hasAttributes(unsigned Index) const { 575 return getAttributes(Index).hasAttributes(); 576} 577 578std::string AttributeSet::getAsString(unsigned Index) const { 579 return getAttributes(Index).getAsString(); 580} 581 582unsigned AttributeSet::getStackAlignment(unsigned Index) const { 583 return getAttributes(Index).getStackAlignment(); 584} 585 586uint64_t AttributeSet::getBitMask(unsigned Index) const { 587 // FIXME: Remove this. 588 return getAttributes(Index).getBitMask(); 589} 590 591/// getAttributes - The attributes for the specified index are returned. 592/// Attributes for the result are denoted with Idx = 0. Function attributes are 593/// denoted with Idx = ~0. 594Attribute AttributeSet::getAttributes(unsigned Idx) const { 595 if (AttrList == 0) return Attribute(); 596 597 ArrayRef<AttributeWithIndex> Attrs = AttrList->getAttributes(); 598 for (unsigned i = 0, e = Attrs.size(); i != e && Attrs[i].Index <= Idx; ++i) 599 if (Attrs[i].Index == Idx) 600 return Attrs[i].Attrs; 601 602 return Attribute(); 603} 604 605/// hasAttrSomewhere - Return true if the specified attribute is set for at 606/// least one parameter or for the return value. 607bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr) const { 608 if (AttrList == 0) return false; 609 610 ArrayRef<AttributeWithIndex> Attrs = AttrList->getAttributes(); 611 for (unsigned i = 0, e = Attrs.size(); i != e; ++i) 612 if (Attrs[i].Attrs.hasAttribute(Attr)) 613 return true; 614 615 return false; 616} 617 618AttributeSet AttributeSet::addAttr(LLVMContext &C, unsigned Idx, 619 Attribute Attrs) const { 620 Attribute OldAttrs = getAttributes(Idx); 621#ifndef NDEBUG 622 // FIXME it is not obvious how this should work for alignment. 623 // For now, say we can't change a known alignment. 624 unsigned OldAlign = OldAttrs.getAlignment(); 625 unsigned NewAlign = Attrs.getAlignment(); 626 assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && 627 "Attempt to change alignment!"); 628#endif 629 630 AttrBuilder NewAttrs = 631 AttrBuilder(OldAttrs).addAttributes(Attrs); 632 if (NewAttrs == AttrBuilder(OldAttrs)) 633 return *this; 634 635 SmallVector<AttributeWithIndex, 8> NewAttrList; 636 if (AttrList == 0) 637 NewAttrList.push_back(AttributeWithIndex::get(Idx, Attrs)); 638 else { 639 ArrayRef<AttributeWithIndex> OldAttrList = AttrList->getAttributes(); 640 unsigned i = 0, e = OldAttrList.size(); 641 // Copy attributes for arguments before this one. 642 for (; i != e && OldAttrList[i].Index < Idx; ++i) 643 NewAttrList.push_back(OldAttrList[i]); 644 645 // If there are attributes already at this index, merge them in. 646 if (i != e && OldAttrList[i].Index == Idx) { 647 Attrs = 648 Attribute::get(C, AttrBuilder(Attrs). 649 addAttributes(OldAttrList[i].Attrs)); 650 ++i; 651 } 652 653 NewAttrList.push_back(AttributeWithIndex::get(Idx, Attrs)); 654 655 // Copy attributes for arguments after this one. 656 NewAttrList.insert(NewAttrList.end(), 657 OldAttrList.begin()+i, OldAttrList.end()); 658 } 659 660 return get(C, NewAttrList); 661} 662 663AttributeSet AttributeSet::removeAttr(LLVMContext &C, unsigned Idx, 664 Attribute Attrs) const { 665#ifndef NDEBUG 666 // FIXME it is not obvious how this should work for alignment. 667 // For now, say we can't pass in alignment, which no current use does. 668 assert(!Attrs.hasAttribute(Attribute::Alignment) && 669 "Attempt to exclude alignment!"); 670#endif 671 if (AttrList == 0) return AttributeSet(); 672 673 Attribute OldAttrs = getAttributes(Idx); 674 AttrBuilder NewAttrs = 675 AttrBuilder(OldAttrs).removeAttributes(Attrs); 676 if (NewAttrs == AttrBuilder(OldAttrs)) 677 return *this; 678 679 SmallVector<AttributeWithIndex, 8> NewAttrList; 680 ArrayRef<AttributeWithIndex> OldAttrList = AttrList->getAttributes(); 681 unsigned i = 0, e = OldAttrList.size(); 682 683 // Copy attributes for arguments before this one. 684 for (; i != e && OldAttrList[i].Index < Idx; ++i) 685 NewAttrList.push_back(OldAttrList[i]); 686 687 // If there are attributes already at this index, merge them in. 688 assert(OldAttrList[i].Index == Idx && "Attribute isn't set?"); 689 Attrs = Attribute::get(C, AttrBuilder(OldAttrList[i].Attrs). 690 removeAttributes(Attrs)); 691 ++i; 692 if (Attrs.hasAttributes()) // If any attributes left for this param, add them. 693 NewAttrList.push_back(AttributeWithIndex::get(Idx, Attrs)); 694 695 // Copy attributes for arguments after this one. 696 NewAttrList.insert(NewAttrList.end(), 697 OldAttrList.begin()+i, OldAttrList.end()); 698 699 return get(C, NewAttrList); 700} 701 702void AttributeSet::dump() const { 703 dbgs() << "PAL[ "; 704 for (unsigned i = 0; i < getNumSlots(); ++i) { 705 const AttributeWithIndex &PAWI = getSlot(i); 706 dbgs() << "{ " << PAWI.Index << ", " << PAWI.Attrs.getAsString() << " } "; 707 } 708 709 dbgs() << "]\n"; 710} 711