1 //===-- Attributes.cpp - Implement AttributesList -------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 // \brief This file implements the Attribute, AttributeImpl, AttrBuilder,
12 // AttributeSetImpl, and AttributeSet classes.
14 //===----------------------------------------------------------------------===//
16 #include "llvm/IR/Attributes.h"
17 #include "llvm/IR/Function.h"
18 #include "AttributeImpl.h"
19 #include "LLVMContextImpl.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/IR/Type.h"
23 #include "llvm/Support/Atomic.h"
24 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/ManagedStatic.h"
26 #include "llvm/Support/Mutex.h"
27 #include "llvm/Support/raw_ostream.h"
31 //===----------------------------------------------------------------------===//
32 // Attribute Construction Methods
33 //===----------------------------------------------------------------------===//
35 // allocsize has two integer arguments, but because they're both 32 bits, we can
36 // pack them into one 64-bit value, at the cost of making said value
39 // In order to do this, we need to reserve one value of the second (optional)
40 // allocsize argument to signify "not present."
41 static const unsigned AllocSizeNumElemsNotPresent = -1;
43 static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
44 const Optional<unsigned> &NumElemsArg) {
45 assert((!NumElemsArg.hasValue() ||
46 *NumElemsArg != AllocSizeNumElemsNotPresent) &&
47 "Attempting to pack a reserved value");
49 return uint64_t(ElemSizeArg) << 32 |
50 NumElemsArg.getValueOr(AllocSizeNumElemsNotPresent);
53 static std::pair<unsigned, Optional<unsigned>>
54 unpackAllocSizeArgs(uint64_t Num) {
55 unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
56 unsigned ElemSizeArg = Num >> 32;
58 Optional<unsigned> NumElemsArg;
59 if (NumElems != AllocSizeNumElemsNotPresent)
60 NumElemsArg = NumElems;
61 return std::make_pair(ElemSizeArg, NumElemsArg);
64 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
66 LLVMContextImpl *pImpl = Context.pImpl;
69 if (Val) ID.AddInteger(Val);
72 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
75 // If we didn't find any existing attributes of the same shape then create a
76 // new one and insert it.
78 PA = new EnumAttributeImpl(Kind);
80 PA = new IntAttributeImpl(Kind, Val);
81 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
84 // Return the Attribute that we found or created.
88 Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
89 LLVMContextImpl *pImpl = Context.pImpl;
92 if (!Val.empty()) ID.AddString(Val);
95 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
98 // If we didn't find any existing attributes of the same shape then create a
99 // new one and insert it.
100 PA = new StringAttributeImpl(Kind, Val);
101 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
104 // Return the Attribute that we found or created.
105 return Attribute(PA);
108 Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
109 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
110 assert(Align <= 0x40000000 && "Alignment too large.");
111 return get(Context, Alignment, Align);
114 Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
116 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
117 assert(Align <= 0x100 && "Alignment too large.");
118 return get(Context, StackAlignment, Align);
121 Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
123 assert(Bytes && "Bytes must be non-zero.");
124 return get(Context, Dereferenceable, Bytes);
127 Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
129 assert(Bytes && "Bytes must be non-zero.");
130 return get(Context, DereferenceableOrNull, Bytes);
134 Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
135 const Optional<unsigned> &NumElemsArg) {
136 assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
137 "Invalid allocsize arguments -- given allocsize(0, 0)");
138 return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
141 //===----------------------------------------------------------------------===//
142 // Attribute Accessor Methods
143 //===----------------------------------------------------------------------===//
145 bool Attribute::isEnumAttribute() const {
146 return pImpl && pImpl->isEnumAttribute();
149 bool Attribute::isIntAttribute() const {
150 return pImpl && pImpl->isIntAttribute();
153 bool Attribute::isStringAttribute() const {
154 return pImpl && pImpl->isStringAttribute();
157 Attribute::AttrKind Attribute::getKindAsEnum() const {
158 if (!pImpl) return None;
159 assert((isEnumAttribute() || isIntAttribute()) &&
160 "Invalid attribute type to get the kind as an enum!");
161 return pImpl->getKindAsEnum();
164 uint64_t Attribute::getValueAsInt() const {
165 if (!pImpl) return 0;
166 assert(isIntAttribute() &&
167 "Expected the attribute to be an integer attribute!");
168 return pImpl->getValueAsInt();
171 StringRef Attribute::getKindAsString() const {
172 if (!pImpl) return StringRef();
173 assert(isStringAttribute() &&
174 "Invalid attribute type to get the kind as a string!");
175 return pImpl->getKindAsString();
178 StringRef Attribute::getValueAsString() const {
179 if (!pImpl) return StringRef();
180 assert(isStringAttribute() &&
181 "Invalid attribute type to get the value as a string!");
182 return pImpl->getValueAsString();
185 bool Attribute::hasAttribute(AttrKind Kind) const {
186 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
189 bool Attribute::hasAttribute(StringRef Kind) const {
190 if (!isStringAttribute()) return false;
191 return pImpl && pImpl->hasAttribute(Kind);
194 unsigned Attribute::getAlignment() const {
195 assert(hasAttribute(Attribute::Alignment) &&
196 "Trying to get alignment from non-alignment attribute!");
197 return pImpl->getValueAsInt();
200 unsigned Attribute::getStackAlignment() const {
201 assert(hasAttribute(Attribute::StackAlignment) &&
202 "Trying to get alignment from non-alignment attribute!");
203 return pImpl->getValueAsInt();
206 uint64_t Attribute::getDereferenceableBytes() const {
207 assert(hasAttribute(Attribute::Dereferenceable) &&
208 "Trying to get dereferenceable bytes from "
209 "non-dereferenceable attribute!");
210 return pImpl->getValueAsInt();
213 uint64_t Attribute::getDereferenceableOrNullBytes() const {
214 assert(hasAttribute(Attribute::DereferenceableOrNull) &&
215 "Trying to get dereferenceable bytes from "
216 "non-dereferenceable attribute!");
217 return pImpl->getValueAsInt();
220 std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
221 assert(hasAttribute(Attribute::AllocSize) &&
222 "Trying to get allocsize args from non-allocsize attribute");
223 return unpackAllocSizeArgs(pImpl->getValueAsInt());
226 std::string Attribute::getAsString(bool InAttrGrp) const {
227 if (!pImpl) return "";
229 if (hasAttribute(Attribute::SanitizeAddress))
230 return "sanitize_address";
231 if (hasAttribute(Attribute::AlwaysInline))
232 return "alwaysinline";
233 if (hasAttribute(Attribute::ArgMemOnly))
235 if (hasAttribute(Attribute::Builtin))
237 if (hasAttribute(Attribute::ByVal))
239 if (hasAttribute(Attribute::Convergent))
241 if (hasAttribute(Attribute::SwiftError))
243 if (hasAttribute(Attribute::SwiftSelf))
245 if (hasAttribute(Attribute::InaccessibleMemOnly))
246 return "inaccessiblememonly";
247 if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
248 return "inaccessiblemem_or_argmemonly";
249 if (hasAttribute(Attribute::InAlloca))
251 if (hasAttribute(Attribute::InlineHint))
253 if (hasAttribute(Attribute::InReg))
255 if (hasAttribute(Attribute::JumpTable))
257 if (hasAttribute(Attribute::MinSize))
259 if (hasAttribute(Attribute::Naked))
261 if (hasAttribute(Attribute::Nest))
263 if (hasAttribute(Attribute::NoAlias))
265 if (hasAttribute(Attribute::NoBuiltin))
267 if (hasAttribute(Attribute::NoCapture))
269 if (hasAttribute(Attribute::NoDuplicate))
270 return "noduplicate";
271 if (hasAttribute(Attribute::NoImplicitFloat))
272 return "noimplicitfloat";
273 if (hasAttribute(Attribute::NoInline))
275 if (hasAttribute(Attribute::NonLazyBind))
276 return "nonlazybind";
277 if (hasAttribute(Attribute::NonNull))
279 if (hasAttribute(Attribute::NoRedZone))
281 if (hasAttribute(Attribute::NoReturn))
283 if (hasAttribute(Attribute::NoRecurse))
285 if (hasAttribute(Attribute::NoUnwind))
287 if (hasAttribute(Attribute::OptimizeNone))
289 if (hasAttribute(Attribute::OptimizeForSize))
291 if (hasAttribute(Attribute::ReadNone))
293 if (hasAttribute(Attribute::ReadOnly))
295 if (hasAttribute(Attribute::WriteOnly))
297 if (hasAttribute(Attribute::Returned))
299 if (hasAttribute(Attribute::ReturnsTwice))
300 return "returns_twice";
301 if (hasAttribute(Attribute::SExt))
303 if (hasAttribute(Attribute::StackProtect))
305 if (hasAttribute(Attribute::StackProtectReq))
307 if (hasAttribute(Attribute::StackProtectStrong))
309 if (hasAttribute(Attribute::SafeStack))
311 if (hasAttribute(Attribute::StructRet))
313 if (hasAttribute(Attribute::SanitizeThread))
314 return "sanitize_thread";
315 if (hasAttribute(Attribute::SanitizeMemory))
316 return "sanitize_memory";
317 if (hasAttribute(Attribute::UWTable))
319 if (hasAttribute(Attribute::ZExt))
321 if (hasAttribute(Attribute::Cold))
324 // FIXME: These should be output like this:
329 if (hasAttribute(Attribute::Alignment)) {
332 Result += (InAttrGrp) ? "=" : " ";
333 Result += utostr(getValueAsInt());
337 auto AttrWithBytesToString = [&](const char *Name) {
342 Result += utostr(getValueAsInt());
345 Result += utostr(getValueAsInt());
351 if (hasAttribute(Attribute::StackAlignment))
352 return AttrWithBytesToString("alignstack");
354 if (hasAttribute(Attribute::Dereferenceable))
355 return AttrWithBytesToString("dereferenceable");
357 if (hasAttribute(Attribute::DereferenceableOrNull))
358 return AttrWithBytesToString("dereferenceable_or_null");
360 if (hasAttribute(Attribute::AllocSize)) {
362 Optional<unsigned> NumElems;
363 std::tie(ElemSize, NumElems) = getAllocSizeArgs();
365 std::string Result = "allocsize(";
366 Result += utostr(ElemSize);
367 if (NumElems.hasValue()) {
369 Result += utostr(*NumElems);
375 // Convert target-dependent attributes to strings of the form:
380 if (isStringAttribute()) {
382 Result += (Twine('"') + getKindAsString() + Twine('"')).str();
384 std::string AttrVal = pImpl->getValueAsString();
385 if (AttrVal.empty()) return Result;
387 // Since some attribute strings contain special characters that cannot be
388 // printable, those have to be escaped to make the attribute value printable
389 // as is. e.g. "\01__gnu_mcount_nc"
391 raw_string_ostream OS(Result);
393 PrintEscapedString(AttrVal, OS);
399 llvm_unreachable("Unknown attribute");
402 bool Attribute::operator<(Attribute A) const {
403 if (!pImpl && !A.pImpl) return false;
404 if (!pImpl) return true;
405 if (!A.pImpl) return false;
406 return *pImpl < *A.pImpl;
409 //===----------------------------------------------------------------------===//
410 // AttributeImpl Definition
411 //===----------------------------------------------------------------------===//
413 // Pin the vtables to this file.
414 AttributeImpl::~AttributeImpl() {}
415 void EnumAttributeImpl::anchor() {}
416 void IntAttributeImpl::anchor() {}
417 void StringAttributeImpl::anchor() {}
419 bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
420 if (isStringAttribute()) return false;
421 return getKindAsEnum() == A;
424 bool AttributeImpl::hasAttribute(StringRef Kind) const {
425 if (!isStringAttribute()) return false;
426 return getKindAsString() == Kind;
429 Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
430 assert(isEnumAttribute() || isIntAttribute());
431 return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
434 uint64_t AttributeImpl::getValueAsInt() const {
435 assert(isIntAttribute());
436 return static_cast<const IntAttributeImpl *>(this)->getValue();
439 StringRef AttributeImpl::getKindAsString() const {
440 assert(isStringAttribute());
441 return static_cast<const StringAttributeImpl *>(this)->getStringKind();
444 StringRef AttributeImpl::getValueAsString() const {
445 assert(isStringAttribute());
446 return static_cast<const StringAttributeImpl *>(this)->getStringValue();
449 bool AttributeImpl::operator<(const AttributeImpl &AI) const {
450 // This sorts the attributes with Attribute::AttrKinds coming first (sorted
451 // relative to their enum value) and then strings.
452 if (isEnumAttribute()) {
453 if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
454 if (AI.isIntAttribute()) return true;
455 if (AI.isStringAttribute()) return true;
458 if (isIntAttribute()) {
459 if (AI.isEnumAttribute()) return false;
460 if (AI.isIntAttribute()) {
461 if (getKindAsEnum() == AI.getKindAsEnum())
462 return getValueAsInt() < AI.getValueAsInt();
463 return getKindAsEnum() < AI.getKindAsEnum();
465 if (AI.isStringAttribute()) return true;
468 if (AI.isEnumAttribute()) return false;
469 if (AI.isIntAttribute()) return false;
470 if (getKindAsString() == AI.getKindAsString())
471 return getValueAsString() < AI.getValueAsString();
472 return getKindAsString() < AI.getKindAsString();
475 //===----------------------------------------------------------------------===//
476 // AttributeSetNode Definition
477 //===----------------------------------------------------------------------===//
479 AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
480 ArrayRef<Attribute> Attrs) {
484 // Otherwise, build a key to look up the existing attributes.
485 LLVMContextImpl *pImpl = C.pImpl;
488 SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
489 std::sort(SortedAttrs.begin(), SortedAttrs.end());
491 for (Attribute Attr : SortedAttrs)
495 AttributeSetNode *PA =
496 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
498 // If we didn't find any existing attributes of the same shape then create a
499 // new one and insert it.
501 // Coallocate entries after the AttributeSetNode itself.
502 void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
503 PA = new (Mem) AttributeSetNode(SortedAttrs);
504 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
507 // Return the AttributesListNode that we found or created.
511 bool AttributeSetNode::hasAttribute(StringRef Kind) const {
512 for (Attribute I : *this)
513 if (I.hasAttribute(Kind))
518 Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
519 if (hasAttribute(Kind)) {
520 for (Attribute I : *this)
521 if (I.hasAttribute(Kind))
527 Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
528 for (Attribute I : *this)
529 if (I.hasAttribute(Kind))
534 unsigned AttributeSetNode::getAlignment() const {
535 for (Attribute I : *this)
536 if (I.hasAttribute(Attribute::Alignment))
537 return I.getAlignment();
541 unsigned AttributeSetNode::getStackAlignment() const {
542 for (Attribute I : *this)
543 if (I.hasAttribute(Attribute::StackAlignment))
544 return I.getStackAlignment();
548 uint64_t AttributeSetNode::getDereferenceableBytes() const {
549 for (Attribute I : *this)
550 if (I.hasAttribute(Attribute::Dereferenceable))
551 return I.getDereferenceableBytes();
555 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
556 for (Attribute I : *this)
557 if (I.hasAttribute(Attribute::DereferenceableOrNull))
558 return I.getDereferenceableOrNullBytes();
562 std::pair<unsigned, Optional<unsigned>>
563 AttributeSetNode::getAllocSizeArgs() const {
564 for (Attribute I : *this)
565 if (I.hasAttribute(Attribute::AllocSize))
566 return I.getAllocSizeArgs();
567 return std::make_pair(0, 0);
570 std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
572 for (iterator I = begin(), E = end(); I != E; ++I) {
575 Str += I->getAsString(InAttrGrp);
580 //===----------------------------------------------------------------------===//
581 // AttributeSetImpl Definition
582 //===----------------------------------------------------------------------===//
584 LLVM_DUMP_METHOD void AttributeSetImpl::dump() const {
585 AttributeSet(const_cast<AttributeSetImpl *>(this)).dump();
588 //===----------------------------------------------------------------------===//
589 // AttributeSet Construction and Mutation Methods
590 //===----------------------------------------------------------------------===//
593 AttributeSet::getImpl(LLVMContext &C,
594 ArrayRef<std::pair<unsigned, AttributeSetNode*> > Attrs) {
595 LLVMContextImpl *pImpl = C.pImpl;
597 AttributeSetImpl::Profile(ID, Attrs);
600 AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
602 // If we didn't find any existing attributes of the same shape then
603 // create a new one and insert it.
605 // Coallocate entries after the AttributeSetImpl itself.
606 void *Mem = ::operator new(
607 AttributeSetImpl::totalSizeToAlloc<IndexAttrPair>(Attrs.size()));
608 PA = new (Mem) AttributeSetImpl(C, Attrs);
609 pImpl->AttrsLists.InsertNode(PA, InsertPoint);
612 // Return the AttributesList that we found or created.
613 return AttributeSet(PA);
616 AttributeSet AttributeSet::get(LLVMContext &C,
617 ArrayRef<std::pair<unsigned, Attribute> > Attrs){
618 // If there are no attributes then return a null AttributesList pointer.
620 return AttributeSet();
622 assert(std::is_sorted(Attrs.begin(), Attrs.end(),
623 [](const std::pair<unsigned, Attribute> &LHS,
624 const std::pair<unsigned, Attribute> &RHS) {
625 return LHS.first < RHS.first;
626 }) && "Misordered Attributes list!");
627 assert(none_of(Attrs,
628 [](const std::pair<unsigned, Attribute> &Pair) {
629 return Pair.second.hasAttribute(Attribute::None);
631 "Pointless attribute!");
633 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
635 SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrPairVec;
636 for (ArrayRef<std::pair<unsigned, Attribute> >::iterator I = Attrs.begin(),
637 E = Attrs.end(); I != E; ) {
638 unsigned Index = I->first;
639 SmallVector<Attribute, 4> AttrVec;
640 while (I != E && I->first == Index) {
641 AttrVec.push_back(I->second);
645 AttrPairVec.emplace_back(Index, AttributeSetNode::get(C, AttrVec));
648 return getImpl(C, AttrPairVec);
651 AttributeSet AttributeSet::get(LLVMContext &C,
652 ArrayRef<std::pair<unsigned,
653 AttributeSetNode*> > Attrs) {
654 // If there are no attributes then return a null AttributesList pointer.
656 return AttributeSet();
658 return getImpl(C, Attrs);
661 AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
662 const AttrBuilder &B) {
663 if (!B.hasAttributes())
664 return AttributeSet();
666 // Add target-independent attributes.
667 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
668 for (Attribute::AttrKind Kind = Attribute::None;
669 Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) {
670 if (!B.contains(Kind))
675 case Attribute::Alignment:
676 Attr = Attribute::getWithAlignment(C, B.getAlignment());
678 case Attribute::StackAlignment:
679 Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment());
681 case Attribute::Dereferenceable:
682 Attr = Attribute::getWithDereferenceableBytes(
683 C, B.getDereferenceableBytes());
685 case Attribute::DereferenceableOrNull:
686 Attr = Attribute::getWithDereferenceableOrNullBytes(
687 C, B.getDereferenceableOrNullBytes());
689 case Attribute::AllocSize: {
690 auto A = B.getAllocSizeArgs();
691 Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
695 Attr = Attribute::get(C, Kind);
697 Attrs.emplace_back(Index, Attr);
700 // Add target-dependent (string) attributes.
701 for (const auto &TDA : B.td_attrs())
702 Attrs.emplace_back(Index, Attribute::get(C, TDA.first, TDA.second));
704 return get(C, Attrs);
707 AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
708 ArrayRef<Attribute::AttrKind> Kinds) {
709 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
710 for (Attribute::AttrKind K : Kinds)
711 Attrs.emplace_back(Index, Attribute::get(C, K));
712 return get(C, Attrs);
715 AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
716 ArrayRef<StringRef> Kinds) {
717 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
718 for (StringRef K : Kinds)
719 Attrs.emplace_back(Index, Attribute::get(C, K));
720 return get(C, Attrs);
723 AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) {
724 if (Attrs.empty()) return AttributeSet();
725 if (Attrs.size() == 1) return Attrs[0];
727 SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrNodeVec;
728 AttributeSetImpl *A0 = Attrs[0].pImpl;
730 AttrNodeVec.append(A0->getNode(0), A0->getNode(A0->getNumSlots()));
731 // Copy all attributes from Attrs into AttrNodeVec while keeping AttrNodeVec
732 // ordered by index. Because we know that each list in Attrs is ordered by
733 // index we only need to merge each successive list in rather than doing a
735 for (unsigned I = 1, E = Attrs.size(); I != E; ++I) {
736 AttributeSetImpl *AS = Attrs[I].pImpl;
738 SmallVector<std::pair<unsigned, AttributeSetNode *>, 8>::iterator
739 ANVI = AttrNodeVec.begin(), ANVE;
740 for (const IndexAttrPair *AI = AS->getNode(0),
741 *AE = AS->getNode(AS->getNumSlots());
743 ANVE = AttrNodeVec.end();
744 while (ANVI != ANVE && ANVI->first <= AI->first)
746 ANVI = AttrNodeVec.insert(ANVI, *AI) + 1;
750 return getImpl(C, AttrNodeVec);
753 AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index,
754 Attribute::AttrKind Kind) const {
755 if (hasAttribute(Index, Kind)) return *this;
756 return addAttributes(C, Index, AttributeSet::get(C, Index, Kind));
759 AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index,
760 StringRef Kind, StringRef Value) const {
762 B.addAttribute(Kind, Value);
763 return addAttributes(C, Index, AttributeSet::get(C, Index, B));
766 AttributeSet AttributeSet::addAttribute(LLVMContext &C,
767 ArrayRef<unsigned> Indices,
769 unsigned I = 0, E = pImpl ? pImpl->getNumSlots() : 0;
770 auto IdxI = Indices.begin(), IdxE = Indices.end();
771 SmallVector<AttributeSet, 4> AttrSet;
773 while (I != E && IdxI != IdxE) {
774 if (getSlotIndex(I) < *IdxI)
775 AttrSet.emplace_back(getSlotAttributes(I++));
776 else if (getSlotIndex(I) > *IdxI)
777 AttrSet.emplace_back(AttributeSet::get(C, std::make_pair(*IdxI++, A)));
779 AttrBuilder B(getSlotAttributes(I), *IdxI);
781 AttrSet.emplace_back(AttributeSet::get(C, *IdxI, B));
788 AttrSet.emplace_back(getSlotAttributes(I++));
791 AttrSet.emplace_back(AttributeSet::get(C, std::make_pair(*IdxI++, A)));
793 return get(C, AttrSet);
796 AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Index,
797 AttributeSet Attrs) const {
798 if (!pImpl) return Attrs;
799 if (!Attrs.pImpl) return *this;
802 // FIXME it is not obvious how this should work for alignment. For now, say
803 // we can't change a known alignment.
804 unsigned OldAlign = getParamAlignment(Index);
805 unsigned NewAlign = Attrs.getParamAlignment(Index);
806 assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
807 "Attempt to change alignment!");
810 // Add the attribute slots before the one we're trying to add.
811 SmallVector<AttributeSet, 4> AttrSet;
812 uint64_t NumAttrs = pImpl->getNumSlots();
814 uint64_t LastIndex = 0;
815 for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
816 if (getSlotIndex(I) >= Index) {
817 if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
821 AttrSet.push_back(getSlotAttributes(I));
824 // Now add the attribute into the correct slot. There may already be an
825 // AttributeSet there.
826 AttrBuilder B(AS, Index);
828 for (unsigned I = 0, E = Attrs.pImpl->getNumSlots(); I != E; ++I)
829 if (Attrs.getSlotIndex(I) == Index) {
830 for (AttributeSetImpl::iterator II = Attrs.pImpl->begin(I),
831 IE = Attrs.pImpl->end(I); II != IE; ++II)
836 AttrSet.push_back(AttributeSet::get(C, Index, B));
838 // Add the remaining attribute slots.
839 for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
840 AttrSet.push_back(getSlotAttributes(I));
842 return get(C, AttrSet);
845 AttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Index,
846 Attribute::AttrKind Kind) const {
847 if (!hasAttribute(Index, Kind)) return *this;
848 return removeAttributes(C, Index, AttributeSet::get(C, Index, Kind));
851 AttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Index,
852 StringRef Kind) const {
853 if (!hasAttribute(Index, Kind)) return *this;
854 return removeAttributes(C, Index, AttributeSet::get(C, Index, Kind));
857 AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Index,
858 AttributeSet Attrs) const {
859 if (!pImpl) return AttributeSet();
860 if (!Attrs.pImpl) return *this;
862 // FIXME it is not obvious how this should work for alignment.
863 // For now, say we can't pass in alignment, which no current use does.
864 assert(!Attrs.hasAttribute(Index, Attribute::Alignment) &&
865 "Attempt to change alignment!");
867 // Add the attribute slots before the one we're trying to add.
868 SmallVector<AttributeSet, 4> AttrSet;
869 uint64_t NumAttrs = pImpl->getNumSlots();
871 uint64_t LastIndex = 0;
872 for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
873 if (getSlotIndex(I) >= Index) {
874 if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
878 AttrSet.push_back(getSlotAttributes(I));
881 // Now remove the attribute from the correct slot. There may already be an
882 // AttributeSet there.
883 AttrBuilder B(AS, Index);
885 for (unsigned I = 0, E = Attrs.pImpl->getNumSlots(); I != E; ++I)
886 if (Attrs.getSlotIndex(I) == Index) {
887 B.removeAttributes(Attrs.pImpl->getSlotAttributes(I), Index);
891 AttrSet.push_back(AttributeSet::get(C, Index, B));
893 // Add the remaining attribute slots.
894 for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
895 AttrSet.push_back(getSlotAttributes(I));
897 return get(C, AttrSet);
900 AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Index,
901 const AttrBuilder &Attrs) const {
902 if (!pImpl) return AttributeSet();
904 // FIXME it is not obvious how this should work for alignment.
905 // For now, say we can't pass in alignment, which no current use does.
906 assert(!Attrs.hasAlignmentAttr() && "Attempt to change alignment!");
908 // Add the attribute slots before the one we're trying to add.
909 SmallVector<AttributeSet, 4> AttrSet;
910 uint64_t NumAttrs = pImpl->getNumSlots();
912 uint64_t LastIndex = 0;
913 for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
914 if (getSlotIndex(I) >= Index) {
915 if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
919 AttrSet.push_back(getSlotAttributes(I));
922 // Now remove the attribute from the correct slot. There may already be an
923 // AttributeSet there.
924 AttrBuilder B(AS, Index);
927 AttrSet.push_back(AttributeSet::get(C, Index, B));
929 // Add the remaining attribute slots.
930 for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
931 AttrSet.push_back(getSlotAttributes(I));
933 return get(C, AttrSet);
936 AttributeSet AttributeSet::addDereferenceableAttr(LLVMContext &C, unsigned Index,
937 uint64_t Bytes) const {
939 B.addDereferenceableAttr(Bytes);
940 return addAttributes(C, Index, AttributeSet::get(C, Index, B));
943 AttributeSet AttributeSet::addDereferenceableOrNullAttr(LLVMContext &C,
945 uint64_t Bytes) const {
947 B.addDereferenceableOrNullAttr(Bytes);
948 return addAttributes(C, Index, AttributeSet::get(C, Index, B));
952 AttributeSet::addAllocSizeAttr(LLVMContext &C, unsigned Index,
953 unsigned ElemSizeArg,
954 const Optional<unsigned> &NumElemsArg) {
956 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
957 return addAttributes(C, Index, AttributeSet::get(C, Index, B));
960 //===----------------------------------------------------------------------===//
961 // AttributeSet Accessor Methods
962 //===----------------------------------------------------------------------===//
964 LLVMContext &AttributeSet::getContext() const {
965 return pImpl->getContext();
968 AttributeSet AttributeSet::getParamAttributes(unsigned Index) const {
969 return pImpl && hasAttributes(Index) ?
970 AttributeSet::get(pImpl->getContext(),
971 ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
972 std::make_pair(Index, getAttributes(Index)))) :
976 AttributeSet AttributeSet::getRetAttributes() const {
977 return pImpl && hasAttributes(ReturnIndex) ?
978 AttributeSet::get(pImpl->getContext(),
979 ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
980 std::make_pair(ReturnIndex,
981 getAttributes(ReturnIndex)))) :
985 AttributeSet AttributeSet::getFnAttributes() const {
986 return pImpl && hasAttributes(FunctionIndex) ?
987 AttributeSet::get(pImpl->getContext(),
988 ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
989 std::make_pair(FunctionIndex,
990 getAttributes(FunctionIndex)))) :
994 bool AttributeSet::hasAttribute(unsigned Index, Attribute::AttrKind Kind) const{
995 AttributeSetNode *ASN = getAttributes(Index);
996 return ASN && ASN->hasAttribute(Kind);
999 bool AttributeSet::hasAttribute(unsigned Index, StringRef Kind) const {
1000 AttributeSetNode *ASN = getAttributes(Index);
1001 return ASN && ASN->hasAttribute(Kind);
1004 bool AttributeSet::hasAttributes(unsigned Index) const {
1005 AttributeSetNode *ASN = getAttributes(Index);
1006 return ASN && ASN->hasAttributes();
1009 bool AttributeSet::hasFnAttribute(Attribute::AttrKind Kind) const {
1010 return pImpl && pImpl->hasFnAttribute(Kind);
1013 bool AttributeSet::hasFnAttribute(StringRef Kind) const {
1014 return hasAttribute(AttributeSet::FunctionIndex, Kind);
1017 bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr,
1018 unsigned *Index) const {
1019 if (!pImpl) return false;
1021 for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I)
1022 for (AttributeSetImpl::iterator II = pImpl->begin(I),
1023 IE = pImpl->end(I); II != IE; ++II)
1024 if (II->hasAttribute(Attr)) {
1025 if (Index) *Index = pImpl->getSlotIndex(I);
1032 Attribute AttributeSet::getAttribute(unsigned Index,
1033 Attribute::AttrKind Kind) const {
1034 AttributeSetNode *ASN = getAttributes(Index);
1035 return ASN ? ASN->getAttribute(Kind) : Attribute();
1038 Attribute AttributeSet::getAttribute(unsigned Index,
1039 StringRef Kind) const {
1040 AttributeSetNode *ASN = getAttributes(Index);
1041 return ASN ? ASN->getAttribute(Kind) : Attribute();
1044 unsigned AttributeSet::getParamAlignment(unsigned Index) const {
1045 AttributeSetNode *ASN = getAttributes(Index);
1046 return ASN ? ASN->getAlignment() : 0;
1049 unsigned AttributeSet::getStackAlignment(unsigned Index) const {
1050 AttributeSetNode *ASN = getAttributes(Index);
1051 return ASN ? ASN->getStackAlignment() : 0;
1054 uint64_t AttributeSet::getDereferenceableBytes(unsigned Index) const {
1055 AttributeSetNode *ASN = getAttributes(Index);
1056 return ASN ? ASN->getDereferenceableBytes() : 0;
1059 uint64_t AttributeSet::getDereferenceableOrNullBytes(unsigned Index) const {
1060 AttributeSetNode *ASN = getAttributes(Index);
1061 return ASN ? ASN->getDereferenceableOrNullBytes() : 0;
1064 std::pair<unsigned, Optional<unsigned>>
1065 AttributeSet::getAllocSizeArgs(unsigned Index) const {
1066 AttributeSetNode *ASN = getAttributes(Index);
1067 return ASN ? ASN->getAllocSizeArgs() : std::make_pair(0u, Optional<unsigned>(0u));
1070 std::string AttributeSet::getAsString(unsigned Index, bool InAttrGrp) const {
1071 AttributeSetNode *ASN = getAttributes(Index);
1072 return ASN ? ASN->getAsString(InAttrGrp) : std::string("");
1075 AttributeSetNode *AttributeSet::getAttributes(unsigned Index) const {
1076 if (!pImpl) return nullptr;
1078 // Loop through to find the attribute node we want.
1079 for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I)
1080 if (pImpl->getSlotIndex(I) == Index)
1081 return pImpl->getSlotNode(I);
1086 AttributeSet::iterator AttributeSet::begin(unsigned Slot) const {
1088 return ArrayRef<Attribute>().begin();
1089 return pImpl->begin(Slot);
1092 AttributeSet::iterator AttributeSet::end(unsigned Slot) const {
1094 return ArrayRef<Attribute>().end();
1095 return pImpl->end(Slot);
1098 //===----------------------------------------------------------------------===//
1099 // AttributeSet Introspection Methods
1100 //===----------------------------------------------------------------------===//
1102 unsigned AttributeSet::getNumSlots() const {
1103 return pImpl ? pImpl->getNumSlots() : 0;
1106 unsigned AttributeSet::getSlotIndex(unsigned Slot) const {
1107 assert(pImpl && Slot < pImpl->getNumSlots() &&
1108 "Slot # out of range!");
1109 return pImpl->getSlotIndex(Slot);
1112 AttributeSet AttributeSet::getSlotAttributes(unsigned Slot) const {
1113 assert(pImpl && Slot < pImpl->getNumSlots() &&
1114 "Slot # out of range!");
1115 return pImpl->getSlotAttributes(Slot);
1118 LLVM_DUMP_METHOD void AttributeSet::dump() const {
1121 for (unsigned i = 0, e = getNumSlots(); i < e; ++i) {
1122 uint64_t Index = getSlotIndex(i);
1128 dbgs() << " => " << getAsString(Index) << " }\n";
1134 //===----------------------------------------------------------------------===//
1135 // AttrBuilder Method Implementations
1136 //===----------------------------------------------------------------------===//
1138 AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Index)
1139 : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0),
1140 DerefOrNullBytes(0), AllocSizeArgs(0) {
1141 AttributeSetImpl *pImpl = AS.pImpl;
1144 for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) {
1145 if (pImpl->getSlotIndex(I) != Index) continue;
1147 for (AttributeSetImpl::iterator II = pImpl->begin(I),
1148 IE = pImpl->end(I); II != IE; ++II)
1155 void AttrBuilder::clear() {
1157 TargetDepAttrs.clear();
1158 Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
1162 AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
1163 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1164 assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
1165 Val != Attribute::Dereferenceable && Val != Attribute::AllocSize &&
1166 "Adding integer attribute without adding a value!");
1171 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
1172 if (Attr.isStringAttribute()) {
1173 addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
1177 Attribute::AttrKind Kind = Attr.getKindAsEnum();
1180 if (Kind == Attribute::Alignment)
1181 Alignment = Attr.getAlignment();
1182 else if (Kind == Attribute::StackAlignment)
1183 StackAlignment = Attr.getStackAlignment();
1184 else if (Kind == Attribute::Dereferenceable)
1185 DerefBytes = Attr.getDereferenceableBytes();
1186 else if (Kind == Attribute::DereferenceableOrNull)
1187 DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
1188 else if (Kind == Attribute::AllocSize)
1189 AllocSizeArgs = Attr.getValueAsInt();
1193 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1194 TargetDepAttrs[A] = V;
1198 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
1199 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1202 if (Val == Attribute::Alignment)
1204 else if (Val == Attribute::StackAlignment)
1206 else if (Val == Attribute::Dereferenceable)
1208 else if (Val == Attribute::DereferenceableOrNull)
1209 DerefOrNullBytes = 0;
1210 else if (Val == Attribute::AllocSize)
1216 AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) {
1217 unsigned Slot = ~0U;
1218 for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I)
1219 if (A.getSlotIndex(I) == Index) {
1224 assert(Slot != ~0U && "Couldn't find index in AttributeSet!");
1226 for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) {
1227 Attribute Attr = *I;
1228 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1229 removeAttribute(Attr.getKindAsEnum());
1231 assert(Attr.isStringAttribute() && "Invalid attribute type!");
1232 removeAttribute(Attr.getKindAsString());
1239 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
1240 std::map<std::string, std::string>::iterator I = TargetDepAttrs.find(A);
1241 if (I != TargetDepAttrs.end())
1242 TargetDepAttrs.erase(I);
1246 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1247 return unpackAllocSizeArgs(AllocSizeArgs);
1250 AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
1251 if (Align == 0) return *this;
1253 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1254 assert(Align <= 0x40000000 && "Alignment too large.");
1256 Attrs[Attribute::Alignment] = true;
1261 AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) {
1262 // Default alignment, allow the target to define how to align it.
1263 if (Align == 0) return *this;
1265 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1266 assert(Align <= 0x100 && "Alignment too large.");
1268 Attrs[Attribute::StackAlignment] = true;
1269 StackAlignment = Align;
1273 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
1274 if (Bytes == 0) return *this;
1276 Attrs[Attribute::Dereferenceable] = true;
1281 AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
1285 Attrs[Attribute::DereferenceableOrNull] = true;
1286 DerefOrNullBytes = Bytes;
1290 AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
1291 const Optional<unsigned> &NumElems) {
1292 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1295 AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
1296 // (0, 0) is our "not present" value, so we need to check for it here.
1297 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1299 Attrs[Attribute::AllocSize] = true;
1300 // Reuse existing machinery to store this as a single 64-bit integer so we can
1301 // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1302 AllocSizeArgs = RawArgs;
1306 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
1307 // FIXME: What if both have alignments, but they don't match?!
1309 Alignment = B.Alignment;
1311 if (!StackAlignment)
1312 StackAlignment = B.StackAlignment;
1315 DerefBytes = B.DerefBytes;
1317 if (!DerefOrNullBytes)
1318 DerefOrNullBytes = B.DerefOrNullBytes;
1321 AllocSizeArgs = B.AllocSizeArgs;
1325 for (auto I : B.td_attrs())
1326 TargetDepAttrs[I.first] = I.second;
1331 AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
1332 // FIXME: What if both have alignments, but they don't match?!
1336 if (B.StackAlignment)
1342 if (B.DerefOrNullBytes)
1343 DerefOrNullBytes = 0;
1345 if (B.AllocSizeArgs)
1350 for (auto I : B.td_attrs())
1351 TargetDepAttrs.erase(I.first);
1356 bool AttrBuilder::overlaps(const AttrBuilder &B) const {
1357 // First check if any of the target independent attributes overlap.
1358 if ((Attrs & B.Attrs).any())
1361 // Then check if any target dependent ones do.
1362 for (auto I : td_attrs())
1363 if (B.contains(I.first))
1369 bool AttrBuilder::contains(StringRef A) const {
1370 return TargetDepAttrs.find(A) != TargetDepAttrs.end();
1373 bool AttrBuilder::hasAttributes() const {
1374 return !Attrs.none() || !TargetDepAttrs.empty();
1377 bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const {
1378 unsigned Slot = ~0U;
1379 for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I)
1380 if (A.getSlotIndex(I) == Index) {
1385 assert(Slot != ~0U && "Couldn't find the index!");
1387 for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) {
1388 Attribute Attr = *I;
1389 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1390 if (Attrs[I->getKindAsEnum()])
1393 assert(Attr.isStringAttribute() && "Invalid attribute kind!");
1394 return TargetDepAttrs.find(Attr.getKindAsString())!=TargetDepAttrs.end();
1401 bool AttrBuilder::hasAlignmentAttr() const {
1402 return Alignment != 0;
1405 bool AttrBuilder::operator==(const AttrBuilder &B) {
1406 if (Attrs != B.Attrs)
1409 for (td_const_iterator I = TargetDepAttrs.begin(),
1410 E = TargetDepAttrs.end(); I != E; ++I)
1411 if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
1414 return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
1415 DerefBytes == B.DerefBytes;
1418 //===----------------------------------------------------------------------===//
1419 // AttributeFuncs Function Defintions
1420 //===----------------------------------------------------------------------===//
1422 /// \brief Which attributes cannot be applied to a type.
1423 AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
1424 AttrBuilder Incompatible;
1426 if (!Ty->isIntegerTy())
1427 // Attribute that only apply to integers.
1428 Incompatible.addAttribute(Attribute::SExt)
1429 .addAttribute(Attribute::ZExt);
1431 if (!Ty->isPointerTy())
1432 // Attribute that only apply to pointers.
1433 Incompatible.addAttribute(Attribute::ByVal)
1434 .addAttribute(Attribute::Nest)
1435 .addAttribute(Attribute::NoAlias)
1436 .addAttribute(Attribute::NoCapture)
1437 .addAttribute(Attribute::NonNull)
1438 .addDereferenceableAttr(1) // the int here is ignored
1439 .addDereferenceableOrNullAttr(1) // the int here is ignored
1440 .addAttribute(Attribute::ReadNone)
1441 .addAttribute(Attribute::ReadOnly)
1442 .addAttribute(Attribute::StructRet)
1443 .addAttribute(Attribute::InAlloca);
1445 return Incompatible;
1448 template<typename AttrClass>
1449 static bool isEqual(const Function &Caller, const Function &Callee) {
1450 return Caller.getFnAttribute(AttrClass::getKind()) ==
1451 Callee.getFnAttribute(AttrClass::getKind());
1454 /// \brief Compute the logical AND of the attributes of the caller and the
1457 /// This function sets the caller's attribute to false if the callee's attribute
1459 template<typename AttrClass>
1460 static void setAND(Function &Caller, const Function &Callee) {
1461 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
1462 !AttrClass::isSet(Callee, AttrClass::getKind()))
1463 AttrClass::set(Caller, AttrClass::getKind(), false);
1466 /// \brief Compute the logical OR of the attributes of the caller and the
1469 /// This function sets the caller's attribute to true if the callee's attribute
1471 template<typename AttrClass>
1472 static void setOR(Function &Caller, const Function &Callee) {
1473 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
1474 AttrClass::isSet(Callee, AttrClass::getKind()))
1475 AttrClass::set(Caller, AttrClass::getKind(), true);
1478 /// \brief If the inlined function had a higher stack protection level than the
1479 /// calling function, then bump up the caller's stack protection level.
1480 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
1481 // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1482 // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1483 // clutter to the IR.
1485 B.addAttribute(Attribute::StackProtect)
1486 .addAttribute(Attribute::StackProtectStrong)
1487 .addAttribute(Attribute::StackProtectReq);
1488 AttributeSet OldSSPAttr = AttributeSet::get(Caller.getContext(),
1489 AttributeSet::FunctionIndex,
1492 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
1493 Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
1494 Caller.addFnAttr(Attribute::StackProtectReq);
1495 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
1496 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
1497 Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
1498 Caller.addFnAttr(Attribute::StackProtectStrong);
1499 } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
1500 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
1501 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
1502 Caller.addFnAttr(Attribute::StackProtect);
1505 #define GET_ATTR_COMPAT_FUNC
1506 #include "AttributesCompatFunc.inc"
1508 bool AttributeFuncs::areInlineCompatible(const Function &Caller,
1509 const Function &Callee) {
1510 return hasCompatibleFnAttrs(Caller, Callee);
1514 void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
1515 const Function &Callee) {
1516 mergeFnAttrs(Caller, Callee);