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