LLVM API Documentation
00001 //===-- Attributes.cpp - Implement AttributesList -------------------------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // \file 00011 // \brief This file implements the Attribute, AttributeImpl, AttrBuilder, 00012 // AttributeSetImpl, and AttributeSet classes. 00013 // 00014 //===----------------------------------------------------------------------===// 00015 00016 #include "llvm/IR/Attributes.h" 00017 #include "AttributeImpl.h" 00018 #include "LLVMContextImpl.h" 00019 #include "llvm/ADT/STLExtras.h" 00020 #include "llvm/ADT/StringExtras.h" 00021 #include "llvm/IR/Type.h" 00022 #include "llvm/Support/Atomic.h" 00023 #include "llvm/Support/Debug.h" 00024 #include "llvm/Support/ManagedStatic.h" 00025 #include "llvm/Support/Mutex.h" 00026 #include "llvm/Support/raw_ostream.h" 00027 #include <algorithm> 00028 using namespace llvm; 00029 00030 //===----------------------------------------------------------------------===// 00031 // Attribute Construction Methods 00032 //===----------------------------------------------------------------------===// 00033 00034 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind, 00035 uint64_t Val) { 00036 LLVMContextImpl *pImpl = Context.pImpl; 00037 FoldingSetNodeID ID; 00038 ID.AddInteger(Kind); 00039 if (Val) ID.AddInteger(Val); 00040 00041 void *InsertPoint; 00042 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); 00043 00044 if (!PA) { 00045 // If we didn't find any existing attributes of the same shape then create a 00046 // new one and insert it. 00047 if (!Val) 00048 PA = new EnumAttributeImpl(Kind); 00049 else 00050 PA = new IntAttributeImpl(Kind, Val); 00051 pImpl->AttrsSet.InsertNode(PA, InsertPoint); 00052 } 00053 00054 // Return the Attribute that we found or created. 00055 return Attribute(PA); 00056 } 00057 00058 Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) { 00059 LLVMContextImpl *pImpl = Context.pImpl; 00060 FoldingSetNodeID ID; 00061 ID.AddString(Kind); 00062 if (!Val.empty()) ID.AddString(Val); 00063 00064 void *InsertPoint; 00065 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); 00066 00067 if (!PA) { 00068 // If we didn't find any existing attributes of the same shape then create a 00069 // new one and insert it. 00070 PA = new StringAttributeImpl(Kind, Val); 00071 pImpl->AttrsSet.InsertNode(PA, InsertPoint); 00072 } 00073 00074 // Return the Attribute that we found or created. 00075 return Attribute(PA); 00076 } 00077 00078 Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) { 00079 assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); 00080 assert(Align <= 0x40000000 && "Alignment too large."); 00081 return get(Context, Alignment, Align); 00082 } 00083 00084 Attribute Attribute::getWithStackAlignment(LLVMContext &Context, 00085 uint64_t Align) { 00086 assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); 00087 assert(Align <= 0x100 && "Alignment too large."); 00088 return get(Context, StackAlignment, Align); 00089 } 00090 00091 Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context, 00092 uint64_t Bytes) { 00093 assert(Bytes && "Bytes must be non-zero."); 00094 return get(Context, Dereferenceable, Bytes); 00095 } 00096 00097 //===----------------------------------------------------------------------===// 00098 // Attribute Accessor Methods 00099 //===----------------------------------------------------------------------===// 00100 00101 bool Attribute::isEnumAttribute() const { 00102 return pImpl && pImpl->isEnumAttribute(); 00103 } 00104 00105 bool Attribute::isIntAttribute() const { 00106 return pImpl && pImpl->isIntAttribute(); 00107 } 00108 00109 bool Attribute::isStringAttribute() const { 00110 return pImpl && pImpl->isStringAttribute(); 00111 } 00112 00113 Attribute::AttrKind Attribute::getKindAsEnum() const { 00114 if (!pImpl) return None; 00115 assert((isEnumAttribute() || isIntAttribute()) && 00116 "Invalid attribute type to get the kind as an enum!"); 00117 return pImpl ? pImpl->getKindAsEnum() : None; 00118 } 00119 00120 uint64_t Attribute::getValueAsInt() const { 00121 if (!pImpl) return 0; 00122 assert(isIntAttribute() && 00123 "Expected the attribute to be an integer attribute!"); 00124 return pImpl ? pImpl->getValueAsInt() : 0; 00125 } 00126 00127 StringRef Attribute::getKindAsString() const { 00128 if (!pImpl) return StringRef(); 00129 assert(isStringAttribute() && 00130 "Invalid attribute type to get the kind as a string!"); 00131 return pImpl ? pImpl->getKindAsString() : StringRef(); 00132 } 00133 00134 StringRef Attribute::getValueAsString() const { 00135 if (!pImpl) return StringRef(); 00136 assert(isStringAttribute() && 00137 "Invalid attribute type to get the value as a string!"); 00138 return pImpl ? pImpl->getValueAsString() : StringRef(); 00139 } 00140 00141 bool Attribute::hasAttribute(AttrKind Kind) const { 00142 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None); 00143 } 00144 00145 bool Attribute::hasAttribute(StringRef Kind) const { 00146 if (!isStringAttribute()) return false; 00147 return pImpl && pImpl->hasAttribute(Kind); 00148 } 00149 00150 /// This returns the alignment field of an attribute as a byte alignment value. 00151 unsigned Attribute::getAlignment() const { 00152 assert(hasAttribute(Attribute::Alignment) && 00153 "Trying to get alignment from non-alignment attribute!"); 00154 return pImpl->getValueAsInt(); 00155 } 00156 00157 /// This returns the stack alignment field of an attribute as a byte alignment 00158 /// value. 00159 unsigned Attribute::getStackAlignment() const { 00160 assert(hasAttribute(Attribute::StackAlignment) && 00161 "Trying to get alignment from non-alignment attribute!"); 00162 return pImpl->getValueAsInt(); 00163 } 00164 00165 /// This returns the number of dereferenceable bytes. 00166 uint64_t Attribute::getDereferenceableBytes() const { 00167 assert(hasAttribute(Attribute::Dereferenceable) && 00168 "Trying to get dereferenceable bytes from " 00169 "non-dereferenceable attribute!"); 00170 return pImpl->getValueAsInt(); 00171 } 00172 00173 std::string Attribute::getAsString(bool InAttrGrp) const { 00174 if (!pImpl) return ""; 00175 00176 if (hasAttribute(Attribute::SanitizeAddress)) 00177 return "sanitize_address"; 00178 if (hasAttribute(Attribute::AlwaysInline)) 00179 return "alwaysinline"; 00180 if (hasAttribute(Attribute::Builtin)) 00181 return "builtin"; 00182 if (hasAttribute(Attribute::ByVal)) 00183 return "byval"; 00184 if (hasAttribute(Attribute::InAlloca)) 00185 return "inalloca"; 00186 if (hasAttribute(Attribute::InlineHint)) 00187 return "inlinehint"; 00188 if (hasAttribute(Attribute::InReg)) 00189 return "inreg"; 00190 if (hasAttribute(Attribute::JumpTable)) 00191 return "jumptable"; 00192 if (hasAttribute(Attribute::MinSize)) 00193 return "minsize"; 00194 if (hasAttribute(Attribute::Naked)) 00195 return "naked"; 00196 if (hasAttribute(Attribute::Nest)) 00197 return "nest"; 00198 if (hasAttribute(Attribute::NoAlias)) 00199 return "noalias"; 00200 if (hasAttribute(Attribute::NoBuiltin)) 00201 return "nobuiltin"; 00202 if (hasAttribute(Attribute::NoCapture)) 00203 return "nocapture"; 00204 if (hasAttribute(Attribute::NoDuplicate)) 00205 return "noduplicate"; 00206 if (hasAttribute(Attribute::NoImplicitFloat)) 00207 return "noimplicitfloat"; 00208 if (hasAttribute(Attribute::NoInline)) 00209 return "noinline"; 00210 if (hasAttribute(Attribute::NonLazyBind)) 00211 return "nonlazybind"; 00212 if (hasAttribute(Attribute::NonNull)) 00213 return "nonnull"; 00214 if (hasAttribute(Attribute::NoRedZone)) 00215 return "noredzone"; 00216 if (hasAttribute(Attribute::NoReturn)) 00217 return "noreturn"; 00218 if (hasAttribute(Attribute::NoUnwind)) 00219 return "nounwind"; 00220 if (hasAttribute(Attribute::OptimizeNone)) 00221 return "optnone"; 00222 if (hasAttribute(Attribute::OptimizeForSize)) 00223 return "optsize"; 00224 if (hasAttribute(Attribute::ReadNone)) 00225 return "readnone"; 00226 if (hasAttribute(Attribute::ReadOnly)) 00227 return "readonly"; 00228 if (hasAttribute(Attribute::Returned)) 00229 return "returned"; 00230 if (hasAttribute(Attribute::ReturnsTwice)) 00231 return "returns_twice"; 00232 if (hasAttribute(Attribute::SExt)) 00233 return "signext"; 00234 if (hasAttribute(Attribute::StackProtect)) 00235 return "ssp"; 00236 if (hasAttribute(Attribute::StackProtectReq)) 00237 return "sspreq"; 00238 if (hasAttribute(Attribute::StackProtectStrong)) 00239 return "sspstrong"; 00240 if (hasAttribute(Attribute::StructRet)) 00241 return "sret"; 00242 if (hasAttribute(Attribute::SanitizeThread)) 00243 return "sanitize_thread"; 00244 if (hasAttribute(Attribute::SanitizeMemory)) 00245 return "sanitize_memory"; 00246 if (hasAttribute(Attribute::UWTable)) 00247 return "uwtable"; 00248 if (hasAttribute(Attribute::ZExt)) 00249 return "zeroext"; 00250 if (hasAttribute(Attribute::Cold)) 00251 return "cold"; 00252 00253 // FIXME: These should be output like this: 00254 // 00255 // align=4 00256 // alignstack=8 00257 // 00258 if (hasAttribute(Attribute::Alignment)) { 00259 std::string Result; 00260 Result += "align"; 00261 Result += (InAttrGrp) ? "=" : " "; 00262 Result += utostr(getValueAsInt()); 00263 return Result; 00264 } 00265 00266 if (hasAttribute(Attribute::StackAlignment)) { 00267 std::string Result; 00268 Result += "alignstack"; 00269 if (InAttrGrp) { 00270 Result += "="; 00271 Result += utostr(getValueAsInt()); 00272 } else { 00273 Result += "("; 00274 Result += utostr(getValueAsInt()); 00275 Result += ")"; 00276 } 00277 return Result; 00278 } 00279 00280 if (hasAttribute(Attribute::Dereferenceable)) { 00281 std::string Result; 00282 Result += "dereferenceable"; 00283 if (InAttrGrp) { 00284 Result += "="; 00285 Result += utostr(getValueAsInt()); 00286 } else { 00287 Result += "("; 00288 Result += utostr(getValueAsInt()); 00289 Result += ")"; 00290 } 00291 return Result; 00292 } 00293 00294 // Convert target-dependent attributes to strings of the form: 00295 // 00296 // "kind" 00297 // "kind" = "value" 00298 // 00299 if (isStringAttribute()) { 00300 std::string Result; 00301 Result += '\"' + getKindAsString().str() + '"'; 00302 00303 StringRef Val = pImpl->getValueAsString(); 00304 if (Val.empty()) return Result; 00305 00306 Result += "=\"" + Val.str() + '"'; 00307 return Result; 00308 } 00309 00310 llvm_unreachable("Unknown attribute"); 00311 } 00312 00313 bool Attribute::operator<(Attribute A) const { 00314 if (!pImpl && !A.pImpl) return false; 00315 if (!pImpl) return true; 00316 if (!A.pImpl) return false; 00317 return *pImpl < *A.pImpl; 00318 } 00319 00320 //===----------------------------------------------------------------------===// 00321 // AttributeImpl Definition 00322 //===----------------------------------------------------------------------===// 00323 00324 // Pin the vtables to this file. 00325 AttributeImpl::~AttributeImpl() {} 00326 void EnumAttributeImpl::anchor() {} 00327 void IntAttributeImpl::anchor() {} 00328 void StringAttributeImpl::anchor() {} 00329 00330 bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { 00331 if (isStringAttribute()) return false; 00332 return getKindAsEnum() == A; 00333 } 00334 00335 bool AttributeImpl::hasAttribute(StringRef Kind) const { 00336 if (!isStringAttribute()) return false; 00337 return getKindAsString() == Kind; 00338 } 00339 00340 Attribute::AttrKind AttributeImpl::getKindAsEnum() const { 00341 assert(isEnumAttribute() || isIntAttribute()); 00342 return static_cast<const EnumAttributeImpl *>(this)->getEnumKind(); 00343 } 00344 00345 uint64_t AttributeImpl::getValueAsInt() const { 00346 assert(isIntAttribute()); 00347 return static_cast<const IntAttributeImpl *>(this)->getValue(); 00348 } 00349 00350 StringRef AttributeImpl::getKindAsString() const { 00351 assert(isStringAttribute()); 00352 return static_cast<const StringAttributeImpl *>(this)->getStringKind(); 00353 } 00354 00355 StringRef AttributeImpl::getValueAsString() const { 00356 assert(isStringAttribute()); 00357 return static_cast<const StringAttributeImpl *>(this)->getStringValue(); 00358 } 00359 00360 bool AttributeImpl::operator<(const AttributeImpl &AI) const { 00361 // This sorts the attributes with Attribute::AttrKinds coming first (sorted 00362 // relative to their enum value) and then strings. 00363 if (isEnumAttribute()) { 00364 if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum(); 00365 if (AI.isIntAttribute()) return true; 00366 if (AI.isStringAttribute()) return true; 00367 } 00368 00369 if (isIntAttribute()) { 00370 if (AI.isEnumAttribute()) return false; 00371 if (AI.isIntAttribute()) return getValueAsInt() < AI.getValueAsInt(); 00372 if (AI.isStringAttribute()) return true; 00373 } 00374 00375 if (AI.isEnumAttribute()) return false; 00376 if (AI.isIntAttribute()) return false; 00377 if (getKindAsString() == AI.getKindAsString()) 00378 return getValueAsString() < AI.getValueAsString(); 00379 return getKindAsString() < AI.getKindAsString(); 00380 } 00381 00382 uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { 00383 // FIXME: Remove this. 00384 switch (Val) { 00385 case Attribute::EndAttrKinds: 00386 llvm_unreachable("Synthetic enumerators which should never get here"); 00387 00388 case Attribute::None: return 0; 00389 case Attribute::ZExt: return 1 << 0; 00390 case Attribute::SExt: return 1 << 1; 00391 case Attribute::NoReturn: return 1 << 2; 00392 case Attribute::InReg: return 1 << 3; 00393 case Attribute::StructRet: return 1 << 4; 00394 case Attribute::NoUnwind: return 1 << 5; 00395 case Attribute::NoAlias: return 1 << 6; 00396 case Attribute::ByVal: return 1 << 7; 00397 case Attribute::Nest: return 1 << 8; 00398 case Attribute::ReadNone: return 1 << 9; 00399 case Attribute::ReadOnly: return 1 << 10; 00400 case Attribute::NoInline: return 1 << 11; 00401 case Attribute::AlwaysInline: return 1 << 12; 00402 case Attribute::OptimizeForSize: return 1 << 13; 00403 case Attribute::StackProtect: return 1 << 14; 00404 case Attribute::StackProtectReq: return 1 << 15; 00405 case Attribute::Alignment: return 31 << 16; 00406 case Attribute::NoCapture: return 1 << 21; 00407 case Attribute::NoRedZone: return 1 << 22; 00408 case Attribute::NoImplicitFloat: return 1 << 23; 00409 case Attribute::Naked: return 1 << 24; 00410 case Attribute::InlineHint: return 1 << 25; 00411 case Attribute::StackAlignment: return 7 << 26; 00412 case Attribute::ReturnsTwice: return 1 << 29; 00413 case Attribute::UWTable: return 1 << 30; 00414 case Attribute::NonLazyBind: return 1U << 31; 00415 case Attribute::SanitizeAddress: return 1ULL << 32; 00416 case Attribute::MinSize: return 1ULL << 33; 00417 case Attribute::NoDuplicate: return 1ULL << 34; 00418 case Attribute::StackProtectStrong: return 1ULL << 35; 00419 case Attribute::SanitizeThread: return 1ULL << 36; 00420 case Attribute::SanitizeMemory: return 1ULL << 37; 00421 case Attribute::NoBuiltin: return 1ULL << 38; 00422 case Attribute::Returned: return 1ULL << 39; 00423 case Attribute::Cold: return 1ULL << 40; 00424 case Attribute::Builtin: return 1ULL << 41; 00425 case Attribute::OptimizeNone: return 1ULL << 42; 00426 case Attribute::InAlloca: return 1ULL << 43; 00427 case Attribute::NonNull: return 1ULL << 44; 00428 case Attribute::JumpTable: return 1ULL << 45; 00429 case Attribute::Dereferenceable: 00430 llvm_unreachable("dereferenceable attribute not supported in raw format"); 00431 } 00432 llvm_unreachable("Unsupported attribute type"); 00433 } 00434 00435 //===----------------------------------------------------------------------===// 00436 // AttributeSetNode Definition 00437 //===----------------------------------------------------------------------===// 00438 00439 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, 00440 ArrayRef<Attribute> Attrs) { 00441 if (Attrs.empty()) 00442 return nullptr; 00443 00444 // Otherwise, build a key to look up the existing attributes. 00445 LLVMContextImpl *pImpl = C.pImpl; 00446 FoldingSetNodeID ID; 00447 00448 SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end()); 00449 array_pod_sort(SortedAttrs.begin(), SortedAttrs.end()); 00450 00451 for (SmallVectorImpl<Attribute>::iterator I = SortedAttrs.begin(), 00452 E = SortedAttrs.end(); I != E; ++I) 00453 I->Profile(ID); 00454 00455 void *InsertPoint; 00456 AttributeSetNode *PA = 00457 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint); 00458 00459 // If we didn't find any existing attributes of the same shape then create a 00460 // new one and insert it. 00461 if (!PA) { 00462 // Coallocate entries after the AttributeSetNode itself. 00463 void *Mem = ::operator new(sizeof(AttributeSetNode) + 00464 sizeof(Attribute) * SortedAttrs.size()); 00465 PA = new (Mem) AttributeSetNode(SortedAttrs); 00466 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint); 00467 } 00468 00469 // Return the AttributesListNode that we found or created. 00470 return PA; 00471 } 00472 00473 bool AttributeSetNode::hasAttribute(Attribute::AttrKind Kind) const { 00474 for (iterator I = begin(), E = end(); I != E; ++I) 00475 if (I->hasAttribute(Kind)) 00476 return true; 00477 return false; 00478 } 00479 00480 bool AttributeSetNode::hasAttribute(StringRef Kind) const { 00481 for (iterator I = begin(), E = end(); I != E; ++I) 00482 if (I->hasAttribute(Kind)) 00483 return true; 00484 return false; 00485 } 00486 00487 Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const { 00488 for (iterator I = begin(), E = end(); I != E; ++I) 00489 if (I->hasAttribute(Kind)) 00490 return *I; 00491 return Attribute(); 00492 } 00493 00494 Attribute AttributeSetNode::getAttribute(StringRef Kind) const { 00495 for (iterator I = begin(), E = end(); I != E; ++I) 00496 if (I->hasAttribute(Kind)) 00497 return *I; 00498 return Attribute(); 00499 } 00500 00501 unsigned AttributeSetNode::getAlignment() const { 00502 for (iterator I = begin(), E = end(); I != E; ++I) 00503 if (I->hasAttribute(Attribute::Alignment)) 00504 return I->getAlignment(); 00505 return 0; 00506 } 00507 00508 unsigned AttributeSetNode::getStackAlignment() const { 00509 for (iterator I = begin(), E = end(); I != E; ++I) 00510 if (I->hasAttribute(Attribute::StackAlignment)) 00511 return I->getStackAlignment(); 00512 return 0; 00513 } 00514 00515 uint64_t AttributeSetNode::getDereferenceableBytes() const { 00516 for (iterator I = begin(), E = end(); I != E; ++I) 00517 if (I->hasAttribute(Attribute::Dereferenceable)) 00518 return I->getDereferenceableBytes(); 00519 return 0; 00520 } 00521 00522 std::string AttributeSetNode::getAsString(bool InAttrGrp) const { 00523 std::string Str; 00524 for (iterator I = begin(), E = end(); I != E; ++I) { 00525 if (I != begin()) 00526 Str += ' '; 00527 Str += I->getAsString(InAttrGrp); 00528 } 00529 return Str; 00530 } 00531 00532 //===----------------------------------------------------------------------===// 00533 // AttributeSetImpl Definition 00534 //===----------------------------------------------------------------------===// 00535 00536 uint64_t AttributeSetImpl::Raw(unsigned Index) const { 00537 for (unsigned I = 0, E = getNumAttributes(); I != E; ++I) { 00538 if (getSlotIndex(I) != Index) continue; 00539 const AttributeSetNode *ASN = getSlotNode(I); 00540 uint64_t Mask = 0; 00541 00542 for (AttributeSetNode::iterator II = ASN->begin(), 00543 IE = ASN->end(); II != IE; ++II) { 00544 Attribute Attr = *II; 00545 00546 // This cannot handle string attributes. 00547 if (Attr.isStringAttribute()) continue; 00548 00549 Attribute::AttrKind Kind = Attr.getKindAsEnum(); 00550 00551 if (Kind == Attribute::Alignment) 00552 Mask |= (Log2_32(ASN->getAlignment()) + 1) << 16; 00553 else if (Kind == Attribute::StackAlignment) 00554 Mask |= (Log2_32(ASN->getStackAlignment()) + 1) << 26; 00555 else if (Kind == Attribute::Dereferenceable) 00556 llvm_unreachable("dereferenceable not supported in bit mask"); 00557 else 00558 Mask |= AttributeImpl::getAttrMask(Kind); 00559 } 00560 00561 return Mask; 00562 } 00563 00564 return 0; 00565 } 00566 00567 void AttributeSetImpl::dump() const { 00568 AttributeSet(const_cast<AttributeSetImpl *>(this)).dump(); 00569 } 00570 00571 //===----------------------------------------------------------------------===// 00572 // AttributeSet Construction and Mutation Methods 00573 //===----------------------------------------------------------------------===// 00574 00575 AttributeSet 00576 AttributeSet::getImpl(LLVMContext &C, 00577 ArrayRef<std::pair<unsigned, AttributeSetNode*> > Attrs) { 00578 LLVMContextImpl *pImpl = C.pImpl; 00579 FoldingSetNodeID ID; 00580 AttributeSetImpl::Profile(ID, Attrs); 00581 00582 void *InsertPoint; 00583 AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint); 00584 00585 // If we didn't find any existing attributes of the same shape then 00586 // create a new one and insert it. 00587 if (!PA) { 00588 // Coallocate entries after the AttributeSetImpl itself. 00589 void *Mem = ::operator new(sizeof(AttributeSetImpl) + 00590 sizeof(std::pair<unsigned, AttributeSetNode *>) * 00591 Attrs.size()); 00592 PA = new (Mem) AttributeSetImpl(C, Attrs); 00593 pImpl->AttrsLists.InsertNode(PA, InsertPoint); 00594 } 00595 00596 // Return the AttributesList that we found or created. 00597 return AttributeSet(PA); 00598 } 00599 00600 AttributeSet AttributeSet::get(LLVMContext &C, 00601 ArrayRef<std::pair<unsigned, Attribute> > Attrs){ 00602 // If there are no attributes then return a null AttributesList pointer. 00603 if (Attrs.empty()) 00604 return AttributeSet(); 00605 00606 #ifndef NDEBUG 00607 for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { 00608 assert((!i || Attrs[i-1].first <= Attrs[i].first) && 00609 "Misordered Attributes list!"); 00610 assert(!Attrs[i].second.hasAttribute(Attribute::None) && 00611 "Pointless attribute!"); 00612 } 00613 #endif 00614 00615 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes 00616 // list. 00617 SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrPairVec; 00618 for (ArrayRef<std::pair<unsigned, Attribute> >::iterator I = Attrs.begin(), 00619 E = Attrs.end(); I != E; ) { 00620 unsigned Index = I->first; 00621 SmallVector<Attribute, 4> AttrVec; 00622 while (I != E && I->first == Index) { 00623 AttrVec.push_back(I->second); 00624 ++I; 00625 } 00626 00627 AttrPairVec.push_back(std::make_pair(Index, 00628 AttributeSetNode::get(C, AttrVec))); 00629 } 00630 00631 return getImpl(C, AttrPairVec); 00632 } 00633 00634 AttributeSet AttributeSet::get(LLVMContext &C, 00635 ArrayRef<std::pair<unsigned, 00636 AttributeSetNode*> > Attrs) { 00637 // If there are no attributes then return a null AttributesList pointer. 00638 if (Attrs.empty()) 00639 return AttributeSet(); 00640 00641 return getImpl(C, Attrs); 00642 } 00643 00644 AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index, 00645 const AttrBuilder &B) { 00646 if (!B.hasAttributes()) 00647 return AttributeSet(); 00648 00649 // Add target-independent attributes. 00650 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; 00651 for (Attribute::AttrKind Kind = Attribute::None; 00652 Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) { 00653 if (!B.contains(Kind)) 00654 continue; 00655 00656 if (Kind == Attribute::Alignment) 00657 Attrs.push_back(std::make_pair(Index, Attribute:: 00658 getWithAlignment(C, B.getAlignment()))); 00659 else if (Kind == Attribute::StackAlignment) 00660 Attrs.push_back(std::make_pair(Index, Attribute:: 00661 getWithStackAlignment(C, B.getStackAlignment()))); 00662 else if (Kind == Attribute::Dereferenceable) 00663 Attrs.push_back(std::make_pair(Index, 00664 Attribute::getWithDereferenceableBytes(C, 00665 B.getDereferenceableBytes()))); 00666 else 00667 Attrs.push_back(std::make_pair(Index, Attribute::get(C, Kind))); 00668 } 00669 00670 // Add target-dependent (string) attributes. 00671 for (const AttrBuilder::td_type &TDA : B.td_attrs()) 00672 Attrs.push_back( 00673 std::make_pair(Index, Attribute::get(C, TDA.first, TDA.second))); 00674 00675 return get(C, Attrs); 00676 } 00677 00678 AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index, 00679 ArrayRef<Attribute::AttrKind> Kind) { 00680 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs; 00681 for (ArrayRef<Attribute::AttrKind>::iterator I = Kind.begin(), 00682 E = Kind.end(); I != E; ++I) 00683 Attrs.push_back(std::make_pair(Index, Attribute::get(C, *I))); 00684 return get(C, Attrs); 00685 } 00686 00687 AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) { 00688 if (Attrs.empty()) return AttributeSet(); 00689 if (Attrs.size() == 1) return Attrs[0]; 00690 00691 SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrNodeVec; 00692 AttributeSetImpl *A0 = Attrs[0].pImpl; 00693 if (A0) 00694 AttrNodeVec.append(A0->getNode(0), A0->getNode(A0->getNumAttributes())); 00695 // Copy all attributes from Attrs into AttrNodeVec while keeping AttrNodeVec 00696 // ordered by index. Because we know that each list in Attrs is ordered by 00697 // index we only need to merge each successive list in rather than doing a 00698 // full sort. 00699 for (unsigned I = 1, E = Attrs.size(); I != E; ++I) { 00700 AttributeSetImpl *AS = Attrs[I].pImpl; 00701 if (!AS) continue; 00702 SmallVector<std::pair<unsigned, AttributeSetNode *>, 8>::iterator 00703 ANVI = AttrNodeVec.begin(), ANVE; 00704 for (const AttributeSetImpl::IndexAttrPair 00705 *AI = AS->getNode(0), 00706 *AE = AS->getNode(AS->getNumAttributes()); 00707 AI != AE; ++AI) { 00708 ANVE = AttrNodeVec.end(); 00709 while (ANVI != ANVE && ANVI->first <= AI->first) 00710 ++ANVI; 00711 ANVI = AttrNodeVec.insert(ANVI, *AI) + 1; 00712 } 00713 } 00714 00715 return getImpl(C, AttrNodeVec); 00716 } 00717 00718 AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index, 00719 Attribute::AttrKind Attr) const { 00720 if (hasAttribute(Index, Attr)) return *this; 00721 return addAttributes(C, Index, AttributeSet::get(C, Index, Attr)); 00722 } 00723 00724 AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index, 00725 StringRef Kind) const { 00726 llvm::AttrBuilder B; 00727 B.addAttribute(Kind); 00728 return addAttributes(C, Index, AttributeSet::get(C, Index, B)); 00729 } 00730 00731 AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index, 00732 StringRef Kind, StringRef Value) const { 00733 llvm::AttrBuilder B; 00734 B.addAttribute(Kind, Value); 00735 return addAttributes(C, Index, AttributeSet::get(C, Index, B)); 00736 } 00737 00738 AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Index, 00739 AttributeSet Attrs) const { 00740 if (!pImpl) return Attrs; 00741 if (!Attrs.pImpl) return *this; 00742 00743 #ifndef NDEBUG 00744 // FIXME it is not obvious how this should work for alignment. For now, say 00745 // we can't change a known alignment. 00746 unsigned OldAlign = getParamAlignment(Index); 00747 unsigned NewAlign = Attrs.getParamAlignment(Index); 00748 assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && 00749 "Attempt to change alignment!"); 00750 #endif 00751 00752 // Add the attribute slots before the one we're trying to add. 00753 SmallVector<AttributeSet, 4> AttrSet; 00754 uint64_t NumAttrs = pImpl->getNumAttributes(); 00755 AttributeSet AS; 00756 uint64_t LastIndex = 0; 00757 for (unsigned I = 0, E = NumAttrs; I != E; ++I) { 00758 if (getSlotIndex(I) >= Index) { 00759 if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++); 00760 break; 00761 } 00762 LastIndex = I + 1; 00763 AttrSet.push_back(getSlotAttributes(I)); 00764 } 00765 00766 // Now add the attribute into the correct slot. There may already be an 00767 // AttributeSet there. 00768 AttrBuilder B(AS, Index); 00769 00770 for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I) 00771 if (Attrs.getSlotIndex(I) == Index) { 00772 for (AttributeSetImpl::iterator II = Attrs.pImpl->begin(I), 00773 IE = Attrs.pImpl->end(I); II != IE; ++II) 00774 B.addAttribute(*II); 00775 break; 00776 } 00777 00778 AttrSet.push_back(AttributeSet::get(C, Index, B)); 00779 00780 // Add the remaining attribute slots. 00781 for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I) 00782 AttrSet.push_back(getSlotAttributes(I)); 00783 00784 return get(C, AttrSet); 00785 } 00786 00787 AttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Index, 00788 Attribute::AttrKind Attr) const { 00789 if (!hasAttribute(Index, Attr)) return *this; 00790 return removeAttributes(C, Index, AttributeSet::get(C, Index, Attr)); 00791 } 00792 00793 AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Index, 00794 AttributeSet Attrs) const { 00795 if (!pImpl) return AttributeSet(); 00796 if (!Attrs.pImpl) return *this; 00797 00798 #ifndef NDEBUG 00799 // FIXME it is not obvious how this should work for alignment. 00800 // For now, say we can't pass in alignment, which no current use does. 00801 assert(!Attrs.hasAttribute(Index, Attribute::Alignment) && 00802 "Attempt to change alignment!"); 00803 #endif 00804 00805 // Add the attribute slots before the one we're trying to add. 00806 SmallVector<AttributeSet, 4> AttrSet; 00807 uint64_t NumAttrs = pImpl->getNumAttributes(); 00808 AttributeSet AS; 00809 uint64_t LastIndex = 0; 00810 for (unsigned I = 0, E = NumAttrs; I != E; ++I) { 00811 if (getSlotIndex(I) >= Index) { 00812 if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++); 00813 break; 00814 } 00815 LastIndex = I + 1; 00816 AttrSet.push_back(getSlotAttributes(I)); 00817 } 00818 00819 // Now remove the attribute from the correct slot. There may already be an 00820 // AttributeSet there. 00821 AttrBuilder B(AS, Index); 00822 00823 for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I) 00824 if (Attrs.getSlotIndex(I) == Index) { 00825 B.removeAttributes(Attrs.pImpl->getSlotAttributes(I), Index); 00826 break; 00827 } 00828 00829 AttrSet.push_back(AttributeSet::get(C, Index, B)); 00830 00831 // Add the remaining attribute slots. 00832 for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I) 00833 AttrSet.push_back(getSlotAttributes(I)); 00834 00835 return get(C, AttrSet); 00836 } 00837 00838 //===----------------------------------------------------------------------===// 00839 // AttributeSet Accessor Methods 00840 //===----------------------------------------------------------------------===// 00841 00842 LLVMContext &AttributeSet::getContext() const { 00843 return pImpl->getContext(); 00844 } 00845 00846 AttributeSet AttributeSet::getParamAttributes(unsigned Index) const { 00847 return pImpl && hasAttributes(Index) ? 00848 AttributeSet::get(pImpl->getContext(), 00849 ArrayRef<std::pair<unsigned, AttributeSetNode*> >( 00850 std::make_pair(Index, getAttributes(Index)))) : 00851 AttributeSet(); 00852 } 00853 00854 AttributeSet AttributeSet::getRetAttributes() const { 00855 return pImpl && hasAttributes(ReturnIndex) ? 00856 AttributeSet::get(pImpl->getContext(), 00857 ArrayRef<std::pair<unsigned, AttributeSetNode*> >( 00858 std::make_pair(ReturnIndex, 00859 getAttributes(ReturnIndex)))) : 00860 AttributeSet(); 00861 } 00862 00863 AttributeSet AttributeSet::getFnAttributes() const { 00864 return pImpl && hasAttributes(FunctionIndex) ? 00865 AttributeSet::get(pImpl->getContext(), 00866 ArrayRef<std::pair<unsigned, AttributeSetNode*> >( 00867 std::make_pair(FunctionIndex, 00868 getAttributes(FunctionIndex)))) : 00869 AttributeSet(); 00870 } 00871 00872 bool AttributeSet::hasAttribute(unsigned Index, Attribute::AttrKind Kind) const{ 00873 AttributeSetNode *ASN = getAttributes(Index); 00874 return ASN ? ASN->hasAttribute(Kind) : false; 00875 } 00876 00877 bool AttributeSet::hasAttribute(unsigned Index, StringRef Kind) const { 00878 AttributeSetNode *ASN = getAttributes(Index); 00879 return ASN ? ASN->hasAttribute(Kind) : false; 00880 } 00881 00882 bool AttributeSet::hasAttributes(unsigned Index) const { 00883 AttributeSetNode *ASN = getAttributes(Index); 00884 return ASN ? ASN->hasAttributes() : false; 00885 } 00886 00887 /// \brief Return true if the specified attribute is set for at least one 00888 /// parameter or for the return value. 00889 bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr) const { 00890 if (!pImpl) return false; 00891 00892 for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) 00893 for (AttributeSetImpl::iterator II = pImpl->begin(I), 00894 IE = pImpl->end(I); II != IE; ++II) 00895 if (II->hasAttribute(Attr)) 00896 return true; 00897 00898 return false; 00899 } 00900 00901 Attribute AttributeSet::getAttribute(unsigned Index, 00902 Attribute::AttrKind Kind) const { 00903 AttributeSetNode *ASN = getAttributes(Index); 00904 return ASN ? ASN->getAttribute(Kind) : Attribute(); 00905 } 00906 00907 Attribute AttributeSet::getAttribute(unsigned Index, 00908 StringRef Kind) const { 00909 AttributeSetNode *ASN = getAttributes(Index); 00910 return ASN ? ASN->getAttribute(Kind) : Attribute(); 00911 } 00912 00913 unsigned AttributeSet::getParamAlignment(unsigned Index) const { 00914 AttributeSetNode *ASN = getAttributes(Index); 00915 return ASN ? ASN->getAlignment() : 0; 00916 } 00917 00918 unsigned AttributeSet::getStackAlignment(unsigned Index) const { 00919 AttributeSetNode *ASN = getAttributes(Index); 00920 return ASN ? ASN->getStackAlignment() : 0; 00921 } 00922 00923 uint64_t AttributeSet::getDereferenceableBytes(unsigned Index) const { 00924 AttributeSetNode *ASN = getAttributes(Index); 00925 return ASN ? ASN->getDereferenceableBytes() : 0; 00926 } 00927 00928 std::string AttributeSet::getAsString(unsigned Index, 00929 bool InAttrGrp) const { 00930 AttributeSetNode *ASN = getAttributes(Index); 00931 return ASN ? ASN->getAsString(InAttrGrp) : std::string(""); 00932 } 00933 00934 /// \brief The attributes for the specified index are returned. 00935 AttributeSetNode *AttributeSet::getAttributes(unsigned Index) const { 00936 if (!pImpl) return nullptr; 00937 00938 // Loop through to find the attribute node we want. 00939 for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) 00940 if (pImpl->getSlotIndex(I) == Index) 00941 return pImpl->getSlotNode(I); 00942 00943 return nullptr; 00944 } 00945 00946 AttributeSet::iterator AttributeSet::begin(unsigned Slot) const { 00947 if (!pImpl) 00948 return ArrayRef<Attribute>().begin(); 00949 return pImpl->begin(Slot); 00950 } 00951 00952 AttributeSet::iterator AttributeSet::end(unsigned Slot) const { 00953 if (!pImpl) 00954 return ArrayRef<Attribute>().end(); 00955 return pImpl->end(Slot); 00956 } 00957 00958 //===----------------------------------------------------------------------===// 00959 // AttributeSet Introspection Methods 00960 //===----------------------------------------------------------------------===// 00961 00962 /// \brief Return the number of slots used in this attribute list. This is the 00963 /// number of arguments that have an attribute set on them (including the 00964 /// function itself). 00965 unsigned AttributeSet::getNumSlots() const { 00966 return pImpl ? pImpl->getNumAttributes() : 0; 00967 } 00968 00969 unsigned AttributeSet::getSlotIndex(unsigned Slot) const { 00970 assert(pImpl && Slot < pImpl->getNumAttributes() && 00971 "Slot # out of range!"); 00972 return pImpl->getSlotIndex(Slot); 00973 } 00974 00975 AttributeSet AttributeSet::getSlotAttributes(unsigned Slot) const { 00976 assert(pImpl && Slot < pImpl->getNumAttributes() && 00977 "Slot # out of range!"); 00978 return pImpl->getSlotAttributes(Slot); 00979 } 00980 00981 uint64_t AttributeSet::Raw(unsigned Index) const { 00982 // FIXME: Remove this. 00983 return pImpl ? pImpl->Raw(Index) : 0; 00984 } 00985 00986 void AttributeSet::dump() const { 00987 dbgs() << "PAL[\n"; 00988 00989 for (unsigned i = 0, e = getNumSlots(); i < e; ++i) { 00990 uint64_t Index = getSlotIndex(i); 00991 dbgs() << " { "; 00992 if (Index == ~0U) 00993 dbgs() << "~0U"; 00994 else 00995 dbgs() << Index; 00996 dbgs() << " => " << getAsString(Index) << " }\n"; 00997 } 00998 00999 dbgs() << "]\n"; 01000 } 01001 01002 //===----------------------------------------------------------------------===// 01003 // AttrBuilder Method Implementations 01004 //===----------------------------------------------------------------------===// 01005 01006 AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Index) 01007 : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0) { 01008 AttributeSetImpl *pImpl = AS.pImpl; 01009 if (!pImpl) return; 01010 01011 for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) { 01012 if (pImpl->getSlotIndex(I) != Index) continue; 01013 01014 for (AttributeSetImpl::iterator II = pImpl->begin(I), 01015 IE = pImpl->end(I); II != IE; ++II) 01016 addAttribute(*II); 01017 01018 break; 01019 } 01020 } 01021 01022 void AttrBuilder::clear() { 01023 Attrs.reset(); 01024 Alignment = StackAlignment = DerefBytes = 0; 01025 } 01026 01027 AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { 01028 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!"); 01029 assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment && 01030 Val != Attribute::Dereferenceable && 01031 "Adding integer attribute without adding a value!"); 01032 Attrs[Val] = true; 01033 return *this; 01034 } 01035 01036 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { 01037 if (Attr.isStringAttribute()) { 01038 addAttribute(Attr.getKindAsString(), Attr.getValueAsString()); 01039 return *this; 01040 } 01041 01042 Attribute::AttrKind Kind = Attr.getKindAsEnum(); 01043 Attrs[Kind] = true; 01044 01045 if (Kind == Attribute::Alignment) 01046 Alignment = Attr.getAlignment(); 01047 else if (Kind == Attribute::StackAlignment) 01048 StackAlignment = Attr.getStackAlignment(); 01049 else if (Kind == Attribute::Dereferenceable) 01050 DerefBytes = Attr.getDereferenceableBytes(); 01051 return *this; 01052 } 01053 01054 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) { 01055 TargetDepAttrs[A] = V; 01056 return *this; 01057 } 01058 01059 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { 01060 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!"); 01061 Attrs[Val] = false; 01062 01063 if (Val == Attribute::Alignment) 01064 Alignment = 0; 01065 else if (Val == Attribute::StackAlignment) 01066 StackAlignment = 0; 01067 else if (Val == Attribute::Dereferenceable) 01068 DerefBytes = 0; 01069 01070 return *this; 01071 } 01072 01073 AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) { 01074 unsigned Slot = ~0U; 01075 for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I) 01076 if (A.getSlotIndex(I) == Index) { 01077 Slot = I; 01078 break; 01079 } 01080 01081 assert(Slot != ~0U && "Couldn't find index in AttributeSet!"); 01082 01083 for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) { 01084 Attribute Attr = *I; 01085 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) { 01086 Attribute::AttrKind Kind = I->getKindAsEnum(); 01087 Attrs[Kind] = false; 01088 01089 if (Kind == Attribute::Alignment) 01090 Alignment = 0; 01091 else if (Kind == Attribute::StackAlignment) 01092 StackAlignment = 0; 01093 else if (Kind == Attribute::Dereferenceable) 01094 DerefBytes = 0; 01095 } else { 01096 assert(Attr.isStringAttribute() && "Invalid attribute type!"); 01097 std::map<std::string, std::string>::iterator 01098 Iter = TargetDepAttrs.find(Attr.getKindAsString()); 01099 if (Iter != TargetDepAttrs.end()) 01100 TargetDepAttrs.erase(Iter); 01101 } 01102 } 01103 01104 return *this; 01105 } 01106 01107 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) { 01108 std::map<std::string, std::string>::iterator I = TargetDepAttrs.find(A); 01109 if (I != TargetDepAttrs.end()) 01110 TargetDepAttrs.erase(I); 01111 return *this; 01112 } 01113 01114 AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) { 01115 if (Align == 0) return *this; 01116 01117 assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); 01118 assert(Align <= 0x40000000 && "Alignment too large."); 01119 01120 Attrs[Attribute::Alignment] = true; 01121 Alignment = Align; 01122 return *this; 01123 } 01124 01125 AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) { 01126 // Default alignment, allow the target to define how to align it. 01127 if (Align == 0) return *this; 01128 01129 assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); 01130 assert(Align <= 0x100 && "Alignment too large."); 01131 01132 Attrs[Attribute::StackAlignment] = true; 01133 StackAlignment = Align; 01134 return *this; 01135 } 01136 01137 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) { 01138 if (Bytes == 0) return *this; 01139 01140 Attrs[Attribute::Dereferenceable] = true; 01141 DerefBytes = Bytes; 01142 return *this; 01143 } 01144 01145 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { 01146 // FIXME: What if both have alignments, but they don't match?! 01147 if (!Alignment) 01148 Alignment = B.Alignment; 01149 01150 if (!StackAlignment) 01151 StackAlignment = B.StackAlignment; 01152 01153 if (!DerefBytes) 01154 DerefBytes = B.DerefBytes; 01155 01156 Attrs |= B.Attrs; 01157 01158 for (td_const_iterator I = B.TargetDepAttrs.begin(), 01159 E = B.TargetDepAttrs.end(); I != E; ++I) 01160 TargetDepAttrs[I->first] = I->second; 01161 01162 return *this; 01163 } 01164 01165 bool AttrBuilder::contains(StringRef A) const { 01166 return TargetDepAttrs.find(A) != TargetDepAttrs.end(); 01167 } 01168 01169 bool AttrBuilder::hasAttributes() const { 01170 return !Attrs.none() || !TargetDepAttrs.empty(); 01171 } 01172 01173 bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const { 01174 unsigned Slot = ~0U; 01175 for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I) 01176 if (A.getSlotIndex(I) == Index) { 01177 Slot = I; 01178 break; 01179 } 01180 01181 assert(Slot != ~0U && "Couldn't find the index!"); 01182 01183 for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); 01184 I != E; ++I) { 01185 Attribute Attr = *I; 01186 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) { 01187 if (Attrs[I->getKindAsEnum()]) 01188 return true; 01189 } else { 01190 assert(Attr.isStringAttribute() && "Invalid attribute kind!"); 01191 return TargetDepAttrs.find(Attr.getKindAsString())!=TargetDepAttrs.end(); 01192 } 01193 } 01194 01195 return false; 01196 } 01197 01198 bool AttrBuilder::hasAlignmentAttr() const { 01199 return Alignment != 0; 01200 } 01201 01202 bool AttrBuilder::operator==(const AttrBuilder &B) { 01203 if (Attrs != B.Attrs) 01204 return false; 01205 01206 for (td_const_iterator I = TargetDepAttrs.begin(), 01207 E = TargetDepAttrs.end(); I != E; ++I) 01208 if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end()) 01209 return false; 01210 01211 return Alignment == B.Alignment && StackAlignment == B.StackAlignment && 01212 DerefBytes == B.DerefBytes; 01213 } 01214 01215 AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { 01216 // FIXME: Remove this in 4.0. 01217 if (!Val) return *this; 01218 01219 for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; 01220 I = Attribute::AttrKind(I + 1)) { 01221 if (I == Attribute::Dereferenceable) 01222 continue; 01223 if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) { 01224 Attrs[I] = true; 01225 01226 if (I == Attribute::Alignment) 01227 Alignment = 1ULL << ((A >> 16) - 1); 01228 else if (I == Attribute::StackAlignment) 01229 StackAlignment = 1ULL << ((A >> 26)-1); 01230 } 01231 } 01232 01233 return *this; 01234 } 01235 01236 //===----------------------------------------------------------------------===// 01237 // AttributeFuncs Function Defintions 01238 //===----------------------------------------------------------------------===// 01239 01240 /// \brief Which attributes cannot be applied to a type. 01241 AttributeSet AttributeFuncs::typeIncompatible(Type *Ty, uint64_t Index) { 01242 AttrBuilder Incompatible; 01243 01244 if (!Ty->isIntegerTy()) 01245 // Attribute that only apply to integers. 01246 Incompatible.addAttribute(Attribute::SExt) 01247 .addAttribute(Attribute::ZExt); 01248 01249 if (!Ty->isPointerTy()) 01250 // Attribute that only apply to pointers. 01251 Incompatible.addAttribute(Attribute::ByVal) 01252 .addAttribute(Attribute::Nest) 01253 .addAttribute(Attribute::NoAlias) 01254 .addAttribute(Attribute::NoCapture) 01255 .addAttribute(Attribute::NonNull) 01256 .addDereferenceableAttr(1) // the int here is ignored 01257 .addAttribute(Attribute::ReadNone) 01258 .addAttribute(Attribute::ReadOnly) 01259 .addAttribute(Attribute::StructRet) 01260 .addAttribute(Attribute::InAlloca); 01261 01262 return AttributeSet::get(Ty->getContext(), Index, Incompatible); 01263 }